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>
This commit is contained in:
Родитель
219edc7178
Коммит
2fba26c659
|
@ -344,6 +344,9 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
|
||||||
container_of(work, struct gpio_button_data, work);
|
container_of(work, struct gpio_button_data, work);
|
||||||
|
|
||||||
gpio_keys_gpio_report_event(bdata);
|
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)
|
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);
|
BUG_ON(irq != bdata->irq);
|
||||||
|
|
||||||
|
if (bdata->button->wakeup)
|
||||||
|
pm_stay_awake(bdata->input->dev.parent);
|
||||||
if (bdata->timer_debounce)
|
if (bdata->timer_debounce)
|
||||||
mod_timer(&bdata->timer,
|
mod_timer(&bdata->timer,
|
||||||
jiffies + msecs_to_jiffies(bdata->timer_debounce));
|
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);
|
spin_lock_irqsave(&bdata->lock, flags);
|
||||||
|
|
||||||
if (!bdata->key_pressed) {
|
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_event(input, EV_KEY, button->code, 1);
|
||||||
input_sync(input);
|
input_sync(input);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче