diff options
author | NeilBrown <neilb@suse.de> | 2012-07-29 22:18:47 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-08-21 22:29:48 -0700 |
commit | 2fba26c6595e4c1c64a74dad30f71c09708ff59a (patch) | |
tree | 978e2ec8f5154128e11778f93ebd9b914cf04630 | |
parent | 219edc71784ff8a3537ffbe64baded61ce4048b9 (diff) |
Input: gpio_keys - report a wakeup_event for a button press
In order to avoid races with suspend, a wakeup event must register as
such by calling pm_wakeup_event() or pm_stay_awake(). This will ensure
that the current suspend cycle aborts.
When the user-space visible event is created in the interrupt handler
(gpio_keys_irq_isr), a simple pm_wakeup_event() with no delay is
sufficient as suspend will synchronise with all interrupt delivery.
When the user-space visible event is created later
(gpio_keys_gpio_isr), we need to bracket the event with
pm_stay_awake() and pm_relax().
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index b890231debd8..6a68041c261d 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -344,6 +344,9 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) container_of(work, struct gpio_button_data, work); gpio_keys_gpio_report_event(bdata); + + if (bdata->button->wakeup) + pm_relax(bdata->input->dev.parent); } static void gpio_keys_gpio_timer(unsigned long _data) @@ -359,6 +362,8 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) BUG_ON(irq != bdata->irq); + if (bdata->button->wakeup) + pm_stay_awake(bdata->input->dev.parent); if (bdata->timer_debounce) mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(bdata->timer_debounce)); @@ -395,6 +400,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) spin_lock_irqsave(&bdata->lock, flags); if (!bdata->key_pressed) { + if (bdata->button->wakeup) + pm_wakeup_event(bdata->input->dev.parent, 0); + input_event(input, EV_KEY, button->code, 1); input_sync(input); |