Commit 0f107573 authored by Joseph Lo's avatar Joseph Lo Committed by Dmitry Torokhov

Input: gpio_keys - handle the missing key press event in resume phase

The GPIO key press event might be missed in the resume phase, if the key
had been released before the system had been resumed to the stage that it
could capture the press event. So we simulate the wakeup key press event
in case the key had been released by the time we got interrupt handler
to run.
Signed-off-by: default avatarJoseph Lo <josephl@nvidia.com>
Signed-off-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 49aac820
...@@ -48,6 +48,7 @@ struct gpio_button_data { ...@@ -48,6 +48,7 @@ struct gpio_button_data {
spinlock_t lock; spinlock_t lock;
bool disabled; bool disabled;
bool key_pressed; bool key_pressed;
bool suspended;
}; };
struct gpio_keys_drvdata { struct gpio_keys_drvdata {
...@@ -396,8 +397,20 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) ...@@ -396,8 +397,20 @@ 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) if (bdata->button->wakeup) {
const struct gpio_keys_button *button = bdata->button;
pm_stay_awake(bdata->input->dev.parent); pm_stay_awake(bdata->input->dev.parent);
if (bdata->suspended &&
(button->type == 0 || button->type == EV_KEY)) {
/*
* Simulate wakeup key press in case the key has
* already released by the time we got interrupt
* handler to run.
*/
input_report_key(bdata->input, button->code, 1);
}
}
mod_delayed_work(system_wq, mod_delayed_work(system_wq,
&bdata->work, &bdata->work,
...@@ -855,6 +868,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev) ...@@ -855,6 +868,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
struct gpio_button_data *bdata = &ddata->data[i]; struct gpio_button_data *bdata = &ddata->data[i];
if (bdata->button->wakeup) if (bdata->button->wakeup)
enable_irq_wake(bdata->irq); enable_irq_wake(bdata->irq);
bdata->suspended = true;
} }
} else { } else {
mutex_lock(&input->mutex); mutex_lock(&input->mutex);
...@@ -878,6 +892,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev) ...@@ -878,6 +892,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
struct gpio_button_data *bdata = &ddata->data[i]; struct gpio_button_data *bdata = &ddata->data[i];
if (bdata->button->wakeup) if (bdata->button->wakeup)
disable_irq_wake(bdata->irq); disable_irq_wake(bdata->irq);
bdata->suspended = false;
} }
} else { } else {
mutex_lock(&input->mutex); mutex_lock(&input->mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment