Thread (13 messages) 13 messages, 3 authors, 2010-01-03

Re: 32-rc1 aka 32-rc2: warning at manage.c:361 (set_irq_wake), matrix-keypad related?

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2009-12-03 03:17:11
Also in: linux-arm-kernel, lkml
Subsystem: input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers: Dmitry Torokhov, Linus Torvalds

On Wed, Oct 07, 2009 at 11:12:26PM +0200, Pavel Machek wrote:
quoted
quoted
quoted
OK, so it looks like your box refuses to set up one of the GPIOs as a
wakeup source... Hmm, either your box is wrong ;) or matrix_keypad
driver needs to maintain a separate list of wakeup GPIOs.
This is due to the nature of PXA processor, where not every GPIO can
be configured as a wakeup source. Mmm.... we can either return a
pseudo value indicating setting wakeup on that GPIO is OK (which
doesn't sound like a good idea), or we can just ignore the failure of
enable_irq_wake() in matrix_keypad?
We ignore the failure right now in the mainline but that causes stack
traces on resume as we trying to disable not enabled wakeup GPIOs. That
was original Pavel's complaint.
Yep...

I'd say that BUG() simply should not trigger if wakeup can not be
enabled/disabled for particular source...?
Pavel,

Could you please try the patch below and let me know if it fixes the
problem for you?

Thanks.

-- 
Dmitry

Input: matrix-keypad - handle cases when GPIOs can't be wakeup sources

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Signed-off-by: Dmitry Torokhov <redacted>
---

 drivers/input/keyboard/matrix_keypad.c |   29 ++++++++++++++++++++++-------
 1 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 91cfe51..a1152ba 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -29,11 +29,13 @@ struct matrix_keypad {
 	unsigned short *keycodes;
 	unsigned int row_shift;
 
+	DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
+
 	uint32_t last_key_state[MATRIX_MAX_COLS];
 	struct delayed_work work;
+	spinlock_t lock;
 	bool scan_pending;
 	bool stopped;
-	spinlock_t lock;
 };
 
 /*
@@ -221,9 +223,16 @@ static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t stat
 
 	matrix_keypad_stop(keypad->input_dev);
 
-	if (device_may_wakeup(&pdev->dev))
-		for (i = 0; i < pdata->num_row_gpios; i++)
-			enable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->num_row_gpios; i++) {
+			if (!test_bit(i, keypad->disabled_gpios)) {
+				unsigned int gpio = pdata->row_gpios[i];
+
+				if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
+					__set_bit(i, keypad->disabled_gpios);
+			}
+		}
+	}
 
 	return 0;
 }
@@ -234,9 +243,15 @@ static int matrix_keypad_resume(struct platform_device *pdev)
 	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 	int i;
 
-	if (device_may_wakeup(&pdev->dev))
-		for (i = 0; i < pdata->num_row_gpios; i++)
-			disable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->num_row_gpios; i++) {
+			if (test_and_clear_bit(i, keypad->disabled_gpios)) {
+				unsigned int gpio = pdata->row_gpios[i];
+
+				disable_irq_wake(gpio_to_irq(gpio));
+			}
+		}
+	}
 
 	matrix_keypad_start(keypad->input_dev);
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help