diff options
author | Hans de Goede <hdegoede@redhat.com> | 2017-08-31 11:45:44 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2017-08-31 11:45:44 +0200 |
commit | 51a2ae761f7a168e5d8e20a164b296a381501ca3 (patch) | |
tree | 29bb4a8823f98f9f77ffa937a0807c2b42429234 /0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch | |
parent | 717a8b5a3cc335ba3ce7d951f16752c7c85d8366 (diff) | |
download | kernel-51a2ae761f7a168e5d8e20a164b296a381501ca3.tar.gz kernel-51a2ae761f7a168e5d8e20a164b296a381501ca3.tar.xz kernel-51a2ae761f7a168e5d8e20a164b296a381501ca3.zip |
Update patches for power-button wakeup issues on Bay / Cherry Trail devices
Add patches to fix an IRQ storm on devices with a MAX17042 fuel-gauge
Diffstat (limited to '0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch')
-rw-r--r-- | 0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch b/0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch new file mode 100644 index 000000000..1f03d710b --- /dev/null +++ b/0001-Input-gpio_keys-Allow-suppression-of-input-events-fo.patch @@ -0,0 +1,163 @@ +From 25bb14c1e78e641049fd1ee0c404a9ccd2755e44 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Sat, 22 Jul 2017 13:00:05 +0200 +Subject: [PATCH 1/2] Input: gpio_keys - Allow suppression of input events for + wakeup button presses + +In some cases it is undesirable for a wakeup button to send input events +to userspace if pressed to wakeup the system (if pressed during suspend). + +A typical example of this is the power-button on laptops / tablets, +sending a KEY_POWER event to userspace when woken up with the power-button +will cause userspace to immediately suspend the system again which is +undesirable. + +For power-buttons attached to a PMIC, or handled by e.g. ACPI, not sending +an input event in this case is take care of by the PMIC / ACPI hardware / +code. But in the case of a GPIO button we need to explicitly suppress the +sending of the input event. + +This commit adds support for this by adding a no_wakeup_events bool to +struct gpio_keys_button, which platform code can set to suppress the +input events for presses of wakeup keys during suspend. + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- +Changes in v2: +-This is a rewrite if my "Input: gpio_keys - Do not report wake button + presses as evdev events" patch. +-Instead of unconditionally ignoring presses of all wake-up buttons during + suspend, this rewrite makes this configurable per button +-This version uses a timer to delay clearing the suspended flag for software + debouncing, rather then jiffy compare magic +--- + drivers/input/keyboard/gpio_keys.c | 33 +++++++++++++++++++++++++++++++-- + include/linux/gpio_keys.h | 3 +++ + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c +index a047b9af8369..fa3a58620407 100644 +--- a/drivers/input/keyboard/gpio_keys.c ++++ b/drivers/input/keyboard/gpio_keys.c +@@ -38,6 +38,7 @@ struct gpio_button_data { + + unsigned short *code; + ++ struct timer_list unsuspend_timer; + struct timer_list release_timer; + unsigned int release_delay; /* in msecs, for IRQ-only buttons */ + +@@ -371,6 +372,9 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) + return; + } + ++ if (state && bdata->button->no_wakeup_events && bdata->suspended) ++ return; ++ + if (type == EV_ABS) { + if (state) + input_event(input, type, button->code, button->value); +@@ -400,6 +404,9 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) + if (bdata->button->wakeup) { + const struct gpio_keys_button *button = bdata->button; + ++ if (bdata->button->no_wakeup_events && bdata->suspended) ++ return IRQ_HANDLED; ++ + pm_stay_awake(bdata->input->dev.parent); + if (bdata->suspended && + (button->type == 0 || button->type == EV_KEY)) { +@@ -445,9 +452,13 @@ 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) ++ if (bdata->button->wakeup) { + pm_wakeup_event(bdata->input->dev.parent, 0); + ++ if (bdata->button->no_wakeup_events && bdata->suspended) ++ goto out; ++ } ++ + input_event(input, EV_KEY, *bdata->code, 1); + input_sync(input); + +@@ -468,6 +479,13 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) + return IRQ_HANDLED; + } + ++static void gpio_keys_unsuspend_timer(unsigned long _data) ++{ ++ struct gpio_button_data *bdata = (struct gpio_button_data *)_data; ++ ++ bdata->suspended = false; ++} ++ + static void gpio_keys_quiesce_key(void *data) + { + struct gpio_button_data *bdata = data; +@@ -476,6 +494,8 @@ static void gpio_keys_quiesce_key(void *data) + cancel_delayed_work_sync(&bdata->work); + else + del_timer_sync(&bdata->release_timer); ++ ++ del_timer_sync(&bdata->unsuspend_timer); + } + + static int gpio_keys_setup_key(struct platform_device *pdev, +@@ -496,6 +516,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, + bdata->input = input; + bdata->button = button; + spin_lock_init(&bdata->lock); ++ setup_timer(&bdata->unsuspend_timer, gpio_keys_unsuspend_timer, ++ (unsigned long)bdata); + + if (child) { + bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, +@@ -868,6 +890,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev) + struct gpio_button_data *bdata = &ddata->data[i]; + if (bdata->button->wakeup) + enable_irq_wake(bdata->irq); ++ del_timer_sync(&bdata->unsuspend_timer); + bdata->suspended = true; + } + } else { +@@ -892,7 +915,13 @@ static int __maybe_unused gpio_keys_resume(struct device *dev) + struct gpio_button_data *bdata = &ddata->data[i]; + if (bdata->button->wakeup) + disable_irq_wake(bdata->irq); +- bdata->suspended = false; ++ if (bdata->button->no_wakeup_events) { ++ mod_timer(&bdata->unsuspend_timer, jiffies + ++ msecs_to_jiffies( ++ bdata->software_debounce)); ++ } else { ++ bdata->suspended = false; ++ } + } + } else { + mutex_lock(&input->mutex); +diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h +index 0b71024c082c..d8a85e52b6bb 100644 +--- a/include/linux/gpio_keys.h ++++ b/include/linux/gpio_keys.h +@@ -15,6 +15,8 @@ struct device; + * @debounce_interval: debounce ticks interval in msecs + * @can_disable: %true indicates that userspace is allowed to + * disable button via sysfs ++ * @no_wakeup_events: For wake-up source buttons only, if %true then no input ++ * events will be generated if pressed while suspended + * @value: axis value for %EV_ABS + * @irq: Irq number in case of interrupt keys + */ +@@ -27,6 +29,7 @@ struct gpio_keys_button { + int wakeup; + int debounce_interval; + bool can_disable; ++ bool no_wakeup_events; + int value; + unsigned int irq; + }; +-- +2.13.4 + |