Commit 2fba26c6 authored by NeilBrown's avatar NeilBrown Committed by Dmitry Torokhov
Browse files

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: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 219edc71
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -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);