All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses
@ 2017-10-11  9:46 Hans de Goede
  2017-10-11  9:46 ` [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend Hans de Goede
  2017-10-16  7:36 ` [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Benjamin Tissoires
  0 siblings, 2 replies; 5+ messages in thread
From: Hans de Goede @ 2017-10-11  9:46 UTC (permalink / raw)
  To: Dmitry Torokhov, Benjamin Tissoires
  Cc: Hans de Goede, Gregor Riepl, linux-input

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 e9f0ebf3267a..611b47261df4 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,
@@ -857,6 +879,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 {
@@ -881,7 +904,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.14.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend
  2017-10-11  9:46 [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Hans de Goede
@ 2017-10-11  9:46 ` Hans de Goede
  2017-10-16  7:42   ` Benjamin Tissoires
  2017-10-16  7:36 ` [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Benjamin Tissoires
  1 sibling, 1 reply; 5+ messages in thread
From: Hans de Goede @ 2017-10-11  9:46 UTC (permalink / raw)
  To: Dmitry Torokhov, Benjamin Tissoires
  Cc: Hans de Goede, Gregor Riepl, linux-input

If the power-button is pressed to wakeup the laptop/tablet from suspend
and we report a KEY_POWER event to userspace when woken up this will cause
userspace to immediately suspend the system again which is undesirable.

This commit sets the new no_wakeup_events flag in the gpio_keys_button
struct for the power-button suppressing the undesirable KEY_POWER input
events on wake-up.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-New patch in v2 of this patch-set
---
 drivers/input/misc/soc_button_array.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index 23520df7650f..0f7cce70f748 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -27,6 +27,7 @@ struct soc_button_info {
 	unsigned int event_code;
 	bool autorepeat;
 	bool wakeup;
+	bool no_wakeup_events;
 };
 
 /*
@@ -100,6 +101,7 @@ soc_button_device_create(struct platform_device *pdev,
 		gpio_keys[n_buttons].active_low = 1;
 		gpio_keys[n_buttons].desc = info->name;
 		gpio_keys[n_buttons].wakeup = info->wakeup;
+		gpio_keys[n_buttons].no_wakeup_events = info->no_wakeup_events;
 		/* These devices often use cheap buttons, use 50 ms debounce */
 		gpio_keys[n_buttons].debounce_interval = 50;
 		n_buttons++;
@@ -185,6 +187,7 @@ static int soc_button_parse_btn_desc(struct device *dev,
 		info->name = "power";
 		info->event_code = KEY_POWER;
 		info->wakeup = true;
+		info->no_wakeup_events = true;
 	} else if (upage == 0x07 && usage == 0xe3) {
 		info->name = "home";
 		info->event_code = KEY_LEFTMETA;
@@ -369,7 +372,7 @@ static int soc_button_probe(struct platform_device *pdev)
  * Platforms"
  */
 static struct soc_button_info soc_button_PNP0C40[] = {
-	{ "power", 0, EV_KEY, KEY_POWER, false, true },
+	{ "power", 0, EV_KEY, KEY_POWER, false, true, true },
 	{ "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
 	{ "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
 	{ "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false },
-- 
2.14.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses
  2017-10-11  9:46 [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Hans de Goede
  2017-10-11  9:46 ` [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend Hans de Goede
@ 2017-10-16  7:36 ` Benjamin Tissoires
  2017-10-30 16:32   ` Hans de Goede
  1 sibling, 1 reply; 5+ messages in thread
From: Benjamin Tissoires @ 2017-10-16  7:36 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Dmitry Torokhov, Gregor Riepl, linux-input

Hi Hans,

On Oct 11 2017 or thereabouts, Hans de Goede wrote:
> 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

Is there any particular reason to have a per button timer instead of a
global one?

> ---
>  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 e9f0ebf3267a..611b47261df4 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);

You'd better use the new shiny API timer_setup instead (see
https://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git/commit/?h=for-4.15/use-timer-setup&id=0ee32774aed648854a06bc3fae636f20f5f75a68)
for an example.

>  
>  	if (child) {
>  		bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
> @@ -857,6 +879,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 {
> @@ -881,7 +904,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;

I am not sure why this field is also duplicated in all the buttons,
while we could have only one per device.

Cheers,
Benjamin

> +			}
>  		}
>  	} 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.14.2
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend
  2017-10-11  9:46 ` [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend Hans de Goede
@ 2017-10-16  7:42   ` Benjamin Tissoires
  0 siblings, 0 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2017-10-16  7:42 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Dmitry Torokhov, Gregor Riepl, linux-input

On Oct 11 2017 or thereabouts, Hans de Goede wrote:
> If the power-button is pressed to wakeup the laptop/tablet from suspend
> and we report a KEY_POWER event to userspace when woken up this will cause
> userspace to immediately suspend the system again which is undesirable.
> 
> This commit sets the new no_wakeup_events flag in the gpio_keys_button
> struct for the power-button suppressing the undesirable KEY_POWER input
> events on wake-up.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v2:
> -New patch in v2 of this patch-set
> ---
>  drivers/input/misc/soc_button_array.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
> index 23520df7650f..0f7cce70f748 100644
> --- a/drivers/input/misc/soc_button_array.c
> +++ b/drivers/input/misc/soc_button_array.c
> @@ -27,6 +27,7 @@ struct soc_button_info {
>  	unsigned int event_code;
>  	bool autorepeat;
>  	bool wakeup;
> +	bool no_wakeup_events;
>  };
>  
>  /*
> @@ -100,6 +101,7 @@ soc_button_device_create(struct platform_device *pdev,
>  		gpio_keys[n_buttons].active_low = 1;
>  		gpio_keys[n_buttons].desc = info->name;
>  		gpio_keys[n_buttons].wakeup = info->wakeup;
> +		gpio_keys[n_buttons].no_wakeup_events = info->no_wakeup_events;

This is an API problem in gpio_keys.c, but reading it here makes me
think "this button will never send wakeup events", so it will not wake
up the system. Can't we find a more explicit name?

>  		/* These devices often use cheap buttons, use 50 ms debounce */
>  		gpio_keys[n_buttons].debounce_interval = 50;
>  		n_buttons++;
> @@ -185,6 +187,7 @@ static int soc_button_parse_btn_desc(struct device *dev,
>  		info->name = "power";
>  		info->event_code = KEY_POWER;
>  		info->wakeup = true;
> +		info->no_wakeup_events = true;
>  	} else if (upage == 0x07 && usage == 0xe3) {
>  		info->name = "home";
>  		info->event_code = KEY_LEFTMETA;
> @@ -369,7 +372,7 @@ static int soc_button_probe(struct platform_device *pdev)
>   * Platforms"
>   */
>  static struct soc_button_info soc_button_PNP0C40[] = {
> -	{ "power", 0, EV_KEY, KEY_POWER, false, true },
> +	{ "power", 0, EV_KEY, KEY_POWER, false, true, true },
>  	{ "home", 1, EV_KEY, KEY_LEFTMETA, false, true },

I think we might as well explicitly set the values to false for the
others, or use an explicit assignment in the whole list.

Cheers,
Benjamin

>  	{ "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
>  	{ "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false },
> -- 
> 2.14.2
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses
  2017-10-16  7:36 ` [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Benjamin Tissoires
@ 2017-10-30 16:32   ` Hans de Goede
  0 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2017-10-30 16:32 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: Dmitry Torokhov, Gregor Riepl, linux-input

Hi,

On 16-10-17 09:36, Benjamin Tissoires wrote:
> Hi Hans,
> 
> On Oct 11 2017 or thereabouts, Hans de Goede wrote:
>> 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
> 
> Is there any particular reason to have a per button timer instead of a
> global one?

Not really I was just following the example of the existing
suspended flag, for v3 I've added 2 patches to the series to make the
suspended flag be in the per-device state rather then per-button state.

This actually also has allowed me to completely remove the need for a
timer, which is much better really.

Regards,

Hans


> 
>> ---
>>   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 e9f0ebf3267a..611b47261df4 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);
> 
> You'd better use the new shiny API timer_setup instead (see
> https://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git/commit/?h=for-4.15/use-timer-setup&id=0ee32774aed648854a06bc3fae636f20f5f75a68)
> for an example.
> 
>>   
>>   	if (child) {
>>   		bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
>> @@ -857,6 +879,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 {
>> @@ -881,7 +904,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;
> 
> I am not sure why this field is also duplicated in all the buttons,
> while we could have only one per device.
> 
> Cheers,
> Benjamin
> 
>> +			}
>>   		}
>>   	} 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.14.2
>>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-10-30 16:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11  9:46 [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Hans de Goede
2017-10-11  9:46 ` [PATCH resend v2 2/2] Input: soc_button_array - Suppress power button presses during suspend Hans de Goede
2017-10-16  7:42   ` Benjamin Tissoires
2017-10-16  7:36 ` [PATCH resend v2 1/2] Input: gpio_keys - Allow suppression of input events for wakeup button presses Benjamin Tissoires
2017-10-30 16:32   ` Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.