Input: gpio_keys: report a wakeup_event for a button press on a wake_up button.
authorNeilBrown <neilb@suse.de>
Fri, 29 Jun 2012 10:18:30 +0000 (20:18 +1000)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 2 Mar 2013 20:11:55 +0000 (22:11 +0200)
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 handled
(gpio_keys_irq_isr), and simple pm_wakeup_event() with no delay is
sufficient as suspend will synchronise with all interrupt delivery.

When the user-space visible event is create 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>
Conflicts:

drivers/input/keyboard/gpio_keys.c

drivers/input/keyboard/gpio_keys.c

index 2879cf4..a20764e 100644 (file)
@@ -342,6 +342,8 @@ static void gpio_keys_work_func(struct work_struct *work)
                container_of(work, struct gpio_button_data, work);
 
        gpio_keys_report_event(bdata);
+       if (bdata->button->wakeup)
+               pm_relax(bdata->input->dev.parent);
 }
 
 static void gpio_keys_timer(unsigned long _data)
@@ -358,6 +360,8 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 
        BUG_ON(irq != gpio_to_irq(button->gpio));
 
+       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));