linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/7] Support inhibiting input devices
       [not found] <20200604072853.GP89269@dtor-ws>
@ 2020-06-05 17:33 ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
                     ` (7 more replies)
  0 siblings, 8 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Userspace might want to implement a policy to temporarily disregard input
from certain devices.

An example use case is a convertible laptop, whose keyboard can be folded
under the screen to create tablet-like experience. The user then must hold
the laptop in such a way that it is difficult to avoid pressing the keyboard
keys. It is therefore desirable to temporarily disregard input from the
keyboard, until it is folded back. This obviously is a policy which should
be kept out of the kernel, but the kernel must provide suitable means to
implement such a policy.

Due to interactions with suspend/resume, a helper has been added for drivers
to decide if the device is being used or not (PATCH 1/7) and it has been
applied to relevant drivers (PATCH 2,4,5,6/7).

PATCH 7/7 adds support for inhibiting input devices.

This work is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/45c2d7bb398f74adfae0017e20b224152fde3822

and

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/4ce0e8a3697edb8fd071110b3af65014512061c7

In this respin the elan_i2c patch is dropped and converting it will be
addressed later.

v2..v3:
- ignored autorepeat events in input_get_disposition() if a key is not
pressed (Hans)
- dropped inhibit()/uninhibit() driver callbacks (Hans)
- split ACPI button patch into taking the lock and using the helper (Rafael)
- dropped the elan_i2c conversion
- fixed typos in exynos adc

v1..v2:
- added input_device_enabled() helper and used it in drivers (Dmitry)
- the fact of open() and close() being called in inhibit/uninhibit paths has
been emphasized in the commit message of PATCH 6/7 (Dmitry)

Andrzej Pietrasiewicz (6):
  Input: add input_device_enabled()
  Input: use input_device_enabled()
  ACPI: button: Access input device's users under appropriate mutex
  ACPI: button: Use input_device_enabled() helper
  iio: adc: exynos: Use input_device_enabled()
  platform/x86: thinkpad_acpi: Use input_device_enabled()

Patrik Fimml (1):
  Input: Add "inhibited" property

 drivers/acpi/button.c                       |   7 +-
 drivers/iio/adc/exynos_adc.c                |  11 +-
 drivers/input/input.c                       | 121 +++++++++++++++++++-
 drivers/input/joystick/xpad.c               |   4 +-
 drivers/input/keyboard/ep93xx_keypad.c      |   2 +-
 drivers/input/keyboard/gpio_keys.c          |   4 +-
 drivers/input/keyboard/imx_keypad.c         |   4 +-
 drivers/input/keyboard/ipaq-micro-keys.c    |   2 +-
 drivers/input/keyboard/lpc32xx-keys.c       |   4 +-
 drivers/input/keyboard/pmic8xxx-keypad.c    |   4 +-
 drivers/input/keyboard/pxa27x_keypad.c      |   2 +-
 drivers/input/keyboard/samsung-keypad.c     |   4 +-
 drivers/input/keyboard/spear-keyboard.c     |   8 +-
 drivers/input/keyboard/st-keyscan.c         |   4 +-
 drivers/input/keyboard/tegra-kbc.c          |   4 +-
 drivers/input/misc/drv260x.c                |   4 +-
 drivers/input/misc/drv2665.c                |   4 +-
 drivers/input/misc/drv2667.c                |   4 +-
 drivers/input/misc/gp2ap002a00f.c           |   4 +-
 drivers/input/misc/kxtj9.c                  |   4 +-
 drivers/input/misc/sirfsoc-onkey.c          |   2 +-
 drivers/input/mouse/navpoint.c              |   4 +-
 drivers/input/touchscreen/ad7879.c          |   6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c    |   4 +-
 drivers/input/touchscreen/auo-pixcir-ts.c   |   8 +-
 drivers/input/touchscreen/bu21029_ts.c      |   4 +-
 drivers/input/touchscreen/chipone_icn8318.c |   4 +-
 drivers/input/touchscreen/cyttsp_core.c     |   4 +-
 drivers/input/touchscreen/eeti_ts.c         |   4 +-
 drivers/input/touchscreen/ektf2127.c        |   4 +-
 drivers/input/touchscreen/imx6ul_tsc.c      |   4 +-
 drivers/input/touchscreen/ipaq-micro-ts.c   |   2 +-
 drivers/input/touchscreen/iqs5xx.c          |   4 +-
 drivers/input/touchscreen/lpc32xx_ts.c      |   4 +-
 drivers/input/touchscreen/melfas_mip4.c     |   4 +-
 drivers/input/touchscreen/mms114.c          |   6 +-
 drivers/input/touchscreen/pixcir_i2c_ts.c   |   8 +-
 drivers/input/touchscreen/ucb1400_ts.c      |   4 +-
 drivers/input/touchscreen/wm97xx-core.c     |  14 ++-
 drivers/input/touchscreen/zforce_ts.c       |   8 +-
 drivers/platform/x86/thinkpad_acpi.c        |   4 +-
 include/linux/input.h                       |  14 ++-
 42 files changed, 230 insertions(+), 95 deletions(-)


base-commit: 3d77e6a8804abcc0504c904bd6e5cdf3a5cf8162
-- 
2.17.1


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

* [PATCH v3 1/7] Input: add input_device_enabled()
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A helper function for drivers to decide if the device is used or not.
A lockdep check is introduced as inspecting ->users should be done under
input device's mutex.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/input.c | 8 ++++++++
 include/linux/input.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3cfd2c18eebd..41377bfa142d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -2127,6 +2127,14 @@ void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
 }
 EXPORT_SYMBOL(input_enable_softrepeat);
 
+bool input_device_enabled(struct input_dev *dev)
+{
+	lockdep_assert_held(&dev->mutex);
+
+	return dev->users > 0;
+}
+EXPORT_SYMBOL_GPL(input_device_enabled);
+
 /**
  * input_register_device - register device with input core
  * @dev: device to be registered
diff --git a/include/linux/input.h b/include/linux/input.h
index 56f2fd32e609..eda4587dba67 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -502,6 +502,8 @@ bool input_match_device_id(const struct input_dev *dev,
 
 void input_enable_softrepeat(struct input_dev *dev, int delay, int period);
 
+bool input_device_enabled(struct input_dev *dev);
+
 extern struct class input_class;
 
 /**
-- 
2.17.1


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

* [PATCH v3 2/7] Input: use input_device_enabled()
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Use the newly added helper in relevant input drivers.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/joystick/xpad.c               |  4 ++--
 drivers/input/keyboard/ep93xx_keypad.c      |  2 +-
 drivers/input/keyboard/gpio_keys.c          |  4 ++--
 drivers/input/keyboard/imx_keypad.c         |  4 ++--
 drivers/input/keyboard/ipaq-micro-keys.c    |  2 +-
 drivers/input/keyboard/lpc32xx-keys.c       |  4 ++--
 drivers/input/keyboard/pmic8xxx-keypad.c    |  4 ++--
 drivers/input/keyboard/pxa27x_keypad.c      |  2 +-
 drivers/input/keyboard/samsung-keypad.c     |  4 ++--
 drivers/input/keyboard/spear-keyboard.c     |  8 ++++----
 drivers/input/keyboard/st-keyscan.c         |  4 ++--
 drivers/input/keyboard/tegra-kbc.c          |  4 ++--
 drivers/input/misc/drv260x.c                |  4 ++--
 drivers/input/misc/drv2665.c                |  4 ++--
 drivers/input/misc/drv2667.c                |  4 ++--
 drivers/input/misc/gp2ap002a00f.c           |  4 ++--
 drivers/input/misc/kxtj9.c                  |  4 ++--
 drivers/input/misc/sirfsoc-onkey.c          |  2 +-
 drivers/input/mouse/navpoint.c              |  4 ++--
 drivers/input/touchscreen/ad7879.c          |  6 +++---
 drivers/input/touchscreen/atmel_mxt_ts.c    |  4 ++--
 drivers/input/touchscreen/auo-pixcir-ts.c   |  8 ++++----
 drivers/input/touchscreen/bu21029_ts.c      |  4 ++--
 drivers/input/touchscreen/chipone_icn8318.c |  4 ++--
 drivers/input/touchscreen/cyttsp_core.c     |  4 ++--
 drivers/input/touchscreen/eeti_ts.c         |  4 ++--
 drivers/input/touchscreen/ektf2127.c        |  4 ++--
 drivers/input/touchscreen/imx6ul_tsc.c      |  4 ++--
 drivers/input/touchscreen/ipaq-micro-ts.c   |  2 +-
 drivers/input/touchscreen/iqs5xx.c          |  4 ++--
 drivers/input/touchscreen/lpc32xx_ts.c      |  4 ++--
 drivers/input/touchscreen/melfas_mip4.c     |  4 ++--
 drivers/input/touchscreen/mms114.c          |  6 +++---
 drivers/input/touchscreen/pixcir_i2c_ts.c   |  8 ++++----
 drivers/input/touchscreen/ucb1400_ts.c      |  4 ++--
 drivers/input/touchscreen/wm97xx-core.c     | 14 +++++++++-----
 drivers/input/touchscreen/zforce_ts.c       |  8 ++++----
 37 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c77cdb3b62b5..d8b6bc2d2171 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1902,7 +1902,7 @@ static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
 			xpad360w_poweroff_controller(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			xpad_stop_input(xpad);
 		mutex_unlock(&input->mutex);
 	}
@@ -1922,7 +1922,7 @@ static int xpad_resume(struct usb_interface *intf)
 		retval = xpad360w_start_input(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users) {
+		if (input_device_enabled(input)) {
 			retval = xpad_start_input(xpad);
 		} else if (xpad->xtype == XTYPE_XBOXONE) {
 			/*
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index 7c70492d9d6b..8194e843d047 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -208,7 +208,7 @@ static int ep93xx_keypad_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		if (!keypad->enabled) {
 			ep93xx_keypad_config(keypad);
 			clk_enable(keypad->clk);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 53c9ff338dea..03ad27189553 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -966,7 +966,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
 			return error;
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			gpio_keys_close(input);
 		mutex_unlock(&input->mutex);
 	}
@@ -984,7 +984,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
 		gpio_keys_disable_wakeup(ddata);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			error = gpio_keys_open(input);
 		mutex_unlock(&input->mutex);
 	}
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 5a46d113e909..1f5c9ea5e9e5 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -532,7 +532,7 @@ static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
 	/* imx kbd can wake up system even clock is disabled */
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		clk_disable_unprepare(kbd->clk);
 
 	mutex_unlock(&input_dev->mutex);
@@ -562,7 +562,7 @@ static int __maybe_unused imx_kbd_noirq_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		ret = clk_prepare_enable(kbd->clk);
 		if (ret)
 			goto err_clk;
diff --git a/drivers/input/keyboard/ipaq-micro-keys.c b/drivers/input/keyboard/ipaq-micro-keys.c
index e3f9e445e880..13a66a8e3411 100644
--- a/drivers/input/keyboard/ipaq-micro-keys.c
+++ b/drivers/input/keyboard/ipaq-micro-keys.c
@@ -140,7 +140,7 @@ static int __maybe_unused micro_key_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		micro_key_start(keys);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c
index 348af2aeb5de..943aeeb0de79 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -273,7 +273,7 @@ static int lpc32xx_kscan_suspend(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		/* Clear IRQ and disable clock */
 		writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
 		clk_disable_unprepare(kscandat->clk);
@@ -292,7 +292,7 @@ static int lpc32xx_kscan_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		/* Enable clock and clear IRQ */
 		retval = clk_prepare_enable(kscandat->clk);
 		if (retval == 0)
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index 91d5811d6f0e..43b4533e7c41 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -633,7 +633,7 @@ static int pmic8xxx_kp_suspend(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			pmic8xxx_kp_disable(kp);
 
 		mutex_unlock(&input_dev->mutex);
@@ -653,7 +653,7 @@ static int pmic8xxx_kp_resume(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			pmic8xxx_kp_enable(kp);
 
 		mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 7e65708b25a4..a7f8257c8a02 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -694,7 +694,7 @@ static int pxa27x_keypad_resume(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users) {
+		if (input_device_enabled(input_dev)) {
 			/* Enable unit clock */
 			ret = clk_prepare_enable(keypad->clk);
 			if (!ret)
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index 70c1d086bdd2..74ec068fbf2f 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -537,7 +537,7 @@ static int samsung_keypad_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		samsung_keypad_stop(keypad);
 
 	samsung_keypad_toggle_wakeup(keypad, true);
@@ -557,7 +557,7 @@ static int samsung_keypad_resume(struct device *dev)
 
 	samsung_keypad_toggle_wakeup(keypad, false);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		samsung_keypad_start(keypad);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 9b8d78f87253..9838c79cb288 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -318,7 +318,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 		writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 
 	} else {
-		if (input_dev->users) {
+		if (input_device_enabled(input_dev)) {
 			writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
 					kbd->io_base + MODE_CTL_REG);
 			clk_disable(kbd->clk);
@@ -326,7 +326,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 	}
 
 	/* store current configuration */
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kbd->mode_ctl_reg = mode_ctl_reg;
 
 	/* restore previous clk state */
@@ -351,12 +351,12 @@ static int __maybe_unused spear_kbd_resume(struct device *dev)
 			disable_irq_wake(kbd->irq);
 		}
 	} else {
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			clk_enable(kbd->clk);
 	}
 
 	/* restore current configuration */
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c
index 27562cd67fb6..a045d61165ac 100644
--- a/drivers/input/keyboard/st-keyscan.c
+++ b/drivers/input/keyboard/st-keyscan.c
@@ -221,7 +221,7 @@ static int keyscan_suspend(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		enable_irq_wake(keypad->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		keyscan_stop(keypad);
 
 	mutex_unlock(&input->mutex);
@@ -239,7 +239,7 @@ static int keyscan_resume(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		disable_irq_wake(keypad->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		retval = keyscan_start(keypad);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index d34d6947960f..9671842a082a 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -756,7 +756,7 @@ static int tegra_kbc_suspend(struct device *dev)
 		enable_irq(kbc->irq);
 		enable_irq_wake(kbc->irq);
 	} else {
-		if (kbc->idev->users)
+		if (input_device_enabled(kbc->idev))
 			tegra_kbc_stop(kbc);
 	}
 	mutex_unlock(&kbc->idev->mutex);
@@ -796,7 +796,7 @@ static int tegra_kbc_resume(struct device *dev)
 			input_sync(kbc->idev);
 		}
 	} else {
-		if (kbc->idev->users)
+		if (input_device_enabled(kbc->idev))
 			err = tegra_kbc_start(kbc);
 	}
 	mutex_unlock(&kbc->idev->mutex);
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index 79d7fa710a71..11c1983e286a 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -580,7 +580,7 @@ static int __maybe_unused drv260x_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap,
 					 DRV260X_MODE,
 					 DRV260X_STANDBY_MASK,
@@ -612,7 +612,7 @@ static int __maybe_unused drv260x_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/drv2665.c b/drivers/input/misc/drv2665.c
index 918ad9c3fa81..e4df1a3b8655 100644
--- a/drivers/input/misc/drv2665.c
+++ b/drivers/input/misc/drv2665.c
@@ -230,7 +230,7 @@ static int __maybe_unused drv2665_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
 					 DRV2665_STANDBY, DRV2665_STANDBY);
 		if (ret) {
@@ -259,7 +259,7 @@ static int __maybe_unused drv2665_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c
index bb9d5784df17..be4be2e0fd6f 100644
--- a/drivers/input/misc/drv2667.c
+++ b/drivers/input/misc/drv2667.c
@@ -405,7 +405,7 @@ static int __maybe_unused drv2667_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
 					 DRV2667_STANDBY, DRV2667_STANDBY);
 		if (ret) {
@@ -434,7 +434,7 @@ static int __maybe_unused drv2667_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c
index 90abda8eea67..5f61ef90b2f2 100644
--- a/drivers/input/misc/gp2ap002a00f.c
+++ b/drivers/input/misc/gp2ap002a00f.c
@@ -230,7 +230,7 @@ static int __maybe_unused gp2a_suspend(struct device *dev)
 		enable_irq_wake(client->irq);
 	} else {
 		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
+		if (input_device_enabled(dt->input))
 			retval = gp2a_disable(dt);
 		mutex_unlock(&dt->input->mutex);
 	}
@@ -248,7 +248,7 @@ static int __maybe_unused gp2a_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 	} else {
 		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
+		if (input_device_enabled(dt->input))
 			retval = gp2a_enable(dt);
 		mutex_unlock(&dt->input->mutex);
 	}
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index 52313c6e3fb3..bbb81617c2b2 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -503,7 +503,7 @@ static int __maybe_unused kxtj9_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kxtj9_disable(tj9);
 
 	mutex_unlock(&input_dev->mutex);
@@ -518,7 +518,7 @@ static int __maybe_unused kxtj9_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kxtj9_enable(tj9);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index 60e1f31ee60a..7982bf8fb839 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -181,7 +181,7 @@ static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev)
 	 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
 	 */
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
 	mutex_unlock(&input->mutex);
 
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c
index 0b75248c8380..643d4b805b64 100644
--- a/drivers/input/mouse/navpoint.c
+++ b/drivers/input/mouse/navpoint.c
@@ -322,7 +322,7 @@ static int __maybe_unused navpoint_suspend(struct device *dev)
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		navpoint_down(navpoint);
 	mutex_unlock(&input->mutex);
 
@@ -336,7 +336,7 @@ static int __maybe_unused navpoint_resume(struct device *dev)
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		navpoint_up(navpoint);
 	mutex_unlock(&input->mutex);
 
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 556a2af46e18..e850853328f1 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -306,7 +306,7 @@ static int __maybe_unused ad7879_suspend(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (!ts->suspended && !ts->disabled && ts->input->users)
+	if (!ts->suspended && !ts->disabled && input_device_enabled(ts->input))
 		__ad7879_disable(ts);
 
 	ts->suspended = true;
@@ -322,7 +322,7 @@ static int __maybe_unused ad7879_resume(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->suspended && !ts->disabled && ts->input->users)
+	if (ts->suspended && !ts->disabled && input_device_enabled(ts->input))
 		__ad7879_enable(ts);
 
 	ts->suspended = false;
@@ -339,7 +339,7 @@ static void ad7879_toggle(struct ad7879 *ts, bool disable)
 {
 	mutex_lock(&ts->input->mutex);
 
-	if (!ts->suspended && ts->input->users != 0) {
+	if (!ts->suspended && input_device_enabled(ts->input)) {
 
 		if (disable) {
 			if (ts->disabled)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ae60442efda0..47b7936bc3e3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3151,7 +3151,7 @@ static int __maybe_unused mxt_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mxt_stop(data);
 
 	mutex_unlock(&input_dev->mutex);
@@ -3174,7 +3174,7 @@ static int __maybe_unused mxt_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mxt_start(data);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c
index 8e9f3b7b8180..c33e63ca6142 100644
--- a/drivers/input/touchscreen/auo-pixcir-ts.c
+++ b/drivers/input/touchscreen/auo-pixcir-ts.c
@@ -414,7 +414,7 @@ static int __maybe_unused auo_pixcir_suspend(struct device *dev)
 	 */
 	if (device_may_wakeup(&client->dev)) {
 		/* need to start device if not open, to be wakeup source */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = auo_pixcir_start(ts);
 			if (ret)
 				goto unlock;
@@ -422,7 +422,7 @@ static int __maybe_unused auo_pixcir_suspend(struct device *dev)
 
 		enable_irq_wake(client->irq);
 		ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = auo_pixcir_stop(ts);
 	}
 
@@ -445,14 +445,14 @@ static int __maybe_unused auo_pixcir_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 
 		/* need to stop device if it was not open on suspend */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = auo_pixcir_stop(ts);
 			if (ret)
 				goto unlock;
 		}
 
 		/* device wakes automatically from SLEEP */
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = auo_pixcir_start(ts);
 	}
 
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 49a8d4bbca3a..341925edb8e6 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -430,7 +430,7 @@ static int __maybe_unused bu21029_suspend(struct device *dev)
 
 	if (!device_may_wakeup(dev)) {
 		mutex_lock(&bu21029->in_dev->mutex);
-		if (bu21029->in_dev->users)
+		if (input_device_enabled(bu21029->in_dev))
 			bu21029_stop_chip(bu21029->in_dev);
 		mutex_unlock(&bu21029->in_dev->mutex);
 	}
@@ -445,7 +445,7 @@ static int __maybe_unused bu21029_resume(struct device *dev)
 
 	if (!device_may_wakeup(dev)) {
 		mutex_lock(&bu21029->in_dev->mutex);
-		if (bu21029->in_dev->users)
+		if (input_device_enabled(bu21029->in_dev))
 			bu21029_start_chip(bu21029->in_dev);
 		mutex_unlock(&bu21029->in_dev->mutex);
 	}
diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c
index d91d2fd78649..f2fb41fb031e 100644
--- a/drivers/input/touchscreen/chipone_icn8318.c
+++ b/drivers/input/touchscreen/chipone_icn8318.c
@@ -154,7 +154,7 @@ static int icn8318_suspend(struct device *dev)
 	struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&data->input->mutex);
-	if (data->input->users)
+	if (input_device_enabled(data->input))
 		icn8318_stop(data->input);
 	mutex_unlock(&data->input->mutex);
 
@@ -166,7 +166,7 @@ static int icn8318_resume(struct device *dev)
 	struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&data->input->mutex);
-	if (data->input->users)
+	if (input_device_enabled(data->input))
 		icn8318_start(data->input);
 	mutex_unlock(&data->input->mutex);
 
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 3f5d463dbeed..6e49cb80ec6d 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -479,7 +479,7 @@ static int __maybe_unused cyttsp_suspend(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->input->users) {
+	if (input_device_enabled(ts->input)) {
 		retval = cyttsp_disable(ts);
 		if (retval == 0)
 			ts->suspended = true;
@@ -496,7 +496,7 @@ static int __maybe_unused cyttsp_resume(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		cyttsp_enable(ts);
 
 	ts->suspended = false;
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 2e1404cd09ec..a639ba7e56ea 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -241,7 +241,7 @@ static int __maybe_unused eeti_ts_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		eeti_ts_stop(eeti);
 
 	mutex_unlock(&input_dev->mutex);
@@ -263,7 +263,7 @@ static int __maybe_unused eeti_ts_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		eeti_ts_start(eeti);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index eadd389cf81f..263bbeb6cee9 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -154,7 +154,7 @@ static int __maybe_unused ektf2127_suspend(struct device *dev)
 	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&ts->input->mutex);
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		ektf2127_stop(ts->input);
 	mutex_unlock(&ts->input->mutex);
 
@@ -166,7 +166,7 @@ static int __maybe_unused ektf2127_resume(struct device *dev)
 	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&ts->input->mutex);
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		ektf2127_start(ts->input);
 	mutex_unlock(&ts->input->mutex);
 
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
index 9ed258854349..59d4a4e9ecc2 100644
--- a/drivers/input/touchscreen/imx6ul_tsc.c
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -509,7 +509,7 @@ static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		imx6ul_tsc_disable(tsc);
 
 		clk_disable_unprepare(tsc->tsc_clk);
@@ -530,7 +530,7 @@ static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		retval = clk_prepare_enable(tsc->adc_clk);
 		if (retval)
 			goto out;
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c
index 5c3977e1af6f..0eb5689fe65f 100644
--- a/drivers/input/touchscreen/ipaq-micro-ts.c
+++ b/drivers/input/touchscreen/ipaq-micro-ts.c
@@ -135,7 +135,7 @@ static int __maybe_unused micro_ts_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		micro_ts_toggle_receive(ts, true);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c
index 5875bb1099a8..8b7b94ef7f39 100644
--- a/drivers/input/touchscreen/iqs5xx.c
+++ b/drivers/input/touchscreen/iqs5xx.c
@@ -1017,7 +1017,7 @@ static int __maybe_unused iqs5xx_suspend(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		error = iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
 
 	mutex_unlock(&input->mutex);
@@ -1036,7 +1036,7 @@ static int __maybe_unused iqs5xx_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		error = iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c
index b2cd9472e2d1..b51450b3d943 100644
--- a/drivers/input/touchscreen/lpc32xx_ts.c
+++ b/drivers/input/touchscreen/lpc32xx_ts.c
@@ -334,7 +334,7 @@ static int lpc32xx_ts_suspend(struct device *dev)
 	 */
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		if (device_may_wakeup(dev))
 			enable_irq_wake(tsc->irq);
 		else
@@ -353,7 +353,7 @@ static int lpc32xx_ts_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		if (device_may_wakeup(dev))
 			disable_irq_wake(tsc->irq);
 		else
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 247c3aaba2d8..d33586919f58 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -1539,7 +1539,7 @@ static int __maybe_unused mip4_suspend(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		ts->wake_irq_enabled = enable_irq_wake(client->irq) == 0;
-	else if (input->users)
+	else if (input_device_enabled(input))
 		mip4_disable(ts);
 
 	mutex_unlock(&input->mutex);
@@ -1557,7 +1557,7 @@ static int __maybe_unused mip4_resume(struct device *dev)
 
 	if (ts->wake_irq_enabled)
 		disable_irq_wake(client->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		mip4_enable(ts);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 2ef1adaed9af..a87caa51204e 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -198,7 +198,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
 	int error;
 
 	mutex_lock(&input_dev->mutex);
-	if (!input_dev->users) {
+	if (!input_device_enabled(input_dev)) {
 		mutex_unlock(&input_dev->mutex);
 		goto out;
 	}
@@ -554,7 +554,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mms114_stop(data);
 	mutex_unlock(&input_dev->mutex);
 
@@ -569,7 +569,7 @@ static int __maybe_unused mms114_resume(struct device *dev)
 	int error;
 
 	mutex_lock(&input_dev->mutex);
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		error = mms114_start(data);
 		if (error < 0) {
 			mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 9aa098577350..dc148b4bed74 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -415,14 +415,14 @@ static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev)
 	mutex_lock(&input->mutex);
 
 	if (device_may_wakeup(&client->dev)) {
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = pixcir_start(ts);
 			if (ret) {
 				dev_err(dev, "Failed to start\n");
 				goto unlock;
 			}
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = pixcir_stop(ts);
 	}
 
@@ -442,14 +442,14 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
 	mutex_lock(&input->mutex);
 
 	if (device_may_wakeup(&client->dev)) {
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = pixcir_stop(ts);
 			if (ret) {
 				dev_err(dev, "Failed to stop\n");
 				goto unlock;
 			}
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = pixcir_start(ts);
 	}
 
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 807d39e18091..e3f2c940ef3d 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -410,7 +410,7 @@ static int __maybe_unused ucb1400_ts_suspend(struct device *dev)
 
 	mutex_lock(&idev->mutex);
 
-	if (idev->users)
+	if (input_device_enabled(idev))
 		ucb1400_ts_stop(ucb);
 
 	mutex_unlock(&idev->mutex);
@@ -424,7 +424,7 @@ static int __maybe_unused ucb1400_ts_resume(struct device *dev)
 
 	mutex_lock(&idev->mutex);
 
-	if (idev->users)
+	if (input_device_enabled(idev))
 		ucb1400_ts_start(ucb);
 
 	mutex_unlock(&idev->mutex);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 0a174bd82915..2c2f1b6c5eff 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -806,23 +806,25 @@ static int __maybe_unused wm97xx_suspend(struct device *dev)
 	else
 		suspend_mode = 0;
 
-	if (wm->input_dev->users)
+	mutex_lock(&wm->input_dev->mutex);
+	if (input_device_enabled(wm->input_dev))
 		cancel_delayed_work_sync(&wm->ts_reader);
 
 	/* Power down the digitiser (bypassing the cache for resume) */
 	reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2);
 	reg &= ~WM97XX_PRP_DET_DIG;
-	if (wm->input_dev->users)
+	if (input_device_enabled(wm->input_dev))
 		reg |= suspend_mode;
 	wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg);
 
 	/* WM9713 has an additional power bit - turn it off if there
 	 * are no users or if suspend mode is zero. */
 	if (wm->id == WM9713_ID2 &&
-	    (!wm->input_dev->users || !suspend_mode)) {
+	    (!input_device_enabled(wm->input_dev) || !suspend_mode)) {
 		reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
 		wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
 	}
+	mutex_unlock(&wm->input_dev->mutex);
 
 	return 0;
 }
@@ -831,11 +833,12 @@ static int __maybe_unused wm97xx_resume(struct device *dev)
 {
 	struct wm97xx *wm = dev_get_drvdata(dev);
 
+	mutex_lock(&wm->input_dev->mutex);
 	/* restore digitiser and gpios */
 	if (wm->id == WM9713_ID2) {
 		wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
 		wm97xx_reg_write(wm, 0x5a, wm->misc);
-		if (wm->input_dev->users) {
+		if (input_device_enabled(wm->input_dev)) {
 			u16 reg;
 			reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
 			wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
@@ -852,11 +855,12 @@ static int __maybe_unused wm97xx_resume(struct device *dev)
 	wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
 	wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
 
-	if (wm->input_dev->users && !wm->pen_irq) {
+	if (input_device_enabled(wm->input_dev) && !wm->pen_irq) {
 		wm->ts_reader_interval = wm->ts_reader_min_interval;
 		queue_delayed_work(wm->ts_workq, &wm->ts_reader,
 				   wm->ts_reader_interval);
 	}
+	mutex_unlock(&wm->input_dev->mutex);
 
 	return 0;
 }
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 5230519b0f74..495629628af6 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -626,14 +626,14 @@ static int __maybe_unused zforce_suspend(struct device *dev)
 		dev_dbg(&client->dev, "suspend while being a wakeup source\n");
 
 		/* Need to start device, if not open, to be a wakeup source. */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = zforce_start(ts);
 			if (ret)
 				goto unlock;
 		}
 
 		enable_irq_wake(client->irq);
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev,
 			"suspend without being a wakeup source\n");
 
@@ -670,12 +670,12 @@ static int __maybe_unused zforce_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 
 		/* need to stop device if it was not open on suspend */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = zforce_stop(ts);
 			if (ret)
 				goto unlock;
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev, "resume without being a wakeup source\n");
 
 		enable_irq(client->irq);
-- 
2.17.1


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

* [PATCH v3 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Inspecting input device's 'users' member should be done under device's
mutex, so add appropriate invocations.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/acpi/button.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 78cfc70cb320..ff7ab291f678 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -456,13 +456,16 @@ static int acpi_button_resume(struct device *dev)
 {
 	struct acpi_device *device = to_acpi_device(dev);
 	struct acpi_button *button = acpi_driver_data(device);
+	struct input_dev *input = button->input;
 
 	button->suspended = false;
-	if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
+	mutex_lock(&input->mutex);
+	if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
 		button->last_state = !!acpi_lid_evaluate_state(device);
 		button->last_time = ktime_get();
 		acpi_lid_initialize_state(device);
 	}
+	mutex_unlock(&input->mutex);
 	return 0;
 }
 #endif
-- 
2.17.1


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

* [PATCH v3 4/7] ACPI: button: Use input_device_enabled() helper
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                     ` (2 preceding siblings ...)
  2020-06-05 17:33   ` [PATCH v3 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A new helper is available, so use it.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/acpi/button.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ff7ab291f678..4deb2b48d03c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -411,7 +411,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
 			mutex_lock(&button->input->mutex);
-			users = button->input->users;
+			users = input_device_enabled(button->input);
 			mutex_unlock(&button->input->mutex);
 			if (users)
 				acpi_lid_update_state(device, true);
@@ -460,7 +460,7 @@ static int acpi_button_resume(struct device *dev)
 
 	button->suspended = false;
 	mutex_lock(&input->mutex);
-	if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
+	if (button->type == ACPI_BUTTON_TYPE_LID && input_device_enabled(input)) {
 		button->last_state = !!acpi_lid_evaluate_state(device);
 		button->last_time = ktime_get();
 		acpi_lid_initialize_state(device);
-- 
2.17.1


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

* [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled()
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                     ` (3 preceding siblings ...)
  2020-06-05 17:33   ` [PATCH v3 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 19:49     ` Michał Mirosław
  2020-06-05 17:33   ` [PATCH v3 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A new helper is available, so use it. Inspecting 'users' member of
input_dev requires taking device's mutex.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/iio/adc/exynos_adc.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 22131a677445..294715bafe25 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -630,10 +630,13 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 	struct exynos_adc *info = dev_id;
 	struct iio_dev *dev = dev_get_drvdata(info->dev);
 	u32 x, y;
-	bool pressed;
+	bool pressed, cont;
 	int ret;
 
-	while (info->input->users) {
+	mutex_lock(&info->input->mutex);
+	cont = input_device_enabled(info->input);
+	mutex_unlock(&info->input->mutex);
+	while (cont) {
 		ret = exynos_read_s3c64xx_ts(dev, &x, &y);
 		if (ret == -ETIMEDOUT)
 			break;
@@ -651,6 +654,10 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 		input_sync(info->input);
 
 		usleep_range(1000, 1100);
+
+		mutex_lock(&info->input->mutex);
+		cont = input_device_enabled(info->input);
+		mutex_unlock(&info->input->mutex);
 	}
 
 	writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
-- 
2.17.1


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

* [PATCH v3 6/7] platform/x86: thinkpad_acpi: Use input_device_enabled()
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                     ` (4 preceding siblings ...)
  2020-06-05 17:33   ` [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:33   ` [PATCH v3 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
  2020-06-07 20:24   ` [PATCH v3 " Pavel Machek
  7 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Use the new helper. Inspecting input device's 'users' member needs to be
done under device's mutex, so add appropriate invocations.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
 drivers/platform/x86/thinkpad_acpi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 0f704484ae1d..8ae11b8c3ebb 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -2671,9 +2671,10 @@ static void hotkey_poll_setup(const bool may_warn)
 	const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
 	const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
 
+	mutex_lock(&tpacpi_inputdev->mutex);
 	if (hotkey_poll_freq > 0 &&
 	    (poll_driver_mask ||
-	     (poll_user_mask && tpacpi_inputdev->users > 0))) {
+	     (poll_user_mask && input_device_enabled(tpacpi_inputdev)))) {
 		if (!tpacpi_hotkey_task) {
 			tpacpi_hotkey_task = kthread_run(hotkey_kthread,
 					NULL, TPACPI_NVRAM_KTHREAD_NAME);
@@ -2690,6 +2691,7 @@ static void hotkey_poll_setup(const bool may_warn)
 				  poll_user_mask, poll_driver_mask);
 		}
 	}
+	mutex_unlock(&tpacpi_inputdev->mutex);
 }
 
 static void hotkey_poll_setup_safe(const bool may_warn)
-- 
2.17.1


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

* [PATCH v3 7/7] Input: Add "inhibited" property
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                     ` (5 preceding siblings ...)
  2020-06-05 17:33   ` [PATCH v3 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
@ 2020-06-05 17:33   ` Andrzej Pietrasiewicz
  2020-06-05 17:41     ` Hans de Goede
  2020-06-07 20:24   ` [PATCH v3 " Pavel Machek
  7 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-05 17:33 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel, Patrik Fimml

From: Patrik Fimml <patrikf@chromium.org>

Userspace might want to implement a policy to temporarily disregard input
from certain devices, including not treating them as wakeup sources.

An example use case is a laptop, whose keyboard can be folded under the
screen to create tablet-like experience. The user then must hold the laptop
in such a way that it is difficult to avoid pressing the keyboard keys. It
is therefore desirable to temporarily disregard input from the keyboard,
until it is folded back. This obviously is a policy which should be kept
out of the kernel, but the kernel must provide suitable means to implement
such a policy.

This patch adds a sysfs interface for exactly this purpose.

To implement the said interface it adds an "inhibited" property to struct
input_dev, and effectively creates four states a device can be in: closed
uninhibited, closed inhibited, open uninhibited, open inhibited. It also
defers calling driver's ->open() and ->close() to until they are actually
needed, e.g. it makes no sense to prepare the underlying device for
generating events (->open()) if the device is inhibited.

              uninhibit
closed      <------------ closed
uninhibited ------------> inhibited
      | ^     inhibit        | ^
 1st  | |               1st  | |
 open | |               open | |
      | |                    | |
      | | last               | | last
      | | close              | | close
      v |     uninhibit      v |
open        <------------ open
uninhibited ------------> inhibited

The top inhibit/uninhibit transition happens when users == 0.
The bottom inhibit/uninhibit transition happens when users > 0.
The left open/close transition happens when !inhibited.
The right open/close transition happens when inhibited.
Due to all transitions being serialized with dev->mutex, it is impossible
to have "diagonal" transitions between closed uninhibited and open
inhibited or between open uninhibited and closed inhibited.

No new callbacks are added to drivers, because their open() and close()
serve exactly the purpose to tell the driver to start/stop providing
events to the input core. Consequently, open() and close() - if provided
- are called in both inhibit and uninhibit paths.

Signed-off-by: Patrik Fimml <patrikf@chromium.org>
Co-developed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/input.c | 115 +++++++++++++++++++++++++++++++++++++++---
 include/linux/input.h |  12 ++++-
 2 files changed, 118 insertions(+), 9 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 41377bfa142d..4110b5797219 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
 	case EV_KEY:
 		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
 
-			/* auto-repeat bypasses state updates */
-			if (value == 2) {
+			/*
+			 * auto-repeat bypasses state updates but repeat
+			 * events are ignored if the key is not pressed
+			 */
+			if (value == 2 && test_bit(code, dev->key)) {
 				disposition = INPUT_PASS_TO_HANDLERS;
 				break;
 			}
@@ -367,8 +370,13 @@ static int input_get_disposition(struct input_dev *dev,
 static void input_handle_event(struct input_dev *dev,
 			       unsigned int type, unsigned int code, int value)
 {
-	int disposition = input_get_disposition(dev, type, code, &value);
+	int disposition;
+
+	/* filter-out events from inhibited devices */
+	if (dev->inhibited)
+		return;
 
+	disposition = input_get_disposition(dev, type, code, &value);
 	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
 		add_input_randomness(type, code, value);
 
@@ -612,7 +620,7 @@ int input_open_device(struct input_handle *handle)
 
 	handle->open++;
 
-	if (dev->users++) {
+	if (dev->users++ || dev->inhibited) {
 		/*
 		 * Device is already opened, so we can exit immediately and
 		 * report success.
@@ -675,10 +683,9 @@ void input_close_device(struct input_handle *handle)
 
 	__input_release_device(handle);
 
-	if (!--dev->users) {
+	if (!dev->inhibited && !--dev->users) {
 		if (dev->poller)
 			input_dev_poller_stop(dev->poller);
-
 		if (dev->close)
 			dev->close(dev);
 	}
@@ -1416,12 +1423,49 @@ static ssize_t input_dev_show_properties(struct device *dev,
 }
 static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
 
+static int input_inhibit_device(struct input_dev *dev);
+static int input_uninhibit_device(struct input_dev *dev);
+
+static ssize_t inhibited_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct input_dev *input_dev = to_input_dev(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", input_dev->inhibited);
+}
+
+static ssize_t inhibited_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t len)
+{
+	struct input_dev *input_dev = to_input_dev(dev);
+	ssize_t rv;
+	bool inhibited;
+
+	if (strtobool(buf, &inhibited))
+		return -EINVAL;
+
+	if (inhibited)
+		rv = input_inhibit_device(input_dev);
+	else
+		rv = input_uninhibit_device(input_dev);
+
+	if (rv != 0)
+		return rv;
+
+	return len;
+}
+
+static DEVICE_ATTR_RW(inhibited);
+
 static struct attribute *input_dev_attrs[] = {
 	&dev_attr_name.attr,
 	&dev_attr_phys.attr,
 	&dev_attr_uniq.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_properties.attr,
+	&dev_attr_inhibited.attr,
 	NULL
 };
 
@@ -1703,6 +1747,63 @@ void input_reset_device(struct input_dev *dev)
 }
 EXPORT_SYMBOL(input_reset_device);
 
+static int input_inhibit_device(struct input_dev *dev)
+{
+	int ret = 0;
+
+	mutex_lock(&dev->mutex);
+
+	if (dev->inhibited)
+		goto out;
+
+	if (dev->users) {
+		if (dev->close)
+			dev->close(dev);
+		if (dev->poller)
+			input_dev_poller_stop(dev->poller);
+	}
+
+	spin_lock_irq(&dev->event_lock);
+	input_dev_release_keys(dev);
+	input_dev_toggle(dev, false);
+	spin_unlock_irq(&dev->event_lock);
+
+	dev->inhibited = true;
+
+out:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
+static int input_uninhibit_device(struct input_dev *dev)
+{
+	int ret = 0;
+
+	mutex_lock(&dev->mutex);
+
+	if (!dev->inhibited)
+		goto out;
+
+	if (dev->users) {
+		if (dev->open) {
+			ret = dev->open(dev);
+			if (ret)
+				goto out;
+		}
+		if (dev->poller)
+			input_dev_poller_start(dev->poller);
+	}
+
+	dev->inhibited = false;
+	spin_lock_irq(&dev->event_lock);
+	input_dev_toggle(dev, true);
+	spin_unlock_irq(&dev->event_lock);
+
+out:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int input_dev_suspend(struct device *dev)
 {
@@ -2131,7 +2232,7 @@ bool input_device_enabled(struct input_dev *dev)
 {
 	lockdep_assert_held(&dev->mutex);
 
-	return dev->users > 0;
+	return !dev->inhibited && dev->users > 0;
 }
 EXPORT_SYMBOL_GPL(input_device_enabled);
 
diff --git a/include/linux/input.h b/include/linux/input.h
index eda4587dba67..0354b298d874 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -90,9 +90,11 @@ enum input_clock_type {
  * @open: this method is called when the very first user calls
  *	input_open_device(). The driver must prepare the device
  *	to start generating events (start polling thread,
- *	request an IRQ, submit URB, etc.)
+ *	request an IRQ, submit URB, etc.). The meaning of open() is
+ *	to start providing events to the input core.
  * @close: this method is called when the very last user calls
- *	input_close_device().
+ *	input_close_device(). The meaning of close() is to stop
+ *	providing events to the input core.
  * @flush: purges the device. Most commonly used to get rid of force
  *	feedback effects loaded into the device when disconnecting
  *	from it
@@ -127,6 +129,10 @@ enum input_clock_type {
  *	and needs not be explicitly unregistered or freed.
  * @timestamp: storage for a timestamp set by input_set_timestamp called
  *  by a driver
+ * @inhibited: indicates that the input device is inhibited. If that is
+ * the case then input core ignores any events generated by the device.
+ * Device's close() is called when it is being inhibited and its open()
+ * is called when it is being uninhibited.
  */
 struct input_dev {
 	const char *name;
@@ -201,6 +207,8 @@ struct input_dev {
 	bool devres_managed;
 
 	ktime_t timestamp[INPUT_CLK_MAX];
+
+	bool inhibited;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
-- 
2.17.1


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

* Re: [PATCH v3 7/7] Input: Add "inhibited" property
  2020-06-05 17:33   ` [PATCH v3 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
@ 2020-06-05 17:41     ` Hans de Goede
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
  0 siblings, 1 reply; 64+ messages in thread
From: Hans de Goede @ 2020-06-05 17:41 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, kernel, Patrik Fimml

Hi,

On 6/5/20 7:33 PM, Andrzej Pietrasiewicz wrote:
> From: Patrik Fimml <patrikf@chromium.org>
> 
> Userspace might want to implement a policy to temporarily disregard input
> from certain devices, including not treating them as wakeup sources.
> 
> An example use case is a laptop, whose keyboard can be folded under the
> screen to create tablet-like experience. The user then must hold the laptop
> in such a way that it is difficult to avoid pressing the keyboard keys. It
> is therefore desirable to temporarily disregard input from the keyboard,
> until it is folded back. This obviously is a policy which should be kept
> out of the kernel, but the kernel must provide suitable means to implement
> such a policy.
> 
> This patch adds a sysfs interface for exactly this purpose.
> 
> To implement the said interface it adds an "inhibited" property to struct
> input_dev, and effectively creates four states a device can be in: closed
> uninhibited, closed inhibited, open uninhibited, open inhibited. It also
> defers calling driver's ->open() and ->close() to until they are actually
> needed, e.g. it makes no sense to prepare the underlying device for
> generating events (->open()) if the device is inhibited.
> 
>                uninhibit
> closed      <------------ closed
> uninhibited ------------> inhibited
>        | ^     inhibit        | ^
>   1st  | |               1st  | |
>   open | |               open | |
>        | |                    | |
>        | | last               | | last
>        | | close              | | close
>        v |     uninhibit      v |
> open        <------------ open
> uninhibited ------------> inhibited
> 
> The top inhibit/uninhibit transition happens when users == 0.
> The bottom inhibit/uninhibit transition happens when users > 0.
> The left open/close transition happens when !inhibited.
> The right open/close transition happens when inhibited.
> Due to all transitions being serialized with dev->mutex, it is impossible
> to have "diagonal" transitions between closed uninhibited and open
> inhibited or between open uninhibited and closed inhibited.
> 
> No new callbacks are added to drivers, because their open() and close()
> serve exactly the purpose to tell the driver to start/stop providing
> events to the input core. Consequently, open() and close() - if provided
> - are called in both inhibit and uninhibit paths.
> 
> Signed-off-by: Patrik Fimml <patrikf@chromium.org>
> Co-developed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
>   drivers/input/input.c | 115 +++++++++++++++++++++++++++++++++++++++---
>   include/linux/input.h |  12 ++++-
>   2 files changed, 118 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 41377bfa142d..4110b5797219 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
>   	case EV_KEY:
>   		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
>   
> -			/* auto-repeat bypasses state updates */
> -			if (value == 2) {
> +			/*
> +			 * auto-repeat bypasses state updates but repeat
> +			 * events are ignored if the key is not pressed
> +			 */
> +			if (value == 2 && test_bit(code, dev->key)) {
>   				disposition = INPUT_PASS_TO_HANDLERS;
>   				break;
>   			}
> @@ -367,8 +370,13 @@ static int input_get_disposition(struct input_dev *dev,
>   static void input_handle_event(struct input_dev *dev,
>   			       unsigned int type, unsigned int code, int value)
>   {
> -	int disposition = input_get_disposition(dev, type, code, &value);
> +	int disposition;
> +
> +	/* filter-out events from inhibited devices */
> +	if (dev->inhibited)
> +		return;
>   
> +	disposition = input_get_disposition(dev, type, code, &value);
>   	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
>   		add_input_randomness(type, code, value);
>   
> @@ -612,7 +620,7 @@ int input_open_device(struct input_handle *handle)
>   
>   	handle->open++;
>   
> -	if (dev->users++) {
> +	if (dev->users++ || dev->inhibited) {
>   		/*
>   		 * Device is already opened, so we can exit immediately and
>   		 * report success.

It seems the comment which is part of the context here may need some
updating because of the inhibit changes ?

Otherwise this patch and the rest of the series looks good to me
now. Thank you very much for your work on this.

Regards,

Hans




> @@ -675,10 +683,9 @@ void input_close_device(struct input_handle *handle)
>   
>   	__input_release_device(handle);
>   
> -	if (!--dev->users) {
> +	if (!dev->inhibited && !--dev->users) {
>   		if (dev->poller)
>   			input_dev_poller_stop(dev->poller);
> -
>   		if (dev->close)
>   			dev->close(dev);
>   	}
> @@ -1416,12 +1423,49 @@ static ssize_t input_dev_show_properties(struct device *dev,
>   }
>   static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
>   
> +static int input_inhibit_device(struct input_dev *dev);
> +static int input_uninhibit_device(struct input_dev *dev);
> +
> +static ssize_t inhibited_show(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct input_dev *input_dev = to_input_dev(dev);
> +
> +	return scnprintf(buf, PAGE_SIZE, "%d\n", input_dev->inhibited);
> +}
> +
> +static ssize_t inhibited_store(struct device *dev,
> +			       struct device_attribute *attr, const char *buf,
> +			       size_t len)
> +{
> +	struct input_dev *input_dev = to_input_dev(dev);
> +	ssize_t rv;
> +	bool inhibited;
> +
> +	if (strtobool(buf, &inhibited))
> +		return -EINVAL;
> +
> +	if (inhibited)
> +		rv = input_inhibit_device(input_dev);
> +	else
> +		rv = input_uninhibit_device(input_dev);
> +
> +	if (rv != 0)
> +		return rv;
> +
> +	return len;
> +}
> +
> +static DEVICE_ATTR_RW(inhibited);
> +
>   static struct attribute *input_dev_attrs[] = {
>   	&dev_attr_name.attr,
>   	&dev_attr_phys.attr,
>   	&dev_attr_uniq.attr,
>   	&dev_attr_modalias.attr,
>   	&dev_attr_properties.attr,
> +	&dev_attr_inhibited.attr,
>   	NULL
>   };
>   
> @@ -1703,6 +1747,63 @@ void input_reset_device(struct input_dev *dev)
>   }
>   EXPORT_SYMBOL(input_reset_device);
>   
> +static int input_inhibit_device(struct input_dev *dev)
> +{
> +	int ret = 0;
> +
> +	mutex_lock(&dev->mutex);
> +
> +	if (dev->inhibited)
> +		goto out;
> +
> +	if (dev->users) {
> +		if (dev->close)
> +			dev->close(dev);
> +		if (dev->poller)
> +			input_dev_poller_stop(dev->poller);
> +	}
> +
> +	spin_lock_irq(&dev->event_lock);
> +	input_dev_release_keys(dev);
> +	input_dev_toggle(dev, false);
> +	spin_unlock_irq(&dev->event_lock);
> +
> +	dev->inhibited = true;
> +
> +out:
> +	mutex_unlock(&dev->mutex);
> +	return ret;
> +}
> +
> +static int input_uninhibit_device(struct input_dev *dev)
> +{
> +	int ret = 0;
> +
> +	mutex_lock(&dev->mutex);
> +
> +	if (!dev->inhibited)
> +		goto out;
> +
> +	if (dev->users) {
> +		if (dev->open) {
> +			ret = dev->open(dev);
> +			if (ret)
> +				goto out;
> +		}
> +		if (dev->poller)
> +			input_dev_poller_start(dev->poller);
> +	}
> +
> +	dev->inhibited = false;
> +	spin_lock_irq(&dev->event_lock);
> +	input_dev_toggle(dev, true);
> +	spin_unlock_irq(&dev->event_lock);
> +
> +out:
> +	mutex_unlock(&dev->mutex);
> +	return ret;
> +}
> +
>   #ifdef CONFIG_PM_SLEEP
>   static int input_dev_suspend(struct device *dev)
>   {
> @@ -2131,7 +2232,7 @@ bool input_device_enabled(struct input_dev *dev)
>   {
>   	lockdep_assert_held(&dev->mutex);
>   
> -	return dev->users > 0;
> +	return !dev->inhibited && dev->users > 0;
>   }
>   EXPORT_SYMBOL_GPL(input_device_enabled);
>   
> diff --git a/include/linux/input.h b/include/linux/input.h
> index eda4587dba67..0354b298d874 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -90,9 +90,11 @@ enum input_clock_type {
>    * @open: this method is called when the very first user calls
>    *	input_open_device(). The driver must prepare the device
>    *	to start generating events (start polling thread,
> - *	request an IRQ, submit URB, etc.)
> + *	request an IRQ, submit URB, etc.). The meaning of open() is
> + *	to start providing events to the input core.
>    * @close: this method is called when the very last user calls
> - *	input_close_device().
> + *	input_close_device(). The meaning of close() is to stop
> + *	providing events to the input core.
>    * @flush: purges the device. Most commonly used to get rid of force
>    *	feedback effects loaded into the device when disconnecting
>    *	from it
> @@ -127,6 +129,10 @@ enum input_clock_type {
>    *	and needs not be explicitly unregistered or freed.
>    * @timestamp: storage for a timestamp set by input_set_timestamp called
>    *  by a driver
> + * @inhibited: indicates that the input device is inhibited. If that is
> + * the case then input core ignores any events generated by the device.
> + * Device's close() is called when it is being inhibited and its open()
> + * is called when it is being uninhibited.
>    */
>   struct input_dev {
>   	const char *name;
> @@ -201,6 +207,8 @@ struct input_dev {
>   	bool devres_managed;
>   
>   	ktime_t timestamp[INPUT_CLK_MAX];
> +
> +	bool inhibited;
>   };
>   #define to_input_dev(d) container_of(d, struct input_dev, dev)
>   
> 


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

* Re: [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled()
  2020-06-05 17:33   ` [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-05 19:49     ` Michał Mirosław
  0 siblings, 0 replies; 64+ messages in thread
From: Michał Mirosław @ 2020-06-05 19:49 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Fri, Jun 05, 2020 at 07:33:33PM +0200, Andrzej Pietrasiewicz wrote:
> A new helper is available, so use it. Inspecting 'users' member of
> input_dev requires taking device's mutex.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
>  drivers/iio/adc/exynos_adc.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
> index 22131a677445..294715bafe25 100644
> --- a/drivers/iio/adc/exynos_adc.c
> +++ b/drivers/iio/adc/exynos_adc.c
> @@ -630,10 +630,13 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
>  	struct exynos_adc *info = dev_id;
>  	struct iio_dev *dev = dev_get_drvdata(info->dev);
>  	u32 x, y;
> -	bool pressed;
> +	bool pressed, cont;
>  	int ret;
>  
> -	while (info->input->users) {
> +	mutex_lock(&info->input->mutex);
> +	cont = input_device_enabled(info->input);
> +	mutex_unlock(&info->input->mutex);
> +	while (cont) {
>  		ret = exynos_read_s3c64xx_ts(dev, &x, &y);
>  		if (ret == -ETIMEDOUT)
>  			break;
> @@ -651,6 +654,10 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
>  		input_sync(info->input);
>  
>  		usleep_range(1000, 1100);
> +
> +		mutex_lock(&info->input->mutex);
> +		cont = input_device_enabled(info->input);
> +		mutex_unlock(&info->input->mutex);
>  	}

The mutex doesn't really protect anything here, but I would nevertheless
suggest this sequence instead:

lock()
while (test) {
	unlock()
	...
	lock()
}
unlock()

Best Regards,
Michał Mirosław

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

* Re: [PATCH v3 0/7] Support inhibiting input devices
  2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                     ` (6 preceding siblings ...)
  2020-06-05 17:33   ` [PATCH v3 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
@ 2020-06-07 20:24   ` Pavel Machek
  2020-06-08  5:37     ` Dmitry Torokhov
  7 siblings, 1 reply; 64+ messages in thread
From: Pavel Machek @ 2020-06-07 20:24 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel

[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]

On Fri 2020-06-05 19:33:28, Andrzej Pietrasiewicz wrote:
> Userspace might want to implement a policy to temporarily disregard input
> from certain devices.

Wow, you certainly cc a lot of lists.

> An example use case is a convertible laptop, whose keyboard can be folded
> under the screen to create tablet-like experience. The user then must hold
> the laptop in such a way that it is difficult to avoid pressing the keyboard
> keys. It is therefore desirable to temporarily disregard input from the
> keyboard, until it is folded back. This obviously is a policy which should
> be kept out of the kernel, but the kernel must provide suitable means to
> implement such a policy.
> 
> Due to interactions with suspend/resume, a helper has been added for drivers
> to decide if the device is being used or not (PATCH 1/7) and it has been
> applied to relevant drivers (PATCH 2,4,5,6/7).

But is that a right way to implement it?

We want this for cellphones, too -- touchscreen should be disabled
while the device is locked in the pocket -- but we really want the
touchscreen hardware to be powered down in that case (because it keeps
SoC busy and eats a _lot_ of electricity).

But simplistic "receive an event and then drop it if device is
inhibited" does not allow that...

Best regards,
								Pavel
								
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

* Re: [PATCH v3 0/7] Support inhibiting input devices
  2020-06-07 20:24   ` [PATCH v3 " Pavel Machek
@ 2020-06-08  5:37     ` Dmitry Torokhov
  2020-06-08  9:28       ` Andrzej Pietrasiewicz
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-06-08  5:37 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Sun, Jun 07, 2020 at 10:24:14PM +0200, Pavel Machek wrote:
> On Fri 2020-06-05 19:33:28, Andrzej Pietrasiewicz wrote:
> > Userspace might want to implement a policy to temporarily disregard input
> > from certain devices.
> 
> Wow, you certainly cc a lot of lists.
> 
> > An example use case is a convertible laptop, whose keyboard can be folded
> > under the screen to create tablet-like experience. The user then must hold
> > the laptop in such a way that it is difficult to avoid pressing the keyboard
> > keys. It is therefore desirable to temporarily disregard input from the
> > keyboard, until it is folded back. This obviously is a policy which should
> > be kept out of the kernel, but the kernel must provide suitable means to
> > implement such a policy.
> > 
> > Due to interactions with suspend/resume, a helper has been added for drivers
> > to decide if the device is being used or not (PATCH 1/7) and it has been
> > applied to relevant drivers (PATCH 2,4,5,6/7).
> 
> But is that a right way to implement it?
> 
> We want this for cellphones, too -- touchscreen should be disabled
> while the device is locked in the pocket -- but we really want the
> touchscreen hardware to be powered down in that case (because it keeps
> SoC busy and eats a _lot_ of electricity).
> 
> But simplistic "receive an event and then drop it if device is
> inhibited" does not allow that...

I do not think you read the entirety of this patch series...

Thanks.

-- 
Dmitry

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

* Re: [PATCH v3 0/7] Support inhibiting input devices
  2020-06-08  5:37     ` Dmitry Torokhov
@ 2020-06-08  9:28       ` Andrzej Pietrasiewicz
  0 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08  9:28 UTC (permalink / raw)
  To: Dmitry Torokhov, Pavel Machek
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel

Hi Pavel,

W dniu 08.06.2020 o 07:37, Dmitry Torokhov pisze:
> On Sun, Jun 07, 2020 at 10:24:14PM +0200, Pavel Machek wrote:
>> On Fri 2020-06-05 19:33:28, Andrzej Pietrasiewicz wrote:
>>> Userspace might want to implement a policy to temporarily disregard input
>>> from certain devices.
>>
>> Wow, you certainly cc a lot of lists.
>>
>>> An example use case is a convertible laptop, whose keyboard can be folded
>>> under the screen to create tablet-like experience. The user then must hold
>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>> keys. It is therefore desirable to temporarily disregard input from the
>>> keyboard, until it is folded back. This obviously is a policy which should
>>> be kept out of the kernel, but the kernel must provide suitable means to
>>> implement such a policy.
>>>
>>> Due to interactions with suspend/resume, a helper has been added for drivers
>>> to decide if the device is being used or not (PATCH 1/7) and it has been
>>> applied to relevant drivers (PATCH 2,4,5,6/7).
>>
>> But is that a right way to implement it?
>>
>> We want this for cellphones, too -- touchscreen should be disabled
>> while the device is locked in the pocket -- but we really want the
>> touchscreen hardware to be powered down in that case (because it keeps
>> SoC busy and eats a _lot_ of electricity).
>>
>> But simplistic "receive an event and then drop it if device is
>> inhibited" does not allow that...
> 
> I do not think you read the entirety of this patch series...
> 

Yeah, kindly read the whole thread. Long story short: Inhibiting _is_ about
ignoring events from inhibited devices. Obviously we can do better than
just that. Indeed, the open() and close() callbacks (which are called at
uninhibiting/inhibiting) mean "start providing events" and "stop providing
events", respectively. How that translates into driver operation is highly
driver-specific and cannot be handled at the input subsystem level, but it
is the place where power savings can be realized: whenever the driver knows
that nobody wants events from it it can do whatever it considers appropriate,
including transitioning the device into low power mode, for example using
PM runtime.

Regards,

Andrzej

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

* [PATCH v4 0/7] Support inhibiting input devices
  2020-06-05 17:41     ` Hans de Goede
@ 2020-06-08 11:22       ` Andrzej Pietrasiewicz
  2020-06-08 11:22         ` [PATCH v4 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
                           ` (8 more replies)
  0 siblings, 9 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

This is a quick respin of v3, with just two small changes, please see
the changelog below.

Userspace might want to implement a policy to temporarily disregard input
from certain devices.

An example use case is a convertible laptop, whose keyboard can be folded
under the screen to create tablet-like experience. The user then must hold
the laptop in such a way that it is difficult to avoid pressing the keyboard
keys. It is therefore desirable to temporarily disregard input from the
keyboard, until it is folded back. This obviously is a policy which should
be kept out of the kernel, but the kernel must provide suitable means to
implement such a policy.

Due to interactions with suspend/resume, a helper has been added for drivers
to decide if the device is being used or not (PATCH 1/7) and it has been
applied to relevant drivers (PATCH 2,4,5,6/7).

PATCH 7/7 adds support for inhibiting input devices.

This work is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/45c2d7bb398f74adfae0017e20b224152fde3822

and

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/4ce0e8a3697edb8fd071110b3af65014512061c7

In this respin the elan_i2c patch is dropped and converting it will be
addressed later.

v3..v4:
- updated the comment in input_open_device() (Hans)
- used more straightforward locking pattern in adc/exynos (Michał)

v2..v3:
- ignored autorepeat events in input_get_disposition() if a key is not
pressed (Hans)
- dropped inhibit()/uninhibit() driver callbacks (Hans)
- split ACPI button patch into taking the lock and using the helper (Rafael)
- dropped the elan_i2c conversion
- fixed typos in exynos adc

v1..v2:
- added input_device_enabled() helper and used it in drivers (Dmitry)
- the fact of open() and close() being called in inhibit/uninhibit paths has
been emphasized in the commit message of PATCH 6/7 (Dmitry)

Andrzej Pietrasiewicz (6):
  Input: add input_device_enabled()
  Input: use input_device_enabled()
  ACPI: button: Access input device's users under appropriate mutex
  ACPI: button: Use input_device_enabled() helper
  iio: adc: exynos: Use input_device_enabled()
  platform/x86: thinkpad_acpi: Use input_device_enabled()

Patrik Fimml (1):
  Input: Add "inhibited" property

 drivers/acpi/button.c                       |   7 +-
 drivers/iio/adc/exynos_adc.c                |   6 +-
 drivers/input/input.c                       | 125 ++++++++++++++++++--
 drivers/input/joystick/xpad.c               |   4 +-
 drivers/input/keyboard/ep93xx_keypad.c      |   2 +-
 drivers/input/keyboard/gpio_keys.c          |   4 +-
 drivers/input/keyboard/imx_keypad.c         |   4 +-
 drivers/input/keyboard/ipaq-micro-keys.c    |   2 +-
 drivers/input/keyboard/lpc32xx-keys.c       |   4 +-
 drivers/input/keyboard/pmic8xxx-keypad.c    |   4 +-
 drivers/input/keyboard/pxa27x_keypad.c      |   2 +-
 drivers/input/keyboard/samsung-keypad.c     |   4 +-
 drivers/input/keyboard/spear-keyboard.c     |   8 +-
 drivers/input/keyboard/st-keyscan.c         |   4 +-
 drivers/input/keyboard/tegra-kbc.c          |   4 +-
 drivers/input/misc/drv260x.c                |   4 +-
 drivers/input/misc/drv2665.c                |   4 +-
 drivers/input/misc/drv2667.c                |   4 +-
 drivers/input/misc/gp2ap002a00f.c           |   4 +-
 drivers/input/misc/kxtj9.c                  |   4 +-
 drivers/input/misc/sirfsoc-onkey.c          |   2 +-
 drivers/input/mouse/navpoint.c              |   4 +-
 drivers/input/touchscreen/ad7879.c          |   6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c    |   4 +-
 drivers/input/touchscreen/auo-pixcir-ts.c   |   8 +-
 drivers/input/touchscreen/bu21029_ts.c      |   4 +-
 drivers/input/touchscreen/chipone_icn8318.c |   4 +-
 drivers/input/touchscreen/cyttsp_core.c     |   4 +-
 drivers/input/touchscreen/eeti_ts.c         |   4 +-
 drivers/input/touchscreen/ektf2127.c        |   4 +-
 drivers/input/touchscreen/imx6ul_tsc.c      |   4 +-
 drivers/input/touchscreen/ipaq-micro-ts.c   |   2 +-
 drivers/input/touchscreen/iqs5xx.c          |   4 +-
 drivers/input/touchscreen/lpc32xx_ts.c      |   4 +-
 drivers/input/touchscreen/melfas_mip4.c     |   4 +-
 drivers/input/touchscreen/mms114.c          |   6 +-
 drivers/input/touchscreen/pixcir_i2c_ts.c   |   8 +-
 drivers/input/touchscreen/ucb1400_ts.c      |   4 +-
 drivers/input/touchscreen/wm97xx-core.c     |  14 ++-
 drivers/input/touchscreen/zforce_ts.c       |   8 +-
 drivers/platform/x86/thinkpad_acpi.c        |   4 +-
 include/linux/input.h                       |  14 ++-
 42 files changed, 228 insertions(+), 96 deletions(-)


base-commit: 3d77e6a8804abcc0504c904bd6e5cdf3a5cf8162
-- 
2.17.1


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

* [PATCH v4 1/7] Input: add input_device_enabled()
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-12-03  6:25           ` Dmitry Torokhov
  2020-06-08 11:22         ` [PATCH v4 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
                           ` (7 subsequent siblings)
  8 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A helper function for drivers to decide if the device is used or not.
A lockdep check is introduced as inspecting ->users should be done under
input device's mutex.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/input.c | 8 ++++++++
 include/linux/input.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3cfd2c18eebd..41377bfa142d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -2127,6 +2127,14 @@ void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
 }
 EXPORT_SYMBOL(input_enable_softrepeat);
 
+bool input_device_enabled(struct input_dev *dev)
+{
+	lockdep_assert_held(&dev->mutex);
+
+	return dev->users > 0;
+}
+EXPORT_SYMBOL_GPL(input_device_enabled);
+
 /**
  * input_register_device - register device with input core
  * @dev: device to be registered
diff --git a/include/linux/input.h b/include/linux/input.h
index 56f2fd32e609..eda4587dba67 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -502,6 +502,8 @@ bool input_match_device_id(const struct input_dev *dev,
 
 void input_enable_softrepeat(struct input_dev *dev, int delay, int period);
 
+bool input_device_enabled(struct input_dev *dev);
+
 extern struct class input_class;
 
 /**
-- 
2.17.1


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

* [PATCH v4 2/7] Input: use input_device_enabled()
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
  2020-06-08 11:22         ` [PATCH v4 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-12-03  6:26           ` Dmitry Torokhov
       [not found]           ` <CGME20201207133237eucas1p26f8484944760a14e51dc7353ed33cd28@eucas1p2.samsung.com>
  2020-06-08 11:22         ` [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
                           ` (6 subsequent siblings)
  8 siblings, 2 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Use the newly added helper in relevant input drivers.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/joystick/xpad.c               |  4 ++--
 drivers/input/keyboard/ep93xx_keypad.c      |  2 +-
 drivers/input/keyboard/gpio_keys.c          |  4 ++--
 drivers/input/keyboard/imx_keypad.c         |  4 ++--
 drivers/input/keyboard/ipaq-micro-keys.c    |  2 +-
 drivers/input/keyboard/lpc32xx-keys.c       |  4 ++--
 drivers/input/keyboard/pmic8xxx-keypad.c    |  4 ++--
 drivers/input/keyboard/pxa27x_keypad.c      |  2 +-
 drivers/input/keyboard/samsung-keypad.c     |  4 ++--
 drivers/input/keyboard/spear-keyboard.c     |  8 ++++----
 drivers/input/keyboard/st-keyscan.c         |  4 ++--
 drivers/input/keyboard/tegra-kbc.c          |  4 ++--
 drivers/input/misc/drv260x.c                |  4 ++--
 drivers/input/misc/drv2665.c                |  4 ++--
 drivers/input/misc/drv2667.c                |  4 ++--
 drivers/input/misc/gp2ap002a00f.c           |  4 ++--
 drivers/input/misc/kxtj9.c                  |  4 ++--
 drivers/input/misc/sirfsoc-onkey.c          |  2 +-
 drivers/input/mouse/navpoint.c              |  4 ++--
 drivers/input/touchscreen/ad7879.c          |  6 +++---
 drivers/input/touchscreen/atmel_mxt_ts.c    |  4 ++--
 drivers/input/touchscreen/auo-pixcir-ts.c   |  8 ++++----
 drivers/input/touchscreen/bu21029_ts.c      |  4 ++--
 drivers/input/touchscreen/chipone_icn8318.c |  4 ++--
 drivers/input/touchscreen/cyttsp_core.c     |  4 ++--
 drivers/input/touchscreen/eeti_ts.c         |  4 ++--
 drivers/input/touchscreen/ektf2127.c        |  4 ++--
 drivers/input/touchscreen/imx6ul_tsc.c      |  4 ++--
 drivers/input/touchscreen/ipaq-micro-ts.c   |  2 +-
 drivers/input/touchscreen/iqs5xx.c          |  4 ++--
 drivers/input/touchscreen/lpc32xx_ts.c      |  4 ++--
 drivers/input/touchscreen/melfas_mip4.c     |  4 ++--
 drivers/input/touchscreen/mms114.c          |  6 +++---
 drivers/input/touchscreen/pixcir_i2c_ts.c   |  8 ++++----
 drivers/input/touchscreen/ucb1400_ts.c      |  4 ++--
 drivers/input/touchscreen/wm97xx-core.c     | 14 +++++++++-----
 drivers/input/touchscreen/zforce_ts.c       |  8 ++++----
 37 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c77cdb3b62b5..d8b6bc2d2171 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1902,7 +1902,7 @@ static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
 			xpad360w_poweroff_controller(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			xpad_stop_input(xpad);
 		mutex_unlock(&input->mutex);
 	}
@@ -1922,7 +1922,7 @@ static int xpad_resume(struct usb_interface *intf)
 		retval = xpad360w_start_input(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users) {
+		if (input_device_enabled(input)) {
 			retval = xpad_start_input(xpad);
 		} else if (xpad->xtype == XTYPE_XBOXONE) {
 			/*
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index 7c70492d9d6b..8194e843d047 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -208,7 +208,7 @@ static int ep93xx_keypad_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		if (!keypad->enabled) {
 			ep93xx_keypad_config(keypad);
 			clk_enable(keypad->clk);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 53c9ff338dea..03ad27189553 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -966,7 +966,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
 			return error;
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			gpio_keys_close(input);
 		mutex_unlock(&input->mutex);
 	}
@@ -984,7 +984,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
 		gpio_keys_disable_wakeup(ddata);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input_device_enabled(input))
 			error = gpio_keys_open(input);
 		mutex_unlock(&input->mutex);
 	}
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 5a46d113e909..1f5c9ea5e9e5 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -532,7 +532,7 @@ static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
 	/* imx kbd can wake up system even clock is disabled */
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		clk_disable_unprepare(kbd->clk);
 
 	mutex_unlock(&input_dev->mutex);
@@ -562,7 +562,7 @@ static int __maybe_unused imx_kbd_noirq_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		ret = clk_prepare_enable(kbd->clk);
 		if (ret)
 			goto err_clk;
diff --git a/drivers/input/keyboard/ipaq-micro-keys.c b/drivers/input/keyboard/ipaq-micro-keys.c
index e3f9e445e880..13a66a8e3411 100644
--- a/drivers/input/keyboard/ipaq-micro-keys.c
+++ b/drivers/input/keyboard/ipaq-micro-keys.c
@@ -140,7 +140,7 @@ static int __maybe_unused micro_key_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		micro_key_start(keys);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c
index 348af2aeb5de..943aeeb0de79 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -273,7 +273,7 @@ static int lpc32xx_kscan_suspend(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		/* Clear IRQ and disable clock */
 		writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
 		clk_disable_unprepare(kscandat->clk);
@@ -292,7 +292,7 @@ static int lpc32xx_kscan_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		/* Enable clock and clear IRQ */
 		retval = clk_prepare_enable(kscandat->clk);
 		if (retval == 0)
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index 91d5811d6f0e..43b4533e7c41 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -633,7 +633,7 @@ static int pmic8xxx_kp_suspend(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			pmic8xxx_kp_disable(kp);
 
 		mutex_unlock(&input_dev->mutex);
@@ -653,7 +653,7 @@ static int pmic8xxx_kp_resume(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			pmic8xxx_kp_enable(kp);
 
 		mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 7e65708b25a4..a7f8257c8a02 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -694,7 +694,7 @@ static int pxa27x_keypad_resume(struct device *dev)
 	} else {
 		mutex_lock(&input_dev->mutex);
 
-		if (input_dev->users) {
+		if (input_device_enabled(input_dev)) {
 			/* Enable unit clock */
 			ret = clk_prepare_enable(keypad->clk);
 			if (!ret)
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index 70c1d086bdd2..74ec068fbf2f 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -537,7 +537,7 @@ static int samsung_keypad_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		samsung_keypad_stop(keypad);
 
 	samsung_keypad_toggle_wakeup(keypad, true);
@@ -557,7 +557,7 @@ static int samsung_keypad_resume(struct device *dev)
 
 	samsung_keypad_toggle_wakeup(keypad, false);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		samsung_keypad_start(keypad);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 9b8d78f87253..9838c79cb288 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -318,7 +318,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 		writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
 
 	} else {
-		if (input_dev->users) {
+		if (input_device_enabled(input_dev)) {
 			writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
 					kbd->io_base + MODE_CTL_REG);
 			clk_disable(kbd->clk);
@@ -326,7 +326,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 	}
 
 	/* store current configuration */
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kbd->mode_ctl_reg = mode_ctl_reg;
 
 	/* restore previous clk state */
@@ -351,12 +351,12 @@ static int __maybe_unused spear_kbd_resume(struct device *dev)
 			disable_irq_wake(kbd->irq);
 		}
 	} else {
-		if (input_dev->users)
+		if (input_device_enabled(input_dev))
 			clk_enable(kbd->clk);
 	}
 
 	/* restore current configuration */
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c
index 27562cd67fb6..a045d61165ac 100644
--- a/drivers/input/keyboard/st-keyscan.c
+++ b/drivers/input/keyboard/st-keyscan.c
@@ -221,7 +221,7 @@ static int keyscan_suspend(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		enable_irq_wake(keypad->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		keyscan_stop(keypad);
 
 	mutex_unlock(&input->mutex);
@@ -239,7 +239,7 @@ static int keyscan_resume(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		disable_irq_wake(keypad->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		retval = keyscan_start(keypad);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index d34d6947960f..9671842a082a 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -756,7 +756,7 @@ static int tegra_kbc_suspend(struct device *dev)
 		enable_irq(kbc->irq);
 		enable_irq_wake(kbc->irq);
 	} else {
-		if (kbc->idev->users)
+		if (input_device_enabled(kbc->idev))
 			tegra_kbc_stop(kbc);
 	}
 	mutex_unlock(&kbc->idev->mutex);
@@ -796,7 +796,7 @@ static int tegra_kbc_resume(struct device *dev)
 			input_sync(kbc->idev);
 		}
 	} else {
-		if (kbc->idev->users)
+		if (input_device_enabled(kbc->idev))
 			err = tegra_kbc_start(kbc);
 	}
 	mutex_unlock(&kbc->idev->mutex);
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index 79d7fa710a71..11c1983e286a 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -580,7 +580,7 @@ static int __maybe_unused drv260x_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap,
 					 DRV260X_MODE,
 					 DRV260X_STANDBY_MASK,
@@ -612,7 +612,7 @@ static int __maybe_unused drv260x_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/drv2665.c b/drivers/input/misc/drv2665.c
index 918ad9c3fa81..e4df1a3b8655 100644
--- a/drivers/input/misc/drv2665.c
+++ b/drivers/input/misc/drv2665.c
@@ -230,7 +230,7 @@ static int __maybe_unused drv2665_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
 					 DRV2665_STANDBY, DRV2665_STANDBY);
 		if (ret) {
@@ -259,7 +259,7 @@ static int __maybe_unused drv2665_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c
index bb9d5784df17..be4be2e0fd6f 100644
--- a/drivers/input/misc/drv2667.c
+++ b/drivers/input/misc/drv2667.c
@@ -405,7 +405,7 @@ static int __maybe_unused drv2667_suspend(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
 					 DRV2667_STANDBY, DRV2667_STANDBY);
 		if (ret) {
@@ -434,7 +434,7 @@ static int __maybe_unused drv2667_resume(struct device *dev)
 
 	mutex_lock(&haptics->input_dev->mutex);
 
-	if (haptics->input_dev->users) {
+	if (input_device_enabled(haptics->input_dev)) {
 		ret = regulator_enable(haptics->regulator);
 		if (ret) {
 			dev_err(dev, "Failed to enable regulator\n");
diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c
index 90abda8eea67..5f61ef90b2f2 100644
--- a/drivers/input/misc/gp2ap002a00f.c
+++ b/drivers/input/misc/gp2ap002a00f.c
@@ -230,7 +230,7 @@ static int __maybe_unused gp2a_suspend(struct device *dev)
 		enable_irq_wake(client->irq);
 	} else {
 		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
+		if (input_device_enabled(dt->input))
 			retval = gp2a_disable(dt);
 		mutex_unlock(&dt->input->mutex);
 	}
@@ -248,7 +248,7 @@ static int __maybe_unused gp2a_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 	} else {
 		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
+		if (input_device_enabled(dt->input))
 			retval = gp2a_enable(dt);
 		mutex_unlock(&dt->input->mutex);
 	}
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index 52313c6e3fb3..bbb81617c2b2 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -503,7 +503,7 @@ static int __maybe_unused kxtj9_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kxtj9_disable(tj9);
 
 	mutex_unlock(&input_dev->mutex);
@@ -518,7 +518,7 @@ static int __maybe_unused kxtj9_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		kxtj9_enable(tj9);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index 60e1f31ee60a..7982bf8fb839 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -181,7 +181,7 @@ static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev)
 	 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
 	 */
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		sirfsoc_pwrc_toggle_interrupts(pwrcdrv, true);
 	mutex_unlock(&input->mutex);
 
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c
index 0b75248c8380..643d4b805b64 100644
--- a/drivers/input/mouse/navpoint.c
+++ b/drivers/input/mouse/navpoint.c
@@ -322,7 +322,7 @@ static int __maybe_unused navpoint_suspend(struct device *dev)
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		navpoint_down(navpoint);
 	mutex_unlock(&input->mutex);
 
@@ -336,7 +336,7 @@ static int __maybe_unused navpoint_resume(struct device *dev)
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
-	if (input->users)
+	if (input_device_enabled(input))
 		navpoint_up(navpoint);
 	mutex_unlock(&input->mutex);
 
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 556a2af46e18..e850853328f1 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -306,7 +306,7 @@ static int __maybe_unused ad7879_suspend(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (!ts->suspended && !ts->disabled && ts->input->users)
+	if (!ts->suspended && !ts->disabled && input_device_enabled(ts->input))
 		__ad7879_disable(ts);
 
 	ts->suspended = true;
@@ -322,7 +322,7 @@ static int __maybe_unused ad7879_resume(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->suspended && !ts->disabled && ts->input->users)
+	if (ts->suspended && !ts->disabled && input_device_enabled(ts->input))
 		__ad7879_enable(ts);
 
 	ts->suspended = false;
@@ -339,7 +339,7 @@ static void ad7879_toggle(struct ad7879 *ts, bool disable)
 {
 	mutex_lock(&ts->input->mutex);
 
-	if (!ts->suspended && ts->input->users != 0) {
+	if (!ts->suspended && input_device_enabled(ts->input)) {
 
 		if (disable) {
 			if (ts->disabled)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ae60442efda0..47b7936bc3e3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3151,7 +3151,7 @@ static int __maybe_unused mxt_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mxt_stop(data);
 
 	mutex_unlock(&input_dev->mutex);
@@ -3174,7 +3174,7 @@ static int __maybe_unused mxt_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mxt_start(data);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c
index 8e9f3b7b8180..c33e63ca6142 100644
--- a/drivers/input/touchscreen/auo-pixcir-ts.c
+++ b/drivers/input/touchscreen/auo-pixcir-ts.c
@@ -414,7 +414,7 @@ static int __maybe_unused auo_pixcir_suspend(struct device *dev)
 	 */
 	if (device_may_wakeup(&client->dev)) {
 		/* need to start device if not open, to be wakeup source */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = auo_pixcir_start(ts);
 			if (ret)
 				goto unlock;
@@ -422,7 +422,7 @@ static int __maybe_unused auo_pixcir_suspend(struct device *dev)
 
 		enable_irq_wake(client->irq);
 		ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = auo_pixcir_stop(ts);
 	}
 
@@ -445,14 +445,14 @@ static int __maybe_unused auo_pixcir_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 
 		/* need to stop device if it was not open on suspend */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = auo_pixcir_stop(ts);
 			if (ret)
 				goto unlock;
 		}
 
 		/* device wakes automatically from SLEEP */
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = auo_pixcir_start(ts);
 	}
 
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 49a8d4bbca3a..341925edb8e6 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -430,7 +430,7 @@ static int __maybe_unused bu21029_suspend(struct device *dev)
 
 	if (!device_may_wakeup(dev)) {
 		mutex_lock(&bu21029->in_dev->mutex);
-		if (bu21029->in_dev->users)
+		if (input_device_enabled(bu21029->in_dev))
 			bu21029_stop_chip(bu21029->in_dev);
 		mutex_unlock(&bu21029->in_dev->mutex);
 	}
@@ -445,7 +445,7 @@ static int __maybe_unused bu21029_resume(struct device *dev)
 
 	if (!device_may_wakeup(dev)) {
 		mutex_lock(&bu21029->in_dev->mutex);
-		if (bu21029->in_dev->users)
+		if (input_device_enabled(bu21029->in_dev))
 			bu21029_start_chip(bu21029->in_dev);
 		mutex_unlock(&bu21029->in_dev->mutex);
 	}
diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c
index d91d2fd78649..f2fb41fb031e 100644
--- a/drivers/input/touchscreen/chipone_icn8318.c
+++ b/drivers/input/touchscreen/chipone_icn8318.c
@@ -154,7 +154,7 @@ static int icn8318_suspend(struct device *dev)
 	struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&data->input->mutex);
-	if (data->input->users)
+	if (input_device_enabled(data->input))
 		icn8318_stop(data->input);
 	mutex_unlock(&data->input->mutex);
 
@@ -166,7 +166,7 @@ static int icn8318_resume(struct device *dev)
 	struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&data->input->mutex);
-	if (data->input->users)
+	if (input_device_enabled(data->input))
 		icn8318_start(data->input);
 	mutex_unlock(&data->input->mutex);
 
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 3f5d463dbeed..6e49cb80ec6d 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -479,7 +479,7 @@ static int __maybe_unused cyttsp_suspend(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->input->users) {
+	if (input_device_enabled(ts->input)) {
 		retval = cyttsp_disable(ts);
 		if (retval == 0)
 			ts->suspended = true;
@@ -496,7 +496,7 @@ static int __maybe_unused cyttsp_resume(struct device *dev)
 
 	mutex_lock(&ts->input->mutex);
 
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		cyttsp_enable(ts);
 
 	ts->suspended = false;
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 2e1404cd09ec..a639ba7e56ea 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -241,7 +241,7 @@ static int __maybe_unused eeti_ts_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		eeti_ts_stop(eeti);
 
 	mutex_unlock(&input_dev->mutex);
@@ -263,7 +263,7 @@ static int __maybe_unused eeti_ts_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		eeti_ts_start(eeti);
 
 	mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index eadd389cf81f..263bbeb6cee9 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -154,7 +154,7 @@ static int __maybe_unused ektf2127_suspend(struct device *dev)
 	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&ts->input->mutex);
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		ektf2127_stop(ts->input);
 	mutex_unlock(&ts->input->mutex);
 
@@ -166,7 +166,7 @@ static int __maybe_unused ektf2127_resume(struct device *dev)
 	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
 
 	mutex_lock(&ts->input->mutex);
-	if (ts->input->users)
+	if (input_device_enabled(ts->input))
 		ektf2127_start(ts->input);
 	mutex_unlock(&ts->input->mutex);
 
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
index 9ed258854349..59d4a4e9ecc2 100644
--- a/drivers/input/touchscreen/imx6ul_tsc.c
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -509,7 +509,7 @@ static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		imx6ul_tsc_disable(tsc);
 
 		clk_disable_unprepare(tsc->tsc_clk);
@@ -530,7 +530,7 @@ static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
 
 	mutex_lock(&input_dev->mutex);
 
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		retval = clk_prepare_enable(tsc->adc_clk);
 		if (retval)
 			goto out;
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c
index 5c3977e1af6f..0eb5689fe65f 100644
--- a/drivers/input/touchscreen/ipaq-micro-ts.c
+++ b/drivers/input/touchscreen/ipaq-micro-ts.c
@@ -135,7 +135,7 @@ static int __maybe_unused micro_ts_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		micro_ts_toggle_receive(ts, true);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c
index 5875bb1099a8..8b7b94ef7f39 100644
--- a/drivers/input/touchscreen/iqs5xx.c
+++ b/drivers/input/touchscreen/iqs5xx.c
@@ -1017,7 +1017,7 @@ static int __maybe_unused iqs5xx_suspend(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		error = iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
 
 	mutex_unlock(&input->mutex);
@@ -1036,7 +1036,7 @@ static int __maybe_unused iqs5xx_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users)
+	if (input_device_enabled(input))
 		error = iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c
index b2cd9472e2d1..b51450b3d943 100644
--- a/drivers/input/touchscreen/lpc32xx_ts.c
+++ b/drivers/input/touchscreen/lpc32xx_ts.c
@@ -334,7 +334,7 @@ static int lpc32xx_ts_suspend(struct device *dev)
 	 */
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		if (device_may_wakeup(dev))
 			enable_irq_wake(tsc->irq);
 		else
@@ -353,7 +353,7 @@ static int lpc32xx_ts_resume(struct device *dev)
 
 	mutex_lock(&input->mutex);
 
-	if (input->users) {
+	if (input_device_enabled(input)) {
 		if (device_may_wakeup(dev))
 			disable_irq_wake(tsc->irq);
 		else
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 247c3aaba2d8..d33586919f58 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -1539,7 +1539,7 @@ static int __maybe_unused mip4_suspend(struct device *dev)
 
 	if (device_may_wakeup(dev))
 		ts->wake_irq_enabled = enable_irq_wake(client->irq) == 0;
-	else if (input->users)
+	else if (input_device_enabled(input))
 		mip4_disable(ts);
 
 	mutex_unlock(&input->mutex);
@@ -1557,7 +1557,7 @@ static int __maybe_unused mip4_resume(struct device *dev)
 
 	if (ts->wake_irq_enabled)
 		disable_irq_wake(client->irq);
-	else if (input->users)
+	else if (input_device_enabled(input))
 		mip4_enable(ts);
 
 	mutex_unlock(&input->mutex);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 2ef1adaed9af..a87caa51204e 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -198,7 +198,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
 	int error;
 
 	mutex_lock(&input_dev->mutex);
-	if (!input_dev->users) {
+	if (!input_device_enabled(input_dev)) {
 		mutex_unlock(&input_dev->mutex);
 		goto out;
 	}
@@ -554,7 +554,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
-	if (input_dev->users)
+	if (input_device_enabled(input_dev))
 		mms114_stop(data);
 	mutex_unlock(&input_dev->mutex);
 
@@ -569,7 +569,7 @@ static int __maybe_unused mms114_resume(struct device *dev)
 	int error;
 
 	mutex_lock(&input_dev->mutex);
-	if (input_dev->users) {
+	if (input_device_enabled(input_dev)) {
 		error = mms114_start(data);
 		if (error < 0) {
 			mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 9aa098577350..dc148b4bed74 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -415,14 +415,14 @@ static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev)
 	mutex_lock(&input->mutex);
 
 	if (device_may_wakeup(&client->dev)) {
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = pixcir_start(ts);
 			if (ret) {
 				dev_err(dev, "Failed to start\n");
 				goto unlock;
 			}
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = pixcir_stop(ts);
 	}
 
@@ -442,14 +442,14 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
 	mutex_lock(&input->mutex);
 
 	if (device_may_wakeup(&client->dev)) {
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = pixcir_stop(ts);
 			if (ret) {
 				dev_err(dev, "Failed to stop\n");
 				goto unlock;
 			}
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		ret = pixcir_start(ts);
 	}
 
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 807d39e18091..e3f2c940ef3d 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -410,7 +410,7 @@ static int __maybe_unused ucb1400_ts_suspend(struct device *dev)
 
 	mutex_lock(&idev->mutex);
 
-	if (idev->users)
+	if (input_device_enabled(idev))
 		ucb1400_ts_stop(ucb);
 
 	mutex_unlock(&idev->mutex);
@@ -424,7 +424,7 @@ static int __maybe_unused ucb1400_ts_resume(struct device *dev)
 
 	mutex_lock(&idev->mutex);
 
-	if (idev->users)
+	if (input_device_enabled(idev))
 		ucb1400_ts_start(ucb);
 
 	mutex_unlock(&idev->mutex);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 0a174bd82915..2c2f1b6c5eff 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -806,23 +806,25 @@ static int __maybe_unused wm97xx_suspend(struct device *dev)
 	else
 		suspend_mode = 0;
 
-	if (wm->input_dev->users)
+	mutex_lock(&wm->input_dev->mutex);
+	if (input_device_enabled(wm->input_dev))
 		cancel_delayed_work_sync(&wm->ts_reader);
 
 	/* Power down the digitiser (bypassing the cache for resume) */
 	reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2);
 	reg &= ~WM97XX_PRP_DET_DIG;
-	if (wm->input_dev->users)
+	if (input_device_enabled(wm->input_dev))
 		reg |= suspend_mode;
 	wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg);
 
 	/* WM9713 has an additional power bit - turn it off if there
 	 * are no users or if suspend mode is zero. */
 	if (wm->id == WM9713_ID2 &&
-	    (!wm->input_dev->users || !suspend_mode)) {
+	    (!input_device_enabled(wm->input_dev) || !suspend_mode)) {
 		reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
 		wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
 	}
+	mutex_unlock(&wm->input_dev->mutex);
 
 	return 0;
 }
@@ -831,11 +833,12 @@ static int __maybe_unused wm97xx_resume(struct device *dev)
 {
 	struct wm97xx *wm = dev_get_drvdata(dev);
 
+	mutex_lock(&wm->input_dev->mutex);
 	/* restore digitiser and gpios */
 	if (wm->id == WM9713_ID2) {
 		wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
 		wm97xx_reg_write(wm, 0x5a, wm->misc);
-		if (wm->input_dev->users) {
+		if (input_device_enabled(wm->input_dev)) {
 			u16 reg;
 			reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
 			wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
@@ -852,11 +855,12 @@ static int __maybe_unused wm97xx_resume(struct device *dev)
 	wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
 	wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
 
-	if (wm->input_dev->users && !wm->pen_irq) {
+	if (input_device_enabled(wm->input_dev) && !wm->pen_irq) {
 		wm->ts_reader_interval = wm->ts_reader_min_interval;
 		queue_delayed_work(wm->ts_workq, &wm->ts_reader,
 				   wm->ts_reader_interval);
 	}
+	mutex_unlock(&wm->input_dev->mutex);
 
 	return 0;
 }
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 5230519b0f74..495629628af6 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -626,14 +626,14 @@ static int __maybe_unused zforce_suspend(struct device *dev)
 		dev_dbg(&client->dev, "suspend while being a wakeup source\n");
 
 		/* Need to start device, if not open, to be a wakeup source. */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = zforce_start(ts);
 			if (ret)
 				goto unlock;
 		}
 
 		enable_irq_wake(client->irq);
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev,
 			"suspend without being a wakeup source\n");
 
@@ -670,12 +670,12 @@ static int __maybe_unused zforce_resume(struct device *dev)
 		disable_irq_wake(client->irq);
 
 		/* need to stop device if it was not open on suspend */
-		if (!input->users) {
+		if (!input_device_enabled(input)) {
 			ret = zforce_stop(ts);
 			if (ret)
 				goto unlock;
 		}
-	} else if (input->users) {
+	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev, "resume without being a wakeup source\n");
 
 		enable_irq(client->irq);
-- 
2.17.1


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

* [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
  2020-06-08 11:22         ` [PATCH v4 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
  2020-06-08 11:22         ` [PATCH v4 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-06-24 15:00           ` Rafael J. Wysocki
  2020-06-08 11:22         ` [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
                           ` (5 subsequent siblings)
  8 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Inspecting input device's 'users' member should be done under device's
mutex, so add appropriate invocations.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/acpi/button.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 78cfc70cb320..ff7ab291f678 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -456,13 +456,16 @@ static int acpi_button_resume(struct device *dev)
 {
 	struct acpi_device *device = to_acpi_device(dev);
 	struct acpi_button *button = acpi_driver_data(device);
+	struct input_dev *input = button->input;
 
 	button->suspended = false;
-	if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
+	mutex_lock(&input->mutex);
+	if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
 		button->last_state = !!acpi_lid_evaluate_state(device);
 		button->last_time = ktime_get();
 		acpi_lid_initialize_state(device);
 	}
+	mutex_unlock(&input->mutex);
 	return 0;
 }
 #endif
-- 
2.17.1


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

* [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (2 preceding siblings ...)
  2020-06-08 11:22         ` [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-06-25  5:24           ` Dmitry Torokhov
  2020-06-08 11:22         ` [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
                           ` (4 subsequent siblings)
  8 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A new helper is available, so use it.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/acpi/button.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ff7ab291f678..4deb2b48d03c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -411,7 +411,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
 			mutex_lock(&button->input->mutex);
-			users = button->input->users;
+			users = input_device_enabled(button->input);
 			mutex_unlock(&button->input->mutex);
 			if (users)
 				acpi_lid_update_state(device, true);
@@ -460,7 +460,7 @@ static int acpi_button_resume(struct device *dev)
 
 	button->suspended = false;
 	mutex_lock(&input->mutex);
-	if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
+	if (button->type == ACPI_BUTTON_TYPE_LID && input_device_enabled(input)) {
 		button->last_state = !!acpi_lid_evaluate_state(device);
 		button->last_time = ktime_get();
 		acpi_lid_initialize_state(device);
-- 
2.17.1


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

* [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled()
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (3 preceding siblings ...)
  2020-06-08 11:22         ` [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-06-10  1:28           ` Michał Mirosław
  2020-06-08 11:22         ` [PATCH v4 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
                           ` (3 subsequent siblings)
  8 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

A new helper is available, so use it. Inspecting 'users' member of
input_dev requires taking device's mutex.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/iio/adc/exynos_adc.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 22131a677445..9a1ddda8c5db 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -633,7 +633,9 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 	bool pressed;
 	int ret;
 
-	while (info->input->users) {
+	mutex_lock(&info->input->mutex);
+	while (input_device_enabled(info->input)) {
+		mutex_unlock(&info->input->mutex);
 		ret = exynos_read_s3c64xx_ts(dev, &x, &y);
 		if (ret == -ETIMEDOUT)
 			break;
@@ -651,6 +653,8 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 		input_sync(info->input);
 
 		usleep_range(1000, 1100);
+
+		mutex_lock(&info->input->mutex);
 	}
 
 	writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
-- 
2.17.1


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

* [PATCH v4 6/7] platform/x86: thinkpad_acpi: Use input_device_enabled()
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (4 preceding siblings ...)
  2020-06-08 11:22         ` [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-06-08 11:22         ` [PATCH v4 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
                           ` (2 subsequent siblings)
  8 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel

Use the new helper. Inspecting input device's 'users' member needs to be
done under device's mutex, so add appropriate invocations.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
 drivers/platform/x86/thinkpad_acpi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 0f704484ae1d..8ae11b8c3ebb 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -2671,9 +2671,10 @@ static void hotkey_poll_setup(const bool may_warn)
 	const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
 	const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
 
+	mutex_lock(&tpacpi_inputdev->mutex);
 	if (hotkey_poll_freq > 0 &&
 	    (poll_driver_mask ||
-	     (poll_user_mask && tpacpi_inputdev->users > 0))) {
+	     (poll_user_mask && input_device_enabled(tpacpi_inputdev)))) {
 		if (!tpacpi_hotkey_task) {
 			tpacpi_hotkey_task = kthread_run(hotkey_kthread,
 					NULL, TPACPI_NVRAM_KTHREAD_NAME);
@@ -2690,6 +2691,7 @@ static void hotkey_poll_setup(const bool may_warn)
 				  poll_user_mask, poll_driver_mask);
 		}
 	}
+	mutex_unlock(&tpacpi_inputdev->mutex);
 }
 
 static void hotkey_poll_setup_safe(const bool may_warn)
-- 
2.17.1


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

* [PATCH v4 7/7] Input: Add "inhibited" property
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (5 preceding siblings ...)
  2020-06-08 11:22         ` [PATCH v4 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
@ 2020-06-08 11:22         ` Andrzej Pietrasiewicz
  2020-10-05 18:10           ` Dmitry Torokhov
  2020-06-10  9:49         ` [PATCH v4 0/7] Support inhibiting input devices Hans de Goede
  2020-06-12  8:17         ` Hans de Goede
  8 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-08 11:22 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Andrzej Pietrasiewicz, kernel, Patrik Fimml

From: Patrik Fimml <patrikf@chromium.org>

Userspace might want to implement a policy to temporarily disregard input
from certain devices, including not treating them as wakeup sources.

An example use case is a laptop, whose keyboard can be folded under the
screen to create tablet-like experience. The user then must hold the laptop
in such a way that it is difficult to avoid pressing the keyboard keys. It
is therefore desirable to temporarily disregard input from the keyboard,
until it is folded back. This obviously is a policy which should be kept
out of the kernel, but the kernel must provide suitable means to implement
such a policy.

This patch adds a sysfs interface for exactly this purpose.

To implement the said interface it adds an "inhibited" property to struct
input_dev, and effectively creates four states a device can be in: closed
uninhibited, closed inhibited, open uninhibited, open inhibited. It also
defers calling driver's ->open() and ->close() to until they are actually
needed, e.g. it makes no sense to prepare the underlying device for
generating events (->open()) if the device is inhibited.

              uninhibit
closed      <------------ closed
uninhibited ------------> inhibited
      | ^     inhibit        | ^
 1st  | |               1st  | |
 open | |               open | |
      | |                    | |
      | | last               | | last
      | | close              | | close
      v |     uninhibit      v |
open        <------------ open
uninhibited ------------> inhibited

The top inhibit/uninhibit transition happens when users == 0.
The bottom inhibit/uninhibit transition happens when users > 0.
The left open/close transition happens when !inhibited.
The right open/close transition happens when inhibited.
Due to all transitions being serialized with dev->mutex, it is impossible
to have "diagonal" transitions between closed uninhibited and open
inhibited or between open uninhibited and closed inhibited.

No new callbacks are added to drivers, because their open() and close()
serve exactly the purpose to tell the driver to start/stop providing
events to the input core. Consequently, open() and close() - if provided
- are called in both inhibit and uninhibit paths.

Signed-off-by: Patrik Fimml <patrikf@chromium.org>
Co-developed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/input/input.c | 119 ++++++++++++++++++++++++++++++++++++++----
 include/linux/input.h |  12 ++++-
 2 files changed, 120 insertions(+), 11 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 41377bfa142d..f624b09a1f00 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
 	case EV_KEY:
 		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
 
-			/* auto-repeat bypasses state updates */
-			if (value == 2) {
+			/*
+			 * auto-repeat bypasses state updates but repeat
+			 * events are ignored if the key is not pressed
+			 */
+			if (value == 2 && test_bit(code, dev->key)) {
 				disposition = INPUT_PASS_TO_HANDLERS;
 				break;
 			}
@@ -367,8 +370,13 @@ static int input_get_disposition(struct input_dev *dev,
 static void input_handle_event(struct input_dev *dev,
 			       unsigned int type, unsigned int code, int value)
 {
-	int disposition = input_get_disposition(dev, type, code, &value);
+	int disposition;
+
+	/* filter-out events from inhibited devices */
+	if (dev->inhibited)
+		return;
 
+	disposition = input_get_disposition(dev, type, code, &value);
 	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
 		add_input_randomness(type, code, value);
 
@@ -612,10 +620,10 @@ int input_open_device(struct input_handle *handle)
 
 	handle->open++;
 
-	if (dev->users++) {
+	if (dev->users++ || dev->inhibited) {
 		/*
-		 * Device is already opened, so we can exit immediately and
-		 * report success.
+		 * Device is already opened and/or inhibited,
+		 * so we can exit immediately and report success.
 		 */
 		goto out;
 	}
@@ -675,10 +683,9 @@ void input_close_device(struct input_handle *handle)
 
 	__input_release_device(handle);
 
-	if (!--dev->users) {
+	if (!dev->inhibited && !--dev->users) {
 		if (dev->poller)
 			input_dev_poller_stop(dev->poller);
-
 		if (dev->close)
 			dev->close(dev);
 	}
@@ -1416,12 +1423,49 @@ static ssize_t input_dev_show_properties(struct device *dev,
 }
 static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
 
+static int input_inhibit_device(struct input_dev *dev);
+static int input_uninhibit_device(struct input_dev *dev);
+
+static ssize_t inhibited_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct input_dev *input_dev = to_input_dev(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", input_dev->inhibited);
+}
+
+static ssize_t inhibited_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t len)
+{
+	struct input_dev *input_dev = to_input_dev(dev);
+	ssize_t rv;
+	bool inhibited;
+
+	if (strtobool(buf, &inhibited))
+		return -EINVAL;
+
+	if (inhibited)
+		rv = input_inhibit_device(input_dev);
+	else
+		rv = input_uninhibit_device(input_dev);
+
+	if (rv != 0)
+		return rv;
+
+	return len;
+}
+
+static DEVICE_ATTR_RW(inhibited);
+
 static struct attribute *input_dev_attrs[] = {
 	&dev_attr_name.attr,
 	&dev_attr_phys.attr,
 	&dev_attr_uniq.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_properties.attr,
+	&dev_attr_inhibited.attr,
 	NULL
 };
 
@@ -1703,6 +1747,63 @@ void input_reset_device(struct input_dev *dev)
 }
 EXPORT_SYMBOL(input_reset_device);
 
+static int input_inhibit_device(struct input_dev *dev)
+{
+	int ret = 0;
+
+	mutex_lock(&dev->mutex);
+
+	if (dev->inhibited)
+		goto out;
+
+	if (dev->users) {
+		if (dev->close)
+			dev->close(dev);
+		if (dev->poller)
+			input_dev_poller_stop(dev->poller);
+	}
+
+	spin_lock_irq(&dev->event_lock);
+	input_dev_release_keys(dev);
+	input_dev_toggle(dev, false);
+	spin_unlock_irq(&dev->event_lock);
+
+	dev->inhibited = true;
+
+out:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
+static int input_uninhibit_device(struct input_dev *dev)
+{
+	int ret = 0;
+
+	mutex_lock(&dev->mutex);
+
+	if (!dev->inhibited)
+		goto out;
+
+	if (dev->users) {
+		if (dev->open) {
+			ret = dev->open(dev);
+			if (ret)
+				goto out;
+		}
+		if (dev->poller)
+			input_dev_poller_start(dev->poller);
+	}
+
+	dev->inhibited = false;
+	spin_lock_irq(&dev->event_lock);
+	input_dev_toggle(dev, true);
+	spin_unlock_irq(&dev->event_lock);
+
+out:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int input_dev_suspend(struct device *dev)
 {
@@ -2131,7 +2232,7 @@ bool input_device_enabled(struct input_dev *dev)
 {
 	lockdep_assert_held(&dev->mutex);
 
-	return dev->users > 0;
+	return !dev->inhibited && dev->users > 0;
 }
 EXPORT_SYMBOL_GPL(input_device_enabled);
 
diff --git a/include/linux/input.h b/include/linux/input.h
index eda4587dba67..0354b298d874 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -90,9 +90,11 @@ enum input_clock_type {
  * @open: this method is called when the very first user calls
  *	input_open_device(). The driver must prepare the device
  *	to start generating events (start polling thread,
- *	request an IRQ, submit URB, etc.)
+ *	request an IRQ, submit URB, etc.). The meaning of open() is
+ *	to start providing events to the input core.
  * @close: this method is called when the very last user calls
- *	input_close_device().
+ *	input_close_device(). The meaning of close() is to stop
+ *	providing events to the input core.
  * @flush: purges the device. Most commonly used to get rid of force
  *	feedback effects loaded into the device when disconnecting
  *	from it
@@ -127,6 +129,10 @@ enum input_clock_type {
  *	and needs not be explicitly unregistered or freed.
  * @timestamp: storage for a timestamp set by input_set_timestamp called
  *  by a driver
+ * @inhibited: indicates that the input device is inhibited. If that is
+ * the case then input core ignores any events generated by the device.
+ * Device's close() is called when it is being inhibited and its open()
+ * is called when it is being uninhibited.
  */
 struct input_dev {
 	const char *name;
@@ -201,6 +207,8 @@ struct input_dev {
 	bool devres_managed;
 
 	ktime_t timestamp[INPUT_CLK_MAX];
+
+	bool inhibited;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
-- 
2.17.1


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

* Re: [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled()
  2020-06-08 11:22         ` [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-06-10  1:28           ` Michał Mirosław
  2020-06-10  7:52             ` [FIXED PATCH " Andrzej Pietrasiewicz
  0 siblings, 1 reply; 64+ messages in thread
From: Michał Mirosław @ 2020-06-10  1:28 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Mon, Jun 08, 2020 at 01:22:09PM +0200, Andrzej Pietrasiewicz wrote:
> A new helper is available, so use it. Inspecting 'users' member of
> input_dev requires taking device's mutex.
[...]
> --- a/drivers/iio/adc/exynos_adc.c
> +++ b/drivers/iio/adc/exynos_adc.c
> @@ -633,7 +633,9 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
>  	bool pressed;
>  	int ret;
>  
> -	while (info->input->users) {
> +	mutex_lock(&info->input->mutex);
> +	while (input_device_enabled(info->input)) {
> +		mutex_unlock(&info->input->mutex);
>  		ret = exynos_read_s3c64xx_ts(dev, &x, &y);
>  		if (ret == -ETIMEDOUT)
>  			break;
> @@ -651,6 +653,8 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
>  		input_sync(info->input);
>  
>  		usleep_range(1000, 1100);
> +
> +		mutex_lock(&info->input->mutex);
>  	}

Missed an mutex_unlock() here.

>  
>  	writel(0, ADC_V1_CLRINTPNDNUP(info->regs));

Best Regards,
Michał Mirosław

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

* [FIXED PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled()
  2020-06-10  1:28           ` Michał Mirosław
@ 2020-06-10  7:52             ` Andrzej Pietrasiewicz
  0 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-10  7:52 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Andrzej Pietrasiewicz,
	Michał Mirosław, kernel

A new helper is available, so use it. Inspecting 'users' member of
input_dev requires taking device's mutex.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 drivers/iio/adc/exynos_adc.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 22131a677445..2761c3aea2c6 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -633,7 +633,9 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 	bool pressed;
 	int ret;
 
-	while (info->input->users) {
+	mutex_lock(&info->input->mutex);
+	while (input_device_enabled(info->input)) {
+		mutex_unlock(&info->input->mutex);
 		ret = exynos_read_s3c64xx_ts(dev, &x, &y);
 		if (ret == -ETIMEDOUT)
 			break;
@@ -651,7 +653,10 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
 		input_sync(info->input);
 
 		usleep_range(1000, 1100);
+
+		mutex_lock(&info->input->mutex);
 	}
+	mutex_unlock(&info->input->mutex);
 
 	writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
 
-- 
2.17.1


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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (6 preceding siblings ...)
  2020-06-08 11:22         ` [PATCH v4 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
@ 2020-06-10  9:49         ` Hans de Goede
  2020-06-10 10:38           ` Rafael J. Wysocki
  2020-06-12  8:17         ` Hans de Goede
  8 siblings, 1 reply; 64+ messages in thread
From: Hans de Goede @ 2020-06-10  9:49 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, kernel

Hi All,

On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
> This is a quick respin of v3, with just two small changes, please see
> the changelog below.
> 
> Userspace might want to implement a policy to temporarily disregard input
> from certain devices.
> 
> An example use case is a convertible laptop, whose keyboard can be folded
> under the screen to create tablet-like experience. The user then must hold
> the laptop in such a way that it is difficult to avoid pressing the keyboard
> keys. It is therefore desirable to temporarily disregard input from the
> keyboard, until it is folded back. This obviously is a policy which should
> be kept out of the kernel, but the kernel must provide suitable means to
> implement such a policy.

First of all sorry to start a somewhat new discussion about this
while this patch set is also somewhat far along in the review process,
but I believe what I discuss below needs to be taken into account.

Yesterday I have been looking into why an Asus T101HA would not stay
suspended when the LID is closed. The cause is that the USB HID multi-touch
touchpad in the base of the device starts sending events when the screen
gets close to the touchpad (so when the LID is fully closed) and these
events are causing a wakeup from suspend. HID multi-touch devices
do have a way to tell them to fully stop sending events, also disabling
the USB remote wakeup the device is doing. The question is when to tell
it to not send events though ...

So now I've been thinking about how to fix this and I believe that there
is some interaction between this problem and this patch-set.

The problem I'm seeing on the T101HA is about wakeups, so the question
which I want to discuss is:

1. How does inhibiting interact with enabling /
disabling the device as a wakeup source ?

2. Since we have now made inhibiting equal open/close how does open/close
interact with a device being a wakeup source ?

And my own initial (to be discussed) answers to these questions:

1. It seems to me that when a device is inhibited it should not be a
wakeup source, so where possible a input-device-driver should disable
a device's wakeup capabilities on suspend if inhibited

2. This one is trickier I don't think we have really clearly specified
any behavior here. The default behavior of most drivers seems to be
using something like this in their suspend callback:

         if (device_may_wakeup(dev))
                 enable_irq_wake(data->irq);
         else if (input->users)
                 foo_stop_receiving_events(data);

Since this is what most drivers seem to do I believe we should keep
this as is and that we should just clearly document that if the
input_device has users (has been opened) or not does not matter
for its wakeup behavior.

Combining these 2 answers leads to this new pseudo code template
for an input-device's suspend method:

	/*
	 * If inhibited we have already disabled events and
	 * we do NOT want to setup the device as wake source.
	 */
	if (input->inhibited)
		return 0;

         if (device_may_wakeup(dev))
                 enable_irq_wake(data->irq);
         else if (input->users)
                 foo_stop_receiving_events(data);

###

A different, but related issue is how to make devices actually use the
new inhibit support on the builtin keyboard + touchpad when say the lid
is closed.   Arguably this is an userspace problem, but it is a tricky
one. Currently on most modern Linux distributions suspend-on-lid-close
is handled by systemd-logind and most modern desktop-environments are
happy to have logind handle this for them.

But most knowledge about input devices and e.g. heurisitics to decide
if a touchpad is internal or external are part of libinput. Now we could
have libinput use the new inhibit support (1), but then when the lid
closes we get race between whatever process is using libinput trying
to inhibit the touchpad (which must be done before to suspend to disable
it as wakeup source) and logind trying to suspend the system.

One solution here would be to move the setting of the inhibit sysfs
attr into logind, but that requires adding a whole bunch of extra
knowledge to logind which does not really belong there IMHO.

I've been thinking a bit about this and to me it seems that the kernel
is in the ideal position to automatically inhibit some devices when
some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
issue here is to chose on which devices to enable this. I believe
that the auto inhibit on some switches mechanism is best done inside
the kernel (disabled by default) and then we can have a sysfs
attr called auto_inhibit_ev_sw_mask which can be set to e.g.
(1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
inhibit both when the lid is closed or when switched to tablet mode.

This could then be combined with a userspace utility run from an
udev rule which makes the actual decision what auto_inhibit_ev_sw_mask
should be set for a given input device.

This will put the mechanism for what we want inside the kernel and
leaves the policy on which switches we want this for out of the
kernel.

Note adding this new auto_inhibit_ev_sw_mask sysfs attr falls
somewhat outside the context of this patchset and could be done
as a follow up to this patch-set. But I do believe that we need to
figure out how (non ChromeOS) userspace can / will use the new inhibit
interface before merging it.

Regards,

Hans




1) There are issues here with libinput not running as root and this
being a root only sysfs interface but lets ignore those for now,
note that the auto_inhibit_ev_sw_mask also neatly solves this
problem



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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10  9:49         ` [PATCH v4 0/7] Support inhibiting input devices Hans de Goede
@ 2020-06-10 10:38           ` Rafael J. Wysocki
  2020-06-10 13:12             ` Andrzej Pietrasiewicz
                               ` (2 more replies)
  0 siblings, 3 replies; 64+ messages in thread
From: Rafael J. Wysocki @ 2020-06-10 10:38 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andrzej Pietrasiewicz, Linux PM, ACPI Devel Maling List,
	Linux Kernel Mailing List, linux-iio, Linux ARM,
	Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi All,
>
> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
> > This is a quick respin of v3, with just two small changes, please see
> > the changelog below.
> >
> > Userspace might want to implement a policy to temporarily disregard input
> > from certain devices.
> >
> > An example use case is a convertible laptop, whose keyboard can be folded
> > under the screen to create tablet-like experience. The user then must hold
> > the laptop in such a way that it is difficult to avoid pressing the keyboard
> > keys. It is therefore desirable to temporarily disregard input from the
> > keyboard, until it is folded back. This obviously is a policy which should
> > be kept out of the kernel, but the kernel must provide suitable means to
> > implement such a policy.
>
> First of all sorry to start a somewhat new discussion about this
> while this patch set is also somewhat far along in the review process,
> but I believe what I discuss below needs to be taken into account.
>
> Yesterday I have been looking into why an Asus T101HA would not stay
> suspended when the LID is closed. The cause is that the USB HID multi-touch
> touchpad in the base of the device starts sending events when the screen
> gets close to the touchpad (so when the LID is fully closed) and these
> events are causing a wakeup from suspend. HID multi-touch devices
> do have a way to tell them to fully stop sending events, also disabling
> the USB remote wakeup the device is doing. The question is when to tell
> it to not send events though ...
>
> So now I've been thinking about how to fix this and I believe that there
> is some interaction between this problem and this patch-set.
>
> The problem I'm seeing on the T101HA is about wakeups, so the question
> which I want to discuss is:
>
> 1. How does inhibiting interact with enabling /
> disabling the device as a wakeup source ?
>
> 2. Since we have now made inhibiting equal open/close how does open/close
> interact with a device being a wakeup source ?
>
> And my own initial (to be discussed) answers to these questions:
>
> 1. It seems to me that when a device is inhibited it should not be a
> wakeup source, so where possible a input-device-driver should disable
> a device's wakeup capabilities on suspend if inhibited

If "inhibit" means "do not generate any events going forward", then
this must also cover wakeup events, so I agree.

> 2. This one is trickier I don't think we have really clearly specified
> any behavior here. The default behavior of most drivers seems to be
> using something like this in their suspend callback:
>
>          if (device_may_wakeup(dev))
>                  enable_irq_wake(data->irq);
>          else if (input->users)
>                  foo_stop_receiving_events(data);
>
> Since this is what most drivers seem to do I believe we should keep
> this as is and that we should just clearly document that if the
> input_device has users (has been opened) or not does not matter
> for its wakeup behavior.
>
> Combining these 2 answers leads to this new pseudo code template
> for an input-device's suspend method:
>
>         /*
>          * If inhibited we have already disabled events and
>          * we do NOT want to setup the device as wake source.
>          */
>         if (input->inhibited)
>                 return 0;
>
>          if (device_may_wakeup(dev))
>                  enable_irq_wake(data->irq);
>          else if (input->users)
>                  foo_stop_receiving_events(data);
>
> ###

Sounds reasonable to me.

> A different, but related issue is how to make devices actually use the
> new inhibit support on the builtin keyboard + touchpad when say the lid
> is closed.   Arguably this is an userspace problem, but it is a tricky
> one. Currently on most modern Linux distributions suspend-on-lid-close
> is handled by systemd-logind and most modern desktop-environments are
> happy to have logind handle this for them.
>
> But most knowledge about input devices and e.g. heurisitics to decide
> if a touchpad is internal or external are part of libinput. Now we could
> have libinput use the new inhibit support (1), but then when the lid
> closes we get race between whatever process is using libinput trying
> to inhibit the touchpad (which must be done before to suspend to disable
> it as wakeup source) and logind trying to suspend the system.
>
> One solution here would be to move the setting of the inhibit sysfs
> attr into logind, but that requires adding a whole bunch of extra
> knowledge to logind which does not really belong there IMHO.
>
> I've been thinking a bit about this and to me it seems that the kernel
> is in the ideal position to automatically inhibit some devices when
> some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
> issue here is to chose on which devices to enable this. I believe
> that the auto inhibit on some switches mechanism is best done inside
> the kernel (disabled by default) and then we can have a sysfs
> attr called auto_inhibit_ev_sw_mask which can be set to e.g.
> (1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
> the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
> inhibit both when the lid is closed or when switched to tablet mode.

I agree that the kernel is the right place to handle this, but it
requires some extra knowledge about dependencies between devices.

It'd be kind of like power resources in ACPI, so for each state of a
"master" device (in principle, there may be more states of it than
just two) there would be a list of "dependent" intput devices that
need to be inhibited when the "master" device goes into that state.

> This could then be combined with a userspace utility run from an
> udev rule which makes the actual decision what auto_inhibit_ev_sw_mask
> should be set for a given input device.
>
> This will put the mechanism for what we want inside the kernel and
> leaves the policy on which switches we want this for out of the
> kernel.
>
> Note adding this new auto_inhibit_ev_sw_mask sysfs attr falls
> somewhat outside the context of this patchset and could be done
> as a follow up to this patch-set. But I do believe that we need to
> figure out how (non ChromeOS) userspace can / will use the new inhibit
> interface before merging it.

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 10:38           ` Rafael J. Wysocki
@ 2020-06-10 13:12             ` Andrzej Pietrasiewicz
  2020-06-10 13:21               ` Hans de Goede
  2020-06-10 13:52             ` Hans de Goede
  2020-06-10 18:28             ` Dmitry Torokhov
  2 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-10 13:12 UTC (permalink / raw)
  To: Rafael J. Wysocki, Hans de Goede
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi All,

W dniu 10.06.2020 o 12:38, Rafael J. Wysocki pisze:
> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi All,
>>
>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>> This is a quick respin of v3, with just two small changes, please see
>>> the changelog below.
>>>
>>> Userspace might want to implement a policy to temporarily disregard input
>>> from certain devices.
>>>
>>> An example use case is a convertible laptop, whose keyboard can be folded
>>> under the screen to create tablet-like experience. The user then must hold
>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>> keys. It is therefore desirable to temporarily disregard input from the
>>> keyboard, until it is folded back. This obviously is a policy which should
>>> be kept out of the kernel, but the kernel must provide suitable means to
>>> implement such a policy.
>>
>> First of all sorry to start a somewhat new discussion about this
>> while this patch set is also somewhat far along in the review process,
>> but I believe what I discuss below needs to be taken into account.
>>
>> Yesterday I have been looking into why an Asus T101HA would not stay
>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>> touchpad in the base of the device starts sending events when the screen
>> gets close to the touchpad (so when the LID is fully closed) and these
>> events are causing a wakeup from suspend. HID multi-touch devices
>> do have a way to tell them to fully stop sending events, also disabling
>> the USB remote wakeup the device is doing. The question is when to tell
>> it to not send events though ...
>>
>> So now I've been thinking about how to fix this and I believe that there
>> is some interaction between this problem and this patch-set.
>>
>> The problem I'm seeing on the T101HA is about wakeups, so the question
>> which I want to discuss is:
>>
>> 1. How does inhibiting interact with enabling /
>> disabling the device as a wakeup source ?
>>
>> 2. Since we have now made inhibiting equal open/close how does open/close
>> interact with a device being a wakeup source ?
>>
>> And my own initial (to be discussed) answers to these questions:
>>
>> 1. It seems to me that when a device is inhibited it should not be a
>> wakeup source, so where possible a input-device-driver should disable
>> a device's wakeup capabilities on suspend if inhibited
> 
> If "inhibit" means "do not generate any events going forward", then
> this must also cover wakeup events, so I agree.

I agree, too.

> 
>> 2. This one is trickier I don't think we have really clearly specified
>> any behavior here. The default behavior of most drivers seems to be
>> using something like this in their suspend callback:
>>
>>           if (device_may_wakeup(dev))
>>                   enable_irq_wake(data->irq);
>>           else if (input->users)
>>                   foo_stop_receiving_events(data);
>>
>> Since this is what most drivers seem to do I believe we should keep
>> this as is and that we should just clearly document that if the
>> input_device has users (has been opened) or not does not matter
>> for its wakeup behavior.
>>
>> Combining these 2 answers leads to this new pseudo code template
>> for an input-device's suspend method:
>>
>>          /*
>>           * If inhibited we have already disabled events and
>>           * we do NOT want to setup the device as wake source.
>>           */
>>          if (input->inhibited)
>>                  return 0;

Right, if a device is inhibited it shouldn't become a wakeup source,
because that would contradict the purpose of being inhibited.

>>
>>           if (device_may_wakeup(dev))
>>                   enable_irq_wake(data->irq);

What would it mean to become a wakeup source if there are no users,
or nobody has ever opened the device? There are no interested
input handlers (users) so what's the point of becoming a wakeup
source? Why would the system need to wake up?

>>           else if (input->users)
>>                   foo_stop_receiving_events(data);
>>
>> ###
> 
> Sounds reasonable to me.
> 
>> A different, but related issue is how to make devices actually use the
>> new inhibit support on the builtin keyboard + touchpad when say the lid
>> is closed.   Arguably this is an userspace problem, but it is a tricky
>> one. Currently on most modern Linux distributions suspend-on-lid-close
>> is handled by systemd-logind and most modern desktop-environments are
>> happy to have logind handle this for them.
>>
>> But most knowledge about input devices and e.g. heurisitics to decide
>> if a touchpad is internal or external are part of libinput. Now we could
>> have libinput use the new inhibit support (1), but then when the lid
>> closes we get race between whatever process is using libinput trying
>> to inhibit the touchpad (which must be done before to suspend to disable
>> it as wakeup source) and logind trying to suspend the system.
>>
>> One solution here would be to move the setting of the inhibit sysfs
>> attr into logind, but that requires adding a whole bunch of extra
>> knowledge to logind which does not really belong there IMHO.
>>
>> I've been thinking a bit about this and to me it seems that the kernel
>> is in the ideal position to automatically inhibit some devices when
>> some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
>> issue here is to chose on which devices to enable this. I believe
>> that the auto inhibit on some switches mechanism is best done inside
>> the kernel (disabled by default) and then we can have a sysfs
>> attr called auto_inhibit_ev_sw_mask which can be set to e.g.
>> (1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
>> the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
>> inhibit both when the lid is closed or when switched to tablet mode.
> 
> I agree that the kernel is the right place to handle this, but it
> requires some extra knowledge about dependencies between devices.
> 
> It'd be kind of like power resources in ACPI, so for each state of a
> "master" device (in principle, there may be more states of it than
> just two) there would be a list of "dependent" intput devices that
> need to be inhibited when the "master" device goes into that state.
> 
>> This could then be combined with a userspace utility run from an
>> udev rule which makes the actual decision what auto_inhibit_ev_sw_mask
>> should be set for a given input device.
>>
>> This will put the mechanism for what we want inside the kernel and
>> leaves the policy on which switches we want this for out of the
>> kernel.
>>
>> Note adding this new auto_inhibit_ev_sw_mask sysfs attr falls
>> somewhat outside the context of this patchset and could be done
>> as a follow up to this patch-set.

Yes, please ;)

But I do believe that we need to
>> figure out how (non ChromeOS) userspace can / will use the new inhibit
>> interface before merging it.

Of course.

Regards,

Andrzej

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 13:12             ` Andrzej Pietrasiewicz
@ 2020-06-10 13:21               ` Hans de Goede
  2020-06-10 13:41                 ` Andrzej Pietrasiewicz
  2020-06-10 14:01                 ` [PATCH v4 0/7] Support inhibiting input devices Rafael J. Wysocki
  0 siblings, 2 replies; 64+ messages in thread
From: Hans de Goede @ 2020-06-10 13:21 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, Rafael J. Wysocki
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi,

On 6/10/20 3:12 PM, Andrzej Pietrasiewicz wrote:
> Hi All,
> 
> W dniu 10.06.2020 o 12:38, Rafael J. Wysocki pisze:
>> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>> Hi All,
>>>
>>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>>> This is a quick respin of v3, with just two small changes, please see
>>>> the changelog below.
>>>>
>>>> Userspace might want to implement a policy to temporarily disregard input
>>>> from certain devices.
>>>>
>>>> An example use case is a convertible laptop, whose keyboard can be folded
>>>> under the screen to create tablet-like experience. The user then must hold
>>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>>> keys. It is therefore desirable to temporarily disregard input from the
>>>> keyboard, until it is folded back. This obviously is a policy which should
>>>> be kept out of the kernel, but the kernel must provide suitable means to
>>>> implement such a policy.
>>>
>>> First of all sorry to start a somewhat new discussion about this
>>> while this patch set is also somewhat far along in the review process,
>>> but I believe what I discuss below needs to be taken into account.
>>>
>>> Yesterday I have been looking into why an Asus T101HA would not stay
>>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>>> touchpad in the base of the device starts sending events when the screen
>>> gets close to the touchpad (so when the LID is fully closed) and these
>>> events are causing a wakeup from suspend. HID multi-touch devices
>>> do have a way to tell them to fully stop sending events, also disabling
>>> the USB remote wakeup the device is doing. The question is when to tell
>>> it to not send events though ...
>>>
>>> So now I've been thinking about how to fix this and I believe that there
>>> is some interaction between this problem and this patch-set.
>>>
>>> The problem I'm seeing on the T101HA is about wakeups, so the question
>>> which I want to discuss is:
>>>
>>> 1. How does inhibiting interact with enabling /
>>> disabling the device as a wakeup source ?
>>>
>>> 2. Since we have now made inhibiting equal open/close how does open/close
>>> interact with a device being a wakeup source ?
>>>
>>> And my own initial (to be discussed) answers to these questions:
>>>
>>> 1. It seems to me that when a device is inhibited it should not be a
>>> wakeup source, so where possible a input-device-driver should disable
>>> a device's wakeup capabilities on suspend if inhibited
>>
>> If "inhibit" means "do not generate any events going forward", then
>> this must also cover wakeup events, so I agree.
> 
> I agree, too.
> 
>>
>>> 2. This one is trickier I don't think we have really clearly specified
>>> any behavior here. The default behavior of most drivers seems to be
>>> using something like this in their suspend callback:
>>>
>>>           if (device_may_wakeup(dev))
>>>                   enable_irq_wake(data->irq);
>>>           else if (input->users)
>>>                   foo_stop_receiving_events(data);
>>>
>>> Since this is what most drivers seem to do I believe we should keep
>>> this as is and that we should just clearly document that if the
>>> input_device has users (has been opened) or not does not matter
>>> for its wakeup behavior.
>>>
>>> Combining these 2 answers leads to this new pseudo code template
>>> for an input-device's suspend method:
>>>
>>>          /*
>>>           * If inhibited we have already disabled events and
>>>           * we do NOT want to setup the device as wake source.
>>>           */
>>>          if (input->inhibited)
>>>                  return 0;
> 
> Right, if a device is inhibited it shouldn't become a wakeup source,
> because that would contradict the purpose of being inhibited.

Ack. Note I do think that we need to document this (and more
in general the answer to both questions from above) clearly so
that going forward if there are any questions about how this is
supposed to work we can just point to the docs.

Can you do a follow-up patch, or include a patch in your next
version which documents this (once we agree on what "this"
exactly is) ?

>>>
>>>           if (device_may_wakeup(dev))
>>>                   enable_irq_wake(data->irq);
> 
> What would it mean to become a wakeup source if there are no users,
> or nobody has ever opened the device? There are no interested
> input handlers (users) so what's the point of becoming a wakeup
> source? Why would the system need to wake up?

Well this is what we have been doing so far, so arguably we
need to keep doing it to avoid regressions / breaking our ABI.

Lets for example take a laptop, where when suspended the
power-button is the only valid wakeup-source and this is
running good old slackware with fvwm2 or windowmaker as
"desktop environment", then likely no process will have
the power-button input evdev node open.  Still we should
wakeup the laptop on the power-button press, otherwise
it will never wakeup.

Note I agree with you that the way this works is not
ideal, I just do not think that we can change it.

>>>           else if (input->users)
>>>                   foo_stop_receiving_events(data);
>>>
>>> ###

<snip>

Regards,

Hans


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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 13:21               ` Hans de Goede
@ 2020-06-10 13:41                 ` Andrzej Pietrasiewicz
  2020-06-12  8:30                   ` Hans de Goede
  2020-06-10 14:01                 ` [PATCH v4 0/7] Support inhibiting input devices Rafael J. Wysocki
  1 sibling, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-10 13:41 UTC (permalink / raw)
  To: Hans de Goede, Rafael J. Wysocki
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi Hans,

W dniu 10.06.2020 o 15:21, Hans de Goede pisze:
> Hi,
> 
> On 6/10/20 3:12 PM, Andrzej Pietrasiewicz wrote:
>> Hi All,
>>
>> W dniu 10.06.2020 o 12:38, Rafael J. Wysocki pisze:
>>> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>
>>>> Hi All,
>>>>
>>>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>>>> This is a quick respin of v3, with just two small changes, please see
>>>>> the changelog below.
>>>>>
>>>>> Userspace might want to implement a policy to temporarily disregard input
>>>>> from certain devices.
>>>>>
>>>>> An example use case is a convertible laptop, whose keyboard can be folded
>>>>> under the screen to create tablet-like experience. The user then must hold
>>>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>>>> keys. It is therefore desirable to temporarily disregard input from the
>>>>> keyboard, until it is folded back. This obviously is a policy which should
>>>>> be kept out of the kernel, but the kernel must provide suitable means to
>>>>> implement such a policy.
>>>>
>>>> First of all sorry to start a somewhat new discussion about this
>>>> while this patch set is also somewhat far along in the review process,
>>>> but I believe what I discuss below needs to be taken into account.
>>>>
>>>> Yesterday I have been looking into why an Asus T101HA would not stay
>>>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>>>> touchpad in the base of the device starts sending events when the screen
>>>> gets close to the touchpad (so when the LID is fully closed) and these
>>>> events are causing a wakeup from suspend. HID multi-touch devices
>>>> do have a way to tell them to fully stop sending events, also disabling
>>>> the USB remote wakeup the device is doing. The question is when to tell
>>>> it to not send events though ...
>>>>
>>>> So now I've been thinking about how to fix this and I believe that there
>>>> is some interaction between this problem and this patch-set.
>>>>
>>>> The problem I'm seeing on the T101HA is about wakeups, so the question
>>>> which I want to discuss is:
>>>>
>>>> 1. How does inhibiting interact with enabling /
>>>> disabling the device as a wakeup source ?
>>>>
>>>> 2. Since we have now made inhibiting equal open/close how does open/close
>>>> interact with a device being a wakeup source ?
>>>>
>>>> And my own initial (to be discussed) answers to these questions:
>>>>
>>>> 1. It seems to me that when a device is inhibited it should not be a
>>>> wakeup source, so where possible a input-device-driver should disable
>>>> a device's wakeup capabilities on suspend if inhibited
>>>
>>> If "inhibit" means "do not generate any events going forward", then
>>> this must also cover wakeup events, so I agree.
>>
>> I agree, too.
>>
>>>
>>>> 2. This one is trickier I don't think we have really clearly specified
>>>> any behavior here. The default behavior of most drivers seems to be
>>>> using something like this in their suspend callback:
>>>>
>>>>           if (device_may_wakeup(dev))
>>>>                   enable_irq_wake(data->irq);
>>>>           else if (input->users)
>>>>                   foo_stop_receiving_events(data);
>>>>
>>>> Since this is what most drivers seem to do I believe we should keep
>>>> this as is and that we should just clearly document that if the
>>>> input_device has users (has been opened) or not does not matter
>>>> for its wakeup behavior.
>>>>
>>>> Combining these 2 answers leads to this new pseudo code template
>>>> for an input-device's suspend method:
>>>>
>>>>          /*
>>>>           * If inhibited we have already disabled events and
>>>>           * we do NOT want to setup the device as wake source.
>>>>           */
>>>>          if (input->inhibited)
>>>>                  return 0;
>>
>> Right, if a device is inhibited it shouldn't become a wakeup source,
>> because that would contradict the purpose of being inhibited.
> 
> Ack. Note I do think that we need to document this (and more
> in general the answer to both questions from above) clearly so
> that going forward if there are any questions about how this is
> supposed to work we can just point to the docs.
> 
> Can you do a follow-up patch, or include a patch in your next
> version which documents this (once we agree on what "this"
> exactly is) ?

Sure I can. Just need to know when "this" becomes stable enough ;)
If this series otherwise looks mature enough I would opt for a
follow-up patch.

> 
>>>>
>>>>           if (device_may_wakeup(dev))
>>>>                   enable_irq_wake(data->irq);
>>
>> What would it mean to become a wakeup source if there are no users,
>> or nobody has ever opened the device? There are no interested
>> input handlers (users) so what's the point of becoming a wakeup
>> source? Why would the system need to wake up?
> 
> Well this is what we have been doing so far, so arguably we
> need to keep doing it to avoid regressions / breaking our ABI.
> 
> Lets for example take a laptop, where when suspended the
> power-button is the only valid wakeup-source and this is
> running good old slackware with fvwm2 or windowmaker as
> "desktop environment", then likely no process will have
> the power-button input evdev node open.  Still we should
> wakeup the laptop on the power-button press, otherwise
> it will never wakeup.
> 

True, thanks for explaining.

> Note I agree with you that the way this works is not
> ideal, I just do not think that we can change it.
> 

Regards,

Andrzej

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 10:38           ` Rafael J. Wysocki
  2020-06-10 13:12             ` Andrzej Pietrasiewicz
@ 2020-06-10 13:52             ` Hans de Goede
  2020-06-10 18:28             ` Dmitry Torokhov
  2 siblings, 0 replies; 64+ messages in thread
From: Hans de Goede @ 2020-06-10 13:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Andrzej Pietrasiewicz, Linux PM, ACPI Devel Maling List,
	Linux Kernel Mailing List, linux-iio, Linux ARM,
	Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi,

On 6/10/20 12:38 PM, Rafael J. Wysocki wrote:
> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:

<snip>

>> A different, but related issue is how to make devices actually use the
>> new inhibit support on the builtin keyboard + touchpad when say the lid
>> is closed.   Arguably this is an userspace problem, but it is a tricky
>> one. Currently on most modern Linux distributions suspend-on-lid-close
>> is handled by systemd-logind and most modern desktop-environments are
>> happy to have logind handle this for them.
>>
>> But most knowledge about input devices and e.g. heurisitics to decide
>> if a touchpad is internal or external are part of libinput. Now we could
>> have libinput use the new inhibit support (1), but then when the lid
>> closes we get race between whatever process is using libinput trying
>> to inhibit the touchpad (which must be done before to suspend to disable
>> it as wakeup source) and logind trying to suspend the system.
>>
>> One solution here would be to move the setting of the inhibit sysfs
>> attr into logind, but that requires adding a whole bunch of extra
>> knowledge to logind which does not really belong there IMHO.
>>
>> I've been thinking a bit about this and to me it seems that the kernel
>> is in the ideal position to automatically inhibit some devices when
>> some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
>> issue here is to chose on which devices to enable this. I believe
>> that the auto inhibit on some switches mechanism is best done inside
>> the kernel (disabled by default) and then we can have a sysfs
>> attr called auto_inhibit_ev_sw_mask which can be set to e.g.
>> (1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
>> the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
>> inhibit both when the lid is closed or when switched to tablet mode.
> 
> I agree that the kernel is the right place to handle this, but it
> requires some extra knowledge about dependencies between devices.
>
> It'd be kind of like power resources in ACPI, so for each state of a
> "master" device (in principle, there may be more states of it than
> just two) there would be a list of "dependent" intput devices that
> need to be inhibited when the "master" device goes into that state.

So a big part of the reason to punt the decision on which input
devices to enable this auto-inhibit is that we don't really have
information about those relationsships / device-links you are
suggesting here.  libinput is already doing inhibiting inside
userspace for e.g. the tablet-mode switch but it relies on heuristics
+ quirk tables to decide which keyboards should be inhibited and which
not.

E.g. for a 360 degree hinges 2-in-1 we want to disable the builtin
keyboard, when folded into in tablet mode, but not any external ones.

Mostly the builtin kbd will be PS2 but I have one such 2-in-1 here
in my home office with a USB kbd ...

In general of the master devices there will be only 1, there will be
only 1 lid switch and only 1 tablet-mode switch. So my idea with the
auto_inhibit_ev_sw_mask, is for it to be a per input-device setting.

So using your terms, all input devices with the (1 << SW_LID) bit
set in their auto_inhibit_ev_sw_mask will be dependents of the
(master) device which actually is reporting the SW_LID bit.

The idea here is for this to work the same as how the rfkill code
from net/rfkill/input.c works, except instead of binding e.g.
KEY_WLAN to toggling the sw-state of rfkill devices with a type
of RFKILL_TYPE_WLAN. This will bind SW_LID to inhibiting input
devices with the SW_LID bit set in their auto_inhibit_ev_sw_mask.

Regards,

Hans


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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 13:21               ` Hans de Goede
  2020-06-10 13:41                 ` Andrzej Pietrasiewicz
@ 2020-06-10 14:01                 ` Rafael J. Wysocki
  1 sibling, 0 replies; 64+ messages in thread
From: Rafael J. Wysocki @ 2020-06-10 14:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andrzej Pietrasiewicz, Rafael J. Wysocki, Linux PM,
	ACPI Devel Maling List, Linux Kernel Mailing List, linux-iio,
	Linux ARM, Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

On Wed, Jun 10, 2020 at 3:21 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 6/10/20 3:12 PM, Andrzej Pietrasiewicz wrote:
> > Hi All,
> >

[cut]

> > What would it mean to become a wakeup source if there are no users,
> > or nobody has ever opened the device? There are no interested
> > input handlers (users) so what's the point of becoming a wakeup
> > source? Why would the system need to wake up?
>
> Well this is what we have been doing so far, so arguably we
> need to keep doing it to avoid regressions / breaking our ABI.
>
> Lets for example take a laptop, where when suspended the
> power-button is the only valid wakeup-source and this is
> running good old slackware with fvwm2 or windowmaker as
> "desktop environment", then likely no process will have
> the power-button input evdev node open.  Still we should
> wakeup the laptop on the power-button press, otherwise
> it will never wakeup.
>
> Note I agree with you that the way this works is not
> ideal, I just do not think that we can change it.

Please note that "no users" merely means that user space is not
interested in receiving and processing the events from that device.

If it is configured for system wakeup, it doesn't matter whether or
not user space will consume the related events.

Thanks!

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 10:38           ` Rafael J. Wysocki
  2020-06-10 13:12             ` Andrzej Pietrasiewicz
  2020-06-10 13:52             ` Hans de Goede
@ 2020-06-10 18:28             ` Dmitry Torokhov
  2020-06-12  8:14               ` Hans de Goede
  2 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-06-10 18:28 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Hans de Goede, Andrzej Pietrasiewicz, Linux PM,
	ACPI Devel Maling List, Linux Kernel Mailing List, linux-iio,
	Linux ARM, Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, Collabora Kernel ML

On Wed, Jun 10, 2020 at 12:38:30PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >
> > Hi All,
> >
> > On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
> > > This is a quick respin of v3, with just two small changes, please see
> > > the changelog below.
> > >
> > > Userspace might want to implement a policy to temporarily disregard input
> > > from certain devices.
> > >
> > > An example use case is a convertible laptop, whose keyboard can be folded
> > > under the screen to create tablet-like experience. The user then must hold
> > > the laptop in such a way that it is difficult to avoid pressing the keyboard
> > > keys. It is therefore desirable to temporarily disregard input from the
> > > keyboard, until it is folded back. This obviously is a policy which should
> > > be kept out of the kernel, but the kernel must provide suitable means to
> > > implement such a policy.
> >
> > First of all sorry to start a somewhat new discussion about this
> > while this patch set is also somewhat far along in the review process,
> > but I believe what I discuss below needs to be taken into account.
> >
> > Yesterday I have been looking into why an Asus T101HA would not stay
> > suspended when the LID is closed. The cause is that the USB HID multi-touch
> > touchpad in the base of the device starts sending events when the screen
> > gets close to the touchpad (so when the LID is fully closed) and these
> > events are causing a wakeup from suspend. HID multi-touch devices
> > do have a way to tell them to fully stop sending events, also disabling
> > the USB remote wakeup the device is doing. The question is when to tell
> > it to not send events though ...
> >
> > So now I've been thinking about how to fix this and I believe that there
> > is some interaction between this problem and this patch-set.
> >
> > The problem I'm seeing on the T101HA is about wakeups, so the question
> > which I want to discuss is:
> >
> > 1. How does inhibiting interact with enabling /
> > disabling the device as a wakeup source ?

One should not affect the other.

> >
> > 2. Since we have now made inhibiting equal open/close how does open/close
> > interact with a device being a wakeup source ?

One did not affect another, and it should not.

> >
> > And my own initial (to be discussed) answers to these questions:
> >
> > 1. It seems to me that when a device is inhibited it should not be a
> > wakeup source, so where possible a input-device-driver should disable
> > a device's wakeup capabilities on suspend if inhibited
> 
> If "inhibit" means "do not generate any events going forward", then
> this must also cover wakeup events, so I agree.

Why? These are separate concepts. Do we disable wake on lan when
bringing network interface down? Do we update power/wakeup when device
is inhibited? Do we restore it afterwards? Do we un-inhibit if we
reenable wakeup after device is inhibited? Do we return error? How?

Inhibit works on logical level, i.e. if I have several input interfaces
on the same hardware device, I cam inhibit one leaving others intact.
This does not mean that the device should stop generating wakeup events.
We can't even guarantee this for composite devices.

> 
> > 2. This one is trickier I don't think we have really clearly specified
> > any behavior here. The default behavior of most drivers seems to be
> > using something like this in their suspend callback:
> >
> >          if (device_may_wakeup(dev))
> >                  enable_irq_wake(data->irq);
> >          else if (input->users)
> >                  foo_stop_receiving_events(data);
> >
> > Since this is what most drivers seem to do I believe we should keep
> > this as is and that we should just clearly document that if the
> > input_device has users (has been opened) or not does not matter
> > for its wakeup behavior.
> >
> > Combining these 2 answers leads to this new pseudo code template
> > for an input-device's suspend method:
> >
> >         /*
> >          * If inhibited we have already disabled events and
> >          * we do NOT want to setup the device as wake source.
> >          */
> >         if (input->inhibited)
> >                 return 0;
> >
> >          if (device_may_wakeup(dev))
> >                  enable_irq_wake(data->irq);
> >          else if (input->users)
> >                  foo_stop_receiving_events(data);
> >
> > ###
> 
> Sounds reasonable to me.

However it will not work. For many input devices connected to i2c we
declare interrupt as wakeup interrupt, and the driver does not need to
issue enable_irq_wake() and disable_irq_wake(). The wakeup handling is
happening in driver core, which is not aware of input-specific inhibit
(nor should it be).

I need to ping Mark about the patch adding the similar handling to SPI.

> 
> > A different, but related issue is how to make devices actually use the
> > new inhibit support on the builtin keyboard + touchpad when say the lid
> > is closed.   Arguably this is an userspace problem, but it is a tricky
> > one. Currently on most modern Linux distributions suspend-on-lid-close
> > is handled by systemd-logind and most modern desktop-environments are
> > happy to have logind handle this for them.
> >
> > But most knowledge about input devices and e.g. heurisitics to decide
> > if a touchpad is internal or external are part of libinput. Now we could
> > have libinput use the new inhibit support (1), but then when the lid
> > closes we get race between whatever process is using libinput trying
> > to inhibit the touchpad (which must be done before to suspend to disable
> > it as wakeup source) and logind trying to suspend the system.
> >
> > One solution here would be to move the setting of the inhibit sysfs
> > attr into logind, but that requires adding a whole bunch of extra
> > knowledge to logind which does not really belong there IMHO.

You do not need to push the knowledge into logind, you just need to
communicate to logind what devices can be wakeup sources and which ones
should not. Chrome OS uses udev tags/properties for that.

> >
> > I've been thinking a bit about this and to me it seems that the kernel
> > is in the ideal position to automatically inhibit some devices when
> > some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
> > issue here is to chose on which devices to enable this. I believe
> > that the auto inhibit on some switches mechanism is best done inside
> > the kernel (disabled by default) and then we can have a sysfs
> > attr called auto_inhibit_ev_sw_mask which can be set to e.g.
> > (1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
> > the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
> > inhibit both when the lid is closed or when switched to tablet mode.

This is a policy and should be kept out of the kernel. Yes, we had it
implemented with rfkill input handler, but it caused quite a few issues.
As far as I know it is not being used anymore and we should not try with
SW_LID->inhibit either.

I know it is faster to patch the kernel than to roll out proper
userspace because everyone updates kernel regularly, but it does not
mean it is the right solution.

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 18:28             ` Dmitry Torokhov
@ 2020-06-12  8:14               ` Hans de Goede
  0 siblings, 0 replies; 64+ messages in thread
From: Hans de Goede @ 2020-06-12  8:14 UTC (permalink / raw)
  To: Dmitry Torokhov, Rafael J. Wysocki
  Cc: Andrzej Pietrasiewicz, Linux PM, ACPI Devel Maling List,
	Linux Kernel Mailing List, linux-iio, Linux ARM,
	Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, Collabora Kernel ML

Hi,

On 6/10/20 8:28 PM, Dmitry Torokhov wrote:
> On Wed, Jun 10, 2020 at 12:38:30PM +0200, Rafael J. Wysocki wrote:
>> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>> Hi All,
>>>
>>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>>> This is a quick respin of v3, with just two small changes, please see
>>>> the changelog below.
>>>>
>>>> Userspace might want to implement a policy to temporarily disregard input
>>>> from certain devices.
>>>>
>>>> An example use case is a convertible laptop, whose keyboard can be folded
>>>> under the screen to create tablet-like experience. The user then must hold
>>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>>> keys. It is therefore desirable to temporarily disregard input from the
>>>> keyboard, until it is folded back. This obviously is a policy which should
>>>> be kept out of the kernel, but the kernel must provide suitable means to
>>>> implement such a policy.
>>>
>>> First of all sorry to start a somewhat new discussion about this
>>> while this patch set is also somewhat far along in the review process,
>>> but I believe what I discuss below needs to be taken into account.
>>>
>>> Yesterday I have been looking into why an Asus T101HA would not stay
>>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>>> touchpad in the base of the device starts sending events when the screen
>>> gets close to the touchpad (so when the LID is fully closed) and these
>>> events are causing a wakeup from suspend. HID multi-touch devices
>>> do have a way to tell them to fully stop sending events, also disabling
>>> the USB remote wakeup the device is doing. The question is when to tell
>>> it to not send events though ...
>>>
>>> So now I've been thinking about how to fix this and I believe that there
>>> is some interaction between this problem and this patch-set.
>>>
>>> The problem I'm seeing on the T101HA is about wakeups, so the question
>>> which I want to discuss is:
>>>
>>> 1. How does inhibiting interact with enabling /
>>> disabling the device as a wakeup source ?
> 
> One should not affect the other.
> 
>>>
>>> 2. Since we have now made inhibiting equal open/close how does open/close
>>> interact with a device being a wakeup source ?
> 
> One did not affect another, and it should not.
> 
>>>
>>> And my own initial (to be discussed) answers to these questions:
>>>
>>> 1. It seems to me that when a device is inhibited it should not be a
>>> wakeup source, so where possible a input-device-driver should disable
>>> a device's wakeup capabilities on suspend if inhibited
>>
>> If "inhibit" means "do not generate any events going forward", then
>> this must also cover wakeup events, so I agree.
> 
> Why? These are separate concepts. Do we disable wake on lan when
> bringing network interface down? Do we update power/wakeup when device
> is inhibited? Do we restore it afterwards? Do we un-inhibit if we
> reenable wakeup after device is inhibited? Do we return error? How?
> 
> Inhibit works on logical level, i.e. if I have several input interfaces
> on the same hardware device, I cam inhibit one leaving others intact.
> This does not mean that the device should stop generating wakeup events.
> We can't even guarantee this for composite devices.

After thinking more about this I believe you are right and we should
keep these as 2 separate, completely independent settings.

Especially since the wakeup setting typically is a setting of the
parent device, where as the inhibit is done on the actual input-dev.

###

Some quick background info on my original thoughts here, as mentioned
I started thinking about this because of spurious wakeups from suspend
when the lid of an asus t101ha is "touching" its touchpad. The HID
multi-touch protocol has a setting where we can ask the device to
stop sending events. So even though the kbd + touchpad are a
single composite USB device, we can disable wakeup (in a way)
for just the touchpad at the hid-multitouch level.

So I was thinking maybe adding a separate wakeup setting to the
input device itself for this. But thinking more about it, when
the lid is closed we can just disable wakeup on the entire USB
device, since the keyboard is covered by the lid too.

And then on suspend the hid-multitouch driver can detect that its
parent (or parents parent in the case of USB) has wakeup disabled
and also tell the device to stop scanning for fingers to save some
power.

We probably also need a close and open callbacks add the HID-driver
level, so that if there are no touchpad users we can also use
the same option to put the HID multi-touch device in a low power mode
where it does not scan for fingers.

<snip>

>>> A different, but related issue is how to make devices actually use the
>>> new inhibit support on the builtin keyboard + touchpad when say the lid
>>> is closed.   Arguably this is an userspace problem, but it is a tricky
>>> one. Currently on most modern Linux distributions suspend-on-lid-close
>>> is handled by systemd-logind and most modern desktop-environments are
>>> happy to have logind handle this for them.
>>>
>>> But most knowledge about input devices and e.g. heurisitics to decide
>>> if a touchpad is internal or external are part of libinput. Now we could
>>> have libinput use the new inhibit support (1), but then when the lid
>>> closes we get race between whatever process is using libinput trying
>>> to inhibit the touchpad (which must be done before to suspend to disable
>>> it as wakeup source) and logind trying to suspend the system.
>>>
>>> One solution here would be to move the setting of the inhibit sysfs
>>> attr into logind, but that requires adding a whole bunch of extra
>>> knowledge to logind which does not really belong there IMHO.
> 
> You do not need to push the knowledge into logind, you just need to
> communicate to logind what devices can be wakeup sources and which ones
> should not. Chrome OS uses udev tags/properties for that.

True, I did not think of doing the tag thingie + letting logind do
the inhibit on LID close based on that. logind could also disable
wakeup (to save power while suspended) on devices which are tagged
for it to do that (should probably be a separate tag from the
inhibit tag).

>>> I've been thinking a bit about this and to me it seems that the kernel
>>> is in the ideal position to automatically inhibit some devices when
>>> some EV_SW transitions from 0->1 (and uninhibit again on 1->0). The
>>> issue here is to chose on which devices to enable this. I believe
>>> that the auto inhibit on some switches mechanism is best done inside
>>> the kernel (disabled by default) and then we can have a sysfs
>>> attr called auto_inhibit_ev_sw_mask which can be set to e.g.
>>> (1 << SW_LID) to make the kernel auto-inhibit the input-device whenever
>>> the lid is closed, or to ((1 << SW_LID) | (1 << SW_TABLET_MODE)) to
>>> inhibit both when the lid is closed or when switched to tablet mode.
> 
> This is a policy and should be kept out of the kernel. Yes, we had it
> implemented with rfkill input handler, but it caused quite a few issues.
> As far as I know it is not being used anymore and we should not try with
> SW_LID->inhibit either.
> 
> I know it is faster to patch the kernel than to roll out proper
> userspace because everyone updates kernel regularly, but it does not
> mean it is the right solution.

Agreed, I just could not come up with a clean userspace solution, but
using udev+hwdb to set a tag for logind instead of having the write
to a new auto_inhibit_ev_sw_mask will work nicely.

So I think this is all resolved now (or at least we have a plan for it).

Regards,

Hans


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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
                           ` (7 preceding siblings ...)
  2020-06-10  9:49         ` [PATCH v4 0/7] Support inhibiting input devices Hans de Goede
@ 2020-06-12  8:17         ` Hans de Goede
  2020-08-03 14:40           ` Andrzej Pietrasiewicz
  8 siblings, 1 reply; 64+ messages in thread
From: Hans de Goede @ 2020-06-12  8:17 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, kernel

Hi,

On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
> This is a quick respin of v3, with just two small changes, please see
> the changelog below.
> 
> Userspace might want to implement a policy to temporarily disregard input
> from certain devices.
> 
> An example use case is a convertible laptop, whose keyboard can be folded
> under the screen to create tablet-like experience. The user then must hold
> the laptop in such a way that it is difficult to avoid pressing the keyboard
> keys. It is therefore desirable to temporarily disregard input from the
> keyboard, until it is folded back. This obviously is a policy which should
> be kept out of the kernel, but the kernel must provide suitable means to
> implement such a policy.
> 
> Due to interactions with suspend/resume, a helper has been added for drivers
> to decide if the device is being used or not (PATCH 1/7) and it has been
> applied to relevant drivers (PATCH 2,4,5,6/7).
> 
> PATCH 7/7 adds support for inhibiting input devices.
> 
> This work is inspired by:
> 
> https://chromium.googlesource.com/chromiumos/third_party/kernel/+/45c2d7bb398f74adfae0017e20b224152fde3822
> 
> and
> 
> https://chromium.googlesource.com/chromiumos/third_party/kernel/+/4ce0e8a3697edb8fd071110b3af65014512061c7
> 
> In this respin the elan_i2c patch is dropped and converting it will be
> addressed later.
> 
> v3..v4:
> - updated the comment in input_open_device() (Hans)
> - used more straightforward locking pattern in adc/exynos (Michał)
> 
> v2..v3:
> - ignored autorepeat events in input_get_disposition() if a key is not
> pressed (Hans)
> - dropped inhibit()/uninhibit() driver callbacks (Hans)
> - split ACPI button patch into taking the lock and using the helper (Rafael)
> - dropped the elan_i2c conversion
> - fixed typos in exynos adc
> 
> v1..v2:
> - added input_device_enabled() helper and used it in drivers (Dmitry)
> - the fact of open() and close() being called in inhibit/uninhibit paths has
> been emphasized in the commit message of PATCH 6/7 (Dmitry)
> 
> Andrzej Pietrasiewicz (6):
>    Input: add input_device_enabled()
>    Input: use input_device_enabled()
>    ACPI: button: Access input device's users under appropriate mutex
>    ACPI: button: Use input_device_enabled() helper
>    iio: adc: exynos: Use input_device_enabled()
>    platform/x86: thinkpad_acpi: Use input_device_enabled()
> 
> Patrik Fimml (1):
>    Input: Add "inhibited" property

The entire series looks good to me:

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans



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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-10 13:41                 ` Andrzej Pietrasiewicz
@ 2020-06-12  8:30                   ` Hans de Goede
  2020-06-12  8:47                     ` Andrzej Pietrasiewicz
  2020-06-16 17:29                     ` [PATCH] Input: document inhibiting Andrzej Pietrasiewicz
  0 siblings, 2 replies; 64+ messages in thread
From: Hans de Goede @ 2020-06-12  8:30 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, Rafael J. Wysocki
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi,

On 6/10/20 3:41 PM, Andrzej Pietrasiewicz wrote:
> Hi Hans,
> 
> W dniu 10.06.2020 o 15:21, Hans de Goede pisze:
>> Hi,
>>
>> On 6/10/20 3:12 PM, Andrzej Pietrasiewicz wrote:
>>> Hi All,
>>>
>>> W dniu 10.06.2020 o 12:38, Rafael J. Wysocki pisze:
>>>> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>
>>>>> Hi All,
>>>>>
>>>>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>>>>> This is a quick respin of v3, with just two small changes, please see
>>>>>> the changelog below.
>>>>>>
>>>>>> Userspace might want to implement a policy to temporarily disregard input
>>>>>> from certain devices.
>>>>>>
>>>>>> An example use case is a convertible laptop, whose keyboard can be folded
>>>>>> under the screen to create tablet-like experience. The user then must hold
>>>>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>>>>> keys. It is therefore desirable to temporarily disregard input from the
>>>>>> keyboard, until it is folded back. This obviously is a policy which should
>>>>>> be kept out of the kernel, but the kernel must provide suitable means to
>>>>>> implement such a policy.
>>>>>
>>>>> First of all sorry to start a somewhat new discussion about this
>>>>> while this patch set is also somewhat far along in the review process,
>>>>> but I believe what I discuss below needs to be taken into account.
>>>>>
>>>>> Yesterday I have been looking into why an Asus T101HA would not stay
>>>>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>>>>> touchpad in the base of the device starts sending events when the screen
>>>>> gets close to the touchpad (so when the LID is fully closed) and these
>>>>> events are causing a wakeup from suspend. HID multi-touch devices
>>>>> do have a way to tell them to fully stop sending events, also disabling
>>>>> the USB remote wakeup the device is doing. The question is when to tell
>>>>> it to not send events though ...
>>>>>
>>>>> So now I've been thinking about how to fix this and I believe that there
>>>>> is some interaction between this problem and this patch-set.
>>>>>
>>>>> The problem I'm seeing on the T101HA is about wakeups, so the question
>>>>> which I want to discuss is:
>>>>>
>>>>> 1. How does inhibiting interact with enabling /
>>>>> disabling the device as a wakeup source ?
>>>>>
>>>>> 2. Since we have now made inhibiting equal open/close how does open/close
>>>>> interact with a device being a wakeup source ?
>>>>>
>>>>> And my own initial (to be discussed) answers to these questions:
>>>>>
>>>>> 1. It seems to me that when a device is inhibited it should not be a
>>>>> wakeup source, so where possible a input-device-driver should disable
>>>>> a device's wakeup capabilities on suspend if inhibited
>>>>
>>>> If "inhibit" means "do not generate any events going forward", then
>>>> this must also cover wakeup events, so I agree.
>>>
>>> I agree, too.
>>>
>>>>
>>>>> 2. This one is trickier I don't think we have really clearly specified
>>>>> any behavior here. The default behavior of most drivers seems to be
>>>>> using something like this in their suspend callback:
>>>>>
>>>>>           if (device_may_wakeup(dev))
>>>>>                   enable_irq_wake(data->irq);
>>>>>           else if (input->users)
>>>>>                   foo_stop_receiving_events(data);
>>>>>
>>>>> Since this is what most drivers seem to do I believe we should keep
>>>>> this as is and that we should just clearly document that if the
>>>>> input_device has users (has been opened) or not does not matter
>>>>> for its wakeup behavior.
>>>>>
>>>>> Combining these 2 answers leads to this new pseudo code template
>>>>> for an input-device's suspend method:
>>>>>
>>>>>          /*
>>>>>           * If inhibited we have already disabled events and
>>>>>           * we do NOT want to setup the device as wake source.
>>>>>           */
>>>>>          if (input->inhibited)
>>>>>                  return 0;
>>>
>>> Right, if a device is inhibited it shouldn't become a wakeup source,
>>> because that would contradict the purpose of being inhibited.
>>
>> Ack. Note I do think that we need to document this (and more
>> in general the answer to both questions from above) clearly so
>> that going forward if there are any questions about how this is
>> supposed to work we can just point to the docs.
>>
>> Can you do a follow-up patch, or include a patch in your next
>> version which documents this (once we agree on what "this"
>> exactly is) ?
> 
> Sure I can. Just need to know when "this" becomes stable enough ;)
> If this series otherwise looks mature enough I would opt for a
> follow-up patch.

FWIW after my flip-flop to agreeing with Dmitry that the 2
(inhibit vs wakeup) should be completely orthogonal this new
policy is stable/mature from my pov (and consistent with how
we handle wakeup vs input_dev->users).

I still think it would be good to do a follow-up documentation
patch documenting that these (and esp. inhibit) are orthogonal.

This will mean for example that if a device is inhibit but
still wakeup enabled and the device's close method silences
the devices, that it needs to be unsilenced in suspend.
This might be worth mentioning in the docs even though
drivers which silence the device on close should already
unsilence the device on suspend when it is wakeup-enabled.

Note maybe we should give it a couple of days for others to
give their opinion before you submit the follow-up documentation
patch.

Regards,

Hans




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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-12  8:30                   ` Hans de Goede
@ 2020-06-12  8:47                     ` Andrzej Pietrasiewicz
  2020-06-16 17:29                     ` [PATCH] Input: document inhibiting Andrzej Pietrasiewicz
  1 sibling, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-12  8:47 UTC (permalink / raw)
  To: Hans de Goede, Rafael J. Wysocki
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Collabora Kernel ML

Hi Hans,

W dniu 12.06.2020 o 10:30, Hans de Goede pisze:
> Hi,
> 
> On 6/10/20 3:41 PM, Andrzej Pietrasiewicz wrote:
>> Hi Hans,
>>
>> W dniu 10.06.2020 o 15:21, Hans de Goede pisze:
>>> Hi,
>>>
>>> On 6/10/20 3:12 PM, Andrzej Pietrasiewicz wrote:
>>>> Hi All,
>>>>
>>>> W dniu 10.06.2020 o 12:38, Rafael J. Wysocki pisze:
>>>>> On Wed, Jun 10, 2020 at 11:50 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>
>>>>>> Hi All,
>>>>>>
>>>>>> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>>>>>>> This is a quick respin of v3, with just two small changes, please see
>>>>>>> the changelog below.
>>>>>>>
>>>>>>> Userspace might want to implement a policy to temporarily disregard input
>>>>>>> from certain devices.
>>>>>>>
>>>>>>> An example use case is a convertible laptop, whose keyboard can be folded
>>>>>>> under the screen to create tablet-like experience. The user then must hold
>>>>>>> the laptop in such a way that it is difficult to avoid pressing the keyboard
>>>>>>> keys. It is therefore desirable to temporarily disregard input from the
>>>>>>> keyboard, until it is folded back. This obviously is a policy which should
>>>>>>> be kept out of the kernel, but the kernel must provide suitable means to
>>>>>>> implement such a policy.
>>>>>>
>>>>>> First of all sorry to start a somewhat new discussion about this
>>>>>> while this patch set is also somewhat far along in the review process,
>>>>>> but I believe what I discuss below needs to be taken into account.
>>>>>>
>>>>>> Yesterday I have been looking into why an Asus T101HA would not stay
>>>>>> suspended when the LID is closed. The cause is that the USB HID multi-touch
>>>>>> touchpad in the base of the device starts sending events when the screen
>>>>>> gets close to the touchpad (so when the LID is fully closed) and these
>>>>>> events are causing a wakeup from suspend. HID multi-touch devices
>>>>>> do have a way to tell them to fully stop sending events, also disabling
>>>>>> the USB remote wakeup the device is doing. The question is when to tell
>>>>>> it to not send events though ...
>>>>>>
>>>>>> So now I've been thinking about how to fix this and I believe that there
>>>>>> is some interaction between this problem and this patch-set.
>>>>>>
>>>>>> The problem I'm seeing on the T101HA is about wakeups, so the question
>>>>>> which I want to discuss is:
>>>>>>
>>>>>> 1. How does inhibiting interact with enabling /
>>>>>> disabling the device as a wakeup source ?
>>>>>>
>>>>>> 2. Since we have now made inhibiting equal open/close how does open/close
>>>>>> interact with a device being a wakeup source ?
>>>>>>
>>>>>> And my own initial (to be discussed) answers to these questions:
>>>>>>
>>>>>> 1. It seems to me that when a device is inhibited it should not be a
>>>>>> wakeup source, so where possible a input-device-driver should disable
>>>>>> a device's wakeup capabilities on suspend if inhibited
>>>>>
>>>>> If "inhibit" means "do not generate any events going forward", then
>>>>> this must also cover wakeup events, so I agree.
>>>>
>>>> I agree, too.
>>>>
>>>>>
>>>>>> 2. This one is trickier I don't think we have really clearly specified
>>>>>> any behavior here. The default behavior of most drivers seems to be
>>>>>> using something like this in their suspend callback:
>>>>>>
>>>>>>           if (device_may_wakeup(dev))
>>>>>>                   enable_irq_wake(data->irq);
>>>>>>           else if (input->users)
>>>>>>                   foo_stop_receiving_events(data);
>>>>>>
>>>>>> Since this is what most drivers seem to do I believe we should keep
>>>>>> this as is and that we should just clearly document that if the
>>>>>> input_device has users (has been opened) or not does not matter
>>>>>> for its wakeup behavior.
>>>>>>
>>>>>> Combining these 2 answers leads to this new pseudo code template
>>>>>> for an input-device's suspend method:
>>>>>>
>>>>>>          /*
>>>>>>           * If inhibited we have already disabled events and
>>>>>>           * we do NOT want to setup the device as wake source.
>>>>>>           */
>>>>>>          if (input->inhibited)
>>>>>>                  return 0;
>>>>
>>>> Right, if a device is inhibited it shouldn't become a wakeup source,
>>>> because that would contradict the purpose of being inhibited.
>>>
>>> Ack. Note I do think that we need to document this (and more
>>> in general the answer to both questions from above) clearly so
>>> that going forward if there are any questions about how this is
>>> supposed to work we can just point to the docs.
>>>
>>> Can you do a follow-up patch, or include a patch in your next
>>> version which documents this (once we agree on what "this"
>>> exactly is) ?
>>
>> Sure I can. Just need to know when "this" becomes stable enough ;)
>> If this series otherwise looks mature enough I would opt for a
>> follow-up patch.
> 
> FWIW after my flip-flop to agreeing with Dmitry that the 2
> (inhibit vs wakeup) should be completely orthogonal this new
> policy is stable/mature from my pov (and consistent with how
> we handle wakeup vs input_dev->users).
> 
> I still think it would be good to do a follow-up documentation
> patch documenting that these (and esp. inhibit) are orthogonal.
> 
> This will mean for example that if a device is inhibit but
> still wakeup enabled and the device's close method silences
> the devices, that it needs to be unsilenced in suspend.
> This might be worth mentioning in the docs even though
> drivers which silence the device on close should already
> unsilence the device on suspend when it is wakeup-enabled.
> 
> Note maybe we should give it a couple of days for others to
> give their opinion before you submit the follow-up documentation
> patch.
> 

True. I will send something after the weekend.

Andrzej

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

* [PATCH] Input: document inhibiting
  2020-06-12  8:30                   ` Hans de Goede
  2020-06-12  8:47                     ` Andrzej Pietrasiewicz
@ 2020-06-16 17:29                     ` Andrzej Pietrasiewicz
  2020-06-16 17:38                       ` Randy Dunlap
  2020-06-17  7:44                       ` Hans de Goede
  1 sibling, 2 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-16 17:29 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Andrzej Pietrasiewicz,
	Michał Mirosław, kernel

Document inhibiting input devices and its relation to being
a wakeup source.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---

@Hans, @Dmitry,

My fist attempt at documenting inhibiting. Kindly look at it to see if I haven't got anything
wrong.

Andrzej

 Documentation/input/input-programming.rst | 36 +++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
index 45a4c6e05e39..0cd1ad4504fb 100644
--- a/Documentation/input/input-programming.rst
+++ b/Documentation/input/input-programming.rst
@@ -164,6 +164,42 @@ disconnects. Calls to both callbacks are serialized.
 The open() callback should return a 0 in case of success or any nonzero value
 in case of failure. The close() callback (which is void) must always succeed.
 
+Inhibiting input devices
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Inhibiting a device means ignoring input events from it. As such it is about maintaining
+relationships with input handlers - either an already existing relationships, or
+relationships to be established while the device is in inhibited state.
+
+If a device is inhibited, no input handler will receive events from it.
+
+The fact that nobody wants events from the device is exploited further, by calling device's
+close() (if there are users) and open() (if there are users) on inhibit and uninhibit
+operations, respectively. Indeed, the meaning of close() is to stop providing events
+to the input core and that of open() is to start providing events to the input core.
+
+Inhibiting and uninhibiting is orthogonal to opening and closing the device by input
+handlers. Userspace might want to inhibit a device in anticipation before any handler is
+positively matched against it.
+
+Inhibiting and uninhibiting is orthogonal to device's being a wakeup source, too. Being a
+wakeup source plays a role when the system is sleeping, not when the system is operating.
+How drivers should program their interaction between inhibiting, sleeping and being a wakeup
+source is driver-specific.
+
+Taking the analogy with the network devices - bringing a network interface down doesn't mean
+that it should be impossible to be wake the system up on LAN through this interface. So, there
+may be input drivers which should be considered wakeup sources even when inhibited. Actually,
+in many i2c input devices their interrupt is declared a wakeup interrupt and its handling
+happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
+Composite devices containing several interfaces can be inhibited on a per-interface basis and
+e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
+
+If a device is to be considered a wakeup source while inhibited, special care must be taken when
+programming its suspend(), as it might need to call device's open(). Depending on what close()
+means for the device in question not opening() it before going to sleep might make it impossible
+to provide any wakeup events. The device is going to sleep anyway.
+
 Basic event types
 ~~~~~~~~~~~~~~~~~
 
-- 
2.17.1


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

* Re: [PATCH] Input: document inhibiting
  2020-06-16 17:29                     ` [PATCH] Input: document inhibiting Andrzej Pietrasiewicz
@ 2020-06-16 17:38                       ` Randy Dunlap
  2020-06-17  7:44                       ` Hans de Goede
  1 sibling, 0 replies; 64+ messages in thread
From: Randy Dunlap @ 2020-06-16 17:38 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Michał Mirosław, kernel

On 6/16/20 10:29 AM, Andrzej Pietrasiewicz wrote:
> Document inhibiting input devices and its relation to being
> a wakeup source.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---

Hi,
I have some editorial comments. Please see below.


> @Hans, @Dmitry,
> 
> My fist attempt at documenting inhibiting. Kindly look at it to see if I haven't got anything
> wrong.
> 
> Andrzej
> 
>  Documentation/input/input-programming.rst | 36 +++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
> index 45a4c6e05e39..0cd1ad4504fb 100644
> --- a/Documentation/input/input-programming.rst
> +++ b/Documentation/input/input-programming.rst
> @@ -164,6 +164,42 @@ disconnects. Calls to both callbacks are serialized.
>  The open() callback should return a 0 in case of success or any nonzero value
>  in case of failure. The close() callback (which is void) must always succeed.
>  
> +Inhibiting input devices
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Inhibiting a device means ignoring input events from it. As such it is about maintaining
> +relationships with input handlers - either an already existing relationships, or
> +relationships to be established while the device is in inhibited state.
> +
> +If a device is inhibited, no input handler will receive events from it.
> +
> +The fact that nobody wants events from the device is exploited further, by calling device's
> +close() (if there are users) and open() (if there are users) on inhibit and uninhibit
> +operations, respectively. Indeed, the meaning of close() is to stop providing events
> +to the input core and that of open() is to start providing events to the input core.
> +
> +Inhibiting and uninhibiting is orthogonal to opening and closing the device by input

                               are

> +handlers. Userspace might want to inhibit a device in anticipation before any handler is
> +positively matched against it.
> +
> +Inhibiting and uninhibiting is orthogonal to device's being a wakeup source, too. Being a

                               are

> +wakeup source plays a role when the system is sleeping, not when the system is operating.
> +How drivers should program their interaction between inhibiting, sleeping and being a wakeup
> +source is driver-specific.
> +
> +Taking the analogy with the network devices - bringing a network interface down doesn't mean
> +that it should be impossible to be wake the system up on LAN through this interface. So, there
> +may be input drivers which should be considered wakeup sources even when inhibited. Actually,
> +in many i2c input devices their interrupt is declared a wakeup interrupt and its handling

           I2C

> +happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
> +Composite devices containing several interfaces can be inhibited on a per-interface basis and
> +e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
> +
> +If a device is to be considered a wakeup source while inhibited, special care must be taken when
> +programming its suspend(), as it might need to call device's open(). Depending on what close()
> +means for the device in question not opening() it before going to sleep might make it impossible

                        in question, not

> +to provide any wakeup events. The device is going to sleep anyway.
> +
>  Basic event types
>  ~~~~~~~~~~~~~~~~~
>  
> 

thanks for documentation.

-- 
~Randy


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

* Re: [PATCH] Input: document inhibiting
  2020-06-16 17:29                     ` [PATCH] Input: document inhibiting Andrzej Pietrasiewicz
  2020-06-16 17:38                       ` Randy Dunlap
@ 2020-06-17  7:44                       ` Hans de Goede
  2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
  1 sibling, 1 reply; 64+ messages in thread
From: Hans de Goede @ 2020-06-17  7:44 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Michał Mirosław, kernel

Hi,

On 6/16/20 7:29 PM, Andrzej Pietrasiewicz wrote:
> Document inhibiting input devices and its relation to being
> a wakeup source.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
> 
> @Hans, @Dmitry,
> 
> My fist attempt at documenting inhibiting. Kindly look at it to see if I haven't got anything
> wrong.
> 
> Andrzej
> 
>   Documentation/input/input-programming.rst | 36 +++++++++++++++++++++++
>   1 file changed, 36 insertions(+)
> 
> diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
> index 45a4c6e05e39..0cd1ad4504fb 100644
> --- a/Documentation/input/input-programming.rst
> +++ b/Documentation/input/input-programming.rst
> @@ -164,6 +164,42 @@ disconnects. Calls to both callbacks are serialized.
>   The open() callback should return a 0 in case of success or any nonzero value
>   in case of failure. The close() callback (which is void) must always succeed.
>   
> +Inhibiting input devices
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Inhibiting a device means ignoring input events from it. As such it is about maintaining
> +relationships with input handlers - either an already existing relationships, or
> +relationships to be established while the device is in inhibited state.
> +
> +If a device is inhibited, no input handler will receive events from it.
> +
> +The fact that nobody wants events from the device is exploited further, by calling device's
> +close() (if there are users) and open() (if there are users) on inhibit and uninhibit
> +operations, respectively. Indeed, the meaning of close() is to stop providing events
> +to the input core and that of open() is to start providing events to the input core.

Maybe add the following here? :

Calling the device's close() method on inhibit (if there are users) allows the driver
to save power. Either by directly powering down the device or by releasing the
runtime-pm reference it got in open() when the driver is using runtime-pm.

Otherwise this looks good to me. Thank you for doing this, we (including myself)
really need to get better at doucmenting all sorts of kernel things. Often we have
these long discussions about something on the mailinglist and then everyone is
expected to just know what was decided from the on, which really doesn't work all
that well.

> +
> +Inhibiting and uninhibiting is orthogonal to opening and closing the device by input
> +handlers. Userspace might want to inhibit a device in anticipation before any handler is
> +positively matched against it.
> +
> +Inhibiting and uninhibiting is orthogonal to device's being a wakeup source, too. Being a
> +wakeup source plays a role when the system is sleeping, not when the system is operating.
> +How drivers should program their interaction between inhibiting, sleeping and being a wakeup
> +source is driver-specific.
> +
> +Taking the analogy with the network devices - bringing a network interface down doesn't mean
> +that it should be impossible to be wake the system up on LAN through this interface. So, there
> +may be input drivers which should be considered wakeup sources even when inhibited. Actually,
> +in many i2c input devices their interrupt is declared a wakeup interrupt and its handling
> +happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
> +Composite devices containing several interfaces can be inhibited on a per-interface basis and
> +e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
> +
> +If a device is to be considered a wakeup source while inhibited, special care must be taken when
> +programming its suspend(), as it might need to call device's open(). Depending on what close()
> +means for the device in question not opening() it before going to sleep might make it impossible
> +to provide any wakeup events. The device is going to sleep anyway.
> +
>   Basic event types
>   ~~~~~~~~~~~~~~~~~
>   
> 


Regards,

Hans


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

* [PATCH v2] Input: document inhibiting
  2020-06-17  7:44                       ` Hans de Goede
@ 2020-06-17 10:18                         ` Andrzej Pietrasiewicz
  2020-06-17 10:21                           ` Hans de Goede
                                             ` (3 more replies)
  0 siblings, 4 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-06-17 10:18 UTC (permalink / raw)
  To: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Andrzej Pietrasiewicz,
	Michał Mirosław, kernel

Document inhibiting input devices and its relation to being
a wakeup source.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
v1..v2:

- Addressed editorial comments from Randy
- Added a paragraph by Hans

 Documentation/input/input-programming.rst | 40 +++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
index 45a4c6e05e39..7432315cc829 100644
--- a/Documentation/input/input-programming.rst
+++ b/Documentation/input/input-programming.rst
@@ -164,6 +164,46 @@ disconnects. Calls to both callbacks are serialized.
 The open() callback should return a 0 in case of success or any nonzero value
 in case of failure. The close() callback (which is void) must always succeed.
 
+Inhibiting input devices
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Inhibiting a device means ignoring input events from it. As such it is about maintaining
+relationships with input handlers - either already existing relationships, or relationships
+to be established while the device is in inhibited state.
+
+If a device is inhibited, no input handler will receive events from it.
+
+The fact that nobody wants events from the device is exploited further, by calling device's
+close() (if there are users) and open() (if there are users) on inhibit and uninhibit
+operations, respectively. Indeed, the meaning of close() is to stop providing events
+to the input core and that of open() is to start providing events to the input core.
+
+Calling the device's close() method on inhibit (if there are users) allows the driver
+to save power. Either by directly powering down the device or by releasing the
+runtime-pm reference it got in open() when the driver is using runtime-pm.
+
+Inhibiting and uninhibiting are orthogonal to opening and closing the device by input
+handlers. Userspace might want to inhibit a device in anticipation before any handler is
+positively matched against it.
+
+Inhibiting and uninhibiting are orthogonal to device's being a wakeup source, too. Being a
+wakeup source plays a role when the system is sleeping, not when the system is operating.
+How drivers should program their interaction between inhibiting, sleeping and being a wakeup
+source is driver-specific.
+
+Taking the analogy with the network devices - bringing a network interface down doesn't mean
+that it should be impossible be wake the system up on LAN through this interface. So, there
+may be input drivers which should be considered wakeup sources even when inhibited. Actually,
+in many I2C input devices their interrupt is declared a wakeup interrupt and its handling
+happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
+Composite devices containing several interfaces can be inhibited on a per-interface basis and
+e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
+
+If a device is to be considered a wakeup source while inhibited, special care must be taken when
+programming its suspend(), as it might need to call device's open(). Depending on what close()
+means for the device in question, not opening() it before going to sleep might make it
+impossible to provide any wakeup events. The device is going to sleep anyway.
+
 Basic event types
 ~~~~~~~~~~~~~~~~~
 
-- 
2.17.1


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

* Re: [PATCH v2] Input: document inhibiting
  2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
@ 2020-06-17 10:21                           ` Hans de Goede
  2020-06-17 16:52                           ` Randy Dunlap
                                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 64+ messages in thread
From: Hans de Goede @ 2020-06-17 10:21 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Michał Mirosław, kernel

Hi,

On 6/17/20 12:18 PM, Andrzej Pietrasiewicz wrote:
> Document inhibiting input devices and its relation to being
> a wakeup source.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
> v1..v2:
> 
> - Addressed editorial comments from Randy
> - Added a paragraph by Hans

Thank you.

v2 looks good to me:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans



> 
>   Documentation/input/input-programming.rst | 40 +++++++++++++++++++++++
>   1 file changed, 40 insertions(+)
> 
> diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
> index 45a4c6e05e39..7432315cc829 100644
> --- a/Documentation/input/input-programming.rst
> +++ b/Documentation/input/input-programming.rst
> @@ -164,6 +164,46 @@ disconnects. Calls to both callbacks are serialized.
>   The open() callback should return a 0 in case of success or any nonzero value
>   in case of failure. The close() callback (which is void) must always succeed.
>   
> +Inhibiting input devices
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Inhibiting a device means ignoring input events from it. As such it is about maintaining
> +relationships with input handlers - either already existing relationships, or relationships
> +to be established while the device is in inhibited state.
> +
> +If a device is inhibited, no input handler will receive events from it.
> +
> +The fact that nobody wants events from the device is exploited further, by calling device's
> +close() (if there are users) and open() (if there are users) on inhibit and uninhibit
> +operations, respectively. Indeed, the meaning of close() is to stop providing events
> +to the input core and that of open() is to start providing events to the input core.
> +
> +Calling the device's close() method on inhibit (if there are users) allows the driver
> +to save power. Either by directly powering down the device or by releasing the
> +runtime-pm reference it got in open() when the driver is using runtime-pm.
> +
> +Inhibiting and uninhibiting are orthogonal to opening and closing the device by input
> +handlers. Userspace might want to inhibit a device in anticipation before any handler is
> +positively matched against it.
> +
> +Inhibiting and uninhibiting are orthogonal to device's being a wakeup source, too. Being a
> +wakeup source plays a role when the system is sleeping, not when the system is operating.
> +How drivers should program their interaction between inhibiting, sleeping and being a wakeup
> +source is driver-specific.
> +
> +Taking the analogy with the network devices - bringing a network interface down doesn't mean
> +that it should be impossible be wake the system up on LAN through this interface. So, there
> +may be input drivers which should be considered wakeup sources even when inhibited. Actually,
> +in many I2C input devices their interrupt is declared a wakeup interrupt and its handling
> +happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
> +Composite devices containing several interfaces can be inhibited on a per-interface basis and
> +e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
> +
> +If a device is to be considered a wakeup source while inhibited, special care must be taken when
> +programming its suspend(), as it might need to call device's open(). Depending on what close()
> +means for the device in question, not opening() it before going to sleep might make it
> +impossible to provide any wakeup events. The device is going to sleep anyway.
> +
>   Basic event types
>   ~~~~~~~~~~~~~~~~~
>   
> 


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

* Re: [PATCH v2] Input: document inhibiting
  2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
  2020-06-17 10:21                           ` Hans de Goede
@ 2020-06-17 16:52                           ` Randy Dunlap
  2020-06-23 13:35                           ` Pavel Machek
  2020-12-03  6:27                           ` Dmitry Torokhov
  3 siblings, 0 replies; 64+ messages in thread
From: Randy Dunlap @ 2020-06-17 16:52 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Michał Mirosław, kernel

On 6/17/20 3:18 AM, Andrzej Pietrasiewicz wrote:
> Document inhibiting input devices and its relation to being
> a wakeup source.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
> v1..v2:
> 
> - Addressed editorial comments from Randy
> - Added a paragraph by Hans
> 
>  Documentation/input/input-programming.rst | 40 +++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
> index 45a4c6e05e39..7432315cc829 100644
> --- a/Documentation/input/input-programming.rst
> +++ b/Documentation/input/input-programming.rst
> @@ -164,6 +164,46 @@ disconnects. Calls to both callbacks are serialized.
>  The open() callback should return a 0 in case of success or any nonzero value
>  in case of failure. The close() callback (which is void) must always succeed.
>  
> +Inhibiting input devices
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Inhibiting a device means ignoring input events from it. As such it is about maintaining
> +relationships with input handlers - either already existing relationships, or relationships
> +to be established while the device is in inhibited state.
> +
> +If a device is inhibited, no input handler will receive events from it.
> +
> +The fact that nobody wants events from the device is exploited further, by calling device's
> +close() (if there are users) and open() (if there are users) on inhibit and uninhibit
> +operations, respectively. Indeed, the meaning of close() is to stop providing events
> +to the input core and that of open() is to start providing events to the input core.
> +
> +Calling the device's close() method on inhibit (if there are users) allows the driver
> +to save power. Either by directly powering down the device or by releasing the
> +runtime-pm reference it got in open() when the driver is using runtime-pm.
> +
> +Inhibiting and uninhibiting are orthogonal to opening and closing the device by input
> +handlers. Userspace might want to inhibit a device in anticipation before any handler is
> +positively matched against it.
> +
> +Inhibiting and uninhibiting are orthogonal to device's being a wakeup source, too. Being a
> +wakeup source plays a role when the system is sleeping, not when the system is operating.
> +How drivers should program their interaction between inhibiting, sleeping and being a wakeup
> +source is driver-specific.
> +
> +Taking the analogy with the network devices - bringing a network interface down doesn't mean
> +that it should be impossible be wake the system up on LAN through this interface. So, there
> +may be input drivers which should be considered wakeup sources even when inhibited. Actually,
> +in many I2C input devices their interrupt is declared a wakeup interrupt and its handling
> +happens in driver's core, which is not aware of input-specific inhibit (nor should it be).
> +Composite devices containing several interfaces can be inhibited on a per-interface basis and
> +e.g. inhibiting one interface shouldn't affect the device's capability of being a wakeup source.
> +
> +If a device is to be considered a wakeup source while inhibited, special care must be taken when
> +programming its suspend(), as it might need to call device's open(). Depending on what close()
> +means for the device in question, not opening() it before going to sleep might make it
> +impossible to provide any wakeup events. The device is going to sleep anyway.
> +
>  Basic event types
>  ~~~~~~~~~~~~~~~~~
>  
> 

Reviewed-by: Randy Dunlap <rdunlap@infradead.org>

Thanks.

-- 
~Randy

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

* Re: [PATCH v2] Input: document inhibiting
  2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
  2020-06-17 10:21                           ` Hans de Goede
  2020-06-17 16:52                           ` Randy Dunlap
@ 2020-06-23 13:35                           ` Pavel Machek
  2020-12-03  6:27                           ` Dmitry Torokhov
  3 siblings, 0 replies; 64+ messages in thread
From: Pavel Machek @ 2020-06-23 13:35 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, Micha?? Miros??aw, kernel

Hi!

> +Inhibiting input devices
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Inhibiting a device means ignoring input events from it. As such it is about maintaining
> +relationships with input handlers - either already existing relationships, or relationships
> +to be established while the device is in inhibited state.
> +
> +If a device is inhibited, no input handler will receive events from it.
> +
> +The fact that nobody wants events from the device is exploited further, by calling device's
> +close() (if there are users) and open() (if there are users) on inhibit and uninhibit
> +operations, respectively. Indeed, the meaning of close() is to stop providing events
> +to the input core and that of open() is to start providing events to the input core.
> +
> +Calling the device's close() method on inhibit (if there are users) allows the driver
> +to save power. Either by directly powering down the device or by releasing the
> +runtime-pm reference it got in open() when the driver is using runtime-pm.
> +
> +Inhibiting and uninhibiting are orthogonal to opening and closing the device by input
> +handlers. Userspace might want to inhibit a device in anticipation before any handler is
> +positively matched against it.

Ok.

> +Inhibiting and uninhibiting are orthogonal to device's being a wakeup source, too. 
> Being a +wakeup source plays a role when the system is sleeping, not when the system is 
> operating. +How drivers should program their interaction between inhibiting, sleeping 
> and being a wakeup +source is driver-specific. + +Taking the analogy with the network 

I don't believe making interaction driver-specific is good idea. We should decide
what reasonable behaviour is and then make drivers implement that...

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

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

* Re: [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-08 11:22         ` [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
@ 2020-06-24 15:00           ` Rafael J. Wysocki
  2020-06-25  5:23             ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Rafael J. Wysocki @ 2020-06-24 15:00 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: Linux PM, ACPI Devel Maling List, Linux Kernel Mailing List,
	linux-iio, Linux ARM, Linux Samsung SoC, linux-input,
	linux-tegra, patches, ibm-acpi-devel, Platform Driver,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, Collabora Kernel ML

On Mon, Jun 8, 2020 at 1:22 PM Andrzej Pietrasiewicz
<andrzej.p@collabora.com> wrote:
>
> Inspecting input device's 'users' member should be done under device's
> mutex, so add appropriate invocations.
>
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>

This looks like a fix that might be applied independently of the other
patches in the series.

Do you want me to pick it up?

> ---
>  drivers/acpi/button.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index 78cfc70cb320..ff7ab291f678 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -456,13 +456,16 @@ static int acpi_button_resume(struct device *dev)
>  {
>         struct acpi_device *device = to_acpi_device(dev);
>         struct acpi_button *button = acpi_driver_data(device);
> +       struct input_dev *input = button->input;
>
>         button->suspended = false;
> -       if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
> +       mutex_lock(&input->mutex);
> +       if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
>                 button->last_state = !!acpi_lid_evaluate_state(device);
>                 button->last_time = ktime_get();
>                 acpi_lid_initialize_state(device);
>         }
> +       mutex_unlock(&input->mutex);
>         return 0;
>  }
>  #endif
> --
> 2.17.1
>

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

* Re: [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-24 15:00           ` Rafael J. Wysocki
@ 2020-06-25  5:23             ` Dmitry Torokhov
  2020-06-25 10:55               ` Rafael J. Wysocki
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-06-25  5:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Andrzej Pietrasiewicz, Linux PM, ACPI Devel Maling List,
	Linux Kernel Mailing List, linux-iio, Linux ARM,
	Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh,
	Collabora Kernel ML

On Wed, Jun 24, 2020 at 05:00:09PM +0200, Rafael J. Wysocki wrote:
> On Mon, Jun 8, 2020 at 1:22 PM Andrzej Pietrasiewicz
> <andrzej.p@collabora.com> wrote:
> >
> > Inspecting input device's 'users' member should be done under device's
> > mutex, so add appropriate invocations.
> >
> > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> 
> This looks like a fix that might be applied independently of the other
> patches in the series.
> 
> Do you want me to pick it up?

If you pick it we'll have to have a dance with this series. Can I apply
instead?

I do not think this change has any practical effect as nobody
attaches/detached input handlers or opening/closing input devices when
system goes through device resume phase.

> 
> > ---
> >  drivers/acpi/button.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> > index 78cfc70cb320..ff7ab291f678 100644
> > --- a/drivers/acpi/button.c
> > +++ b/drivers/acpi/button.c
> > @@ -456,13 +456,16 @@ static int acpi_button_resume(struct device *dev)
> >  {
> >         struct acpi_device *device = to_acpi_device(dev);
> >         struct acpi_button *button = acpi_driver_data(device);
> > +       struct input_dev *input = button->input;
> >
> >         button->suspended = false;
> > -       if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
> > +       mutex_lock(&input->mutex);
> > +       if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
> >                 button->last_state = !!acpi_lid_evaluate_state(device);
> >                 button->last_time = ktime_get();
> >                 acpi_lid_initialize_state(device);
> >         }
> > +       mutex_unlock(&input->mutex);
> >         return 0;
> >  }
> >  #endif
> > --
> > 2.17.1
> >

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper
  2020-06-08 11:22         ` [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
@ 2020-06-25  5:24           ` Dmitry Torokhov
  2020-10-05  5:06             ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-06-25  5:24 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Mon, Jun 08, 2020 at 01:22:08PM +0200, Andrzej Pietrasiewicz wrote:
> A new helper is available, so use it.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
>  drivers/acpi/button.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index ff7ab291f678..4deb2b48d03c 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -411,7 +411,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
>  		input = button->input;
>  		if (button->type == ACPI_BUTTON_TYPE_LID) {
>  			mutex_lock(&button->input->mutex);
> -			users = button->input->users;
> +			users = input_device_enabled(button->input);
>  			mutex_unlock(&button->input->mutex);
>  			if (users)

This chunk (pre-patch) is really wrong. 'users' value is obsolete and
can not be trusted the moment we unlocked the mutex. "if" needs to be
inside critical section.

>  				acpi_lid_update_state(device, true);
> @@ -460,7 +460,7 @@ static int acpi_button_resume(struct device *dev)
>  
>  	button->suspended = false;
>  	mutex_lock(&input->mutex);
> -	if (button->type == ACPI_BUTTON_TYPE_LID && input->users) {
> +	if (button->type == ACPI_BUTTON_TYPE_LID && input_device_enabled(input)) {
>  		button->last_state = !!acpi_lid_evaluate_state(device);
>  		button->last_time = ktime_get();
>  		acpi_lid_initialize_state(device);
> -- 
> 2.17.1
> 

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-25  5:23             ` Dmitry Torokhov
@ 2020-06-25 10:55               ` Rafael J. Wysocki
  2020-10-05  5:08                 ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Rafael J. Wysocki @ 2020-06-25 10:55 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rafael J. Wysocki, Andrzej Pietrasiewicz, Linux PM,
	ACPI Devel Maling List, Linux Kernel Mailing List, linux-iio,
	Linux ARM, Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh,
	Collabora Kernel ML

On Thu, Jun 25, 2020 at 7:23 AM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> On Wed, Jun 24, 2020 at 05:00:09PM +0200, Rafael J. Wysocki wrote:
> > On Mon, Jun 8, 2020 at 1:22 PM Andrzej Pietrasiewicz
> > <andrzej.p@collabora.com> wrote:
> > >
> > > Inspecting input device's 'users' member should be done under device's
> > > mutex, so add appropriate invocations.
> > >
> > > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> >
> > This looks like a fix that might be applied independently of the other
> > patches in the series.
> >
> > Do you want me to pick it up?
>
> If you pick it we'll have to have a dance with this series. Can I apply
> instead?

Yes, please.

Also feel free to add

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

to it.

> I do not think this change has any practical effect as nobody
> attaches/detached input handlers or opening/closing input devices when
> system goes through device resume phase.

Indeed.

Thanks!

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

* Re: [PATCH v4 0/7] Support inhibiting input devices
  2020-06-12  8:17         ` Hans de Goede
@ 2020-08-03 14:40           ` Andrzej Pietrasiewicz
  0 siblings, 0 replies; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-08-03 14:40 UTC (permalink / raw)
  To: Hans de Goede, linux-pm, linux-acpi, linux-kernel, linux-iio,
	linux-arm-kernel, linux-samsung-soc, linux-input, linux-tegra,
	patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Ferruh Yigit, Sangwon Jee, Peter Hutterer,
	Henrique de Moraes Holschuh, kernel

Hi Dmitry,

W dniu 12.06.2020 o 10:17, Hans de Goede pisze:
> Hi,
> 
> On 6/8/20 1:22 PM, Andrzej Pietrasiewicz wrote:
>> This is a quick respin of v3, with just two small changes, please see
>> the changelog below.
>>
>> Userspace might want to implement a policy to temporarily disregard input
>> from certain devices.
>>

<snip>

>> v3..v4:
>> - updated the comment in input_open_device() (Hans)
>> - used more straightforward locking pattern in adc/exynos (Michał)
>>
>> v2..v3:
>> - ignored autorepeat events in input_get_disposition() if a key is not
>> pressed (Hans)
>> - dropped inhibit()/uninhibit() driver callbacks (Hans)
>> - split ACPI button patch into taking the lock and using the helper (Rafael)
>> - dropped the elan_i2c conversion
>> - fixed typos in exynos adc
>>
>> v1..v2:
>> - added input_device_enabled() helper and used it in drivers (Dmitry)
>> - the fact of open() and close() being called in inhibit/uninhibit paths has
>> been emphasized in the commit message of PATCH 6/7 (Dmitry)

<snip>

> 
> The entire series looks good to me:
> 
> Acked-by: Hans de Goede <hdegoede@redhat.com>

What are the prospects of this series being merged?

Regards,

Andrzej

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

* Re: [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper
  2020-06-25  5:24           ` Dmitry Torokhov
@ 2020-10-05  5:06             ` Dmitry Torokhov
  0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-10-05  5:06 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Wed, Jun 24, 2020 at 10:24:46PM -0700, Dmitry Torokhov wrote:
> On Mon, Jun 08, 2020 at 01:22:08PM +0200, Andrzej Pietrasiewicz wrote:
> > A new helper is available, so use it.
> > 
> > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> > ---
> >  drivers/acpi/button.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> > index ff7ab291f678..4deb2b48d03c 100644
> > --- a/drivers/acpi/button.c
> > +++ b/drivers/acpi/button.c
> > @@ -411,7 +411,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
> >  		input = button->input;
> >  		if (button->type == ACPI_BUTTON_TYPE_LID) {
> >  			mutex_lock(&button->input->mutex);
> > -			users = button->input->users;
> > +			users = input_device_enabled(button->input);
> >  			mutex_unlock(&button->input->mutex);
> >  			if (users)
> 
> This chunk (pre-patch) is really wrong. 'users' value is obsolete and
> can not be trusted the moment we unlocked the mutex. "if" needs to be
> inside critical section.

So looking at this patch and the previous one again, I believe this
driver is wrong to key the behavior off input->users and we should not
apply either of the patches. I'll post another patch fixing this.

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex
  2020-06-25 10:55               ` Rafael J. Wysocki
@ 2020-10-05  5:08                 ` Dmitry Torokhov
  0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-10-05  5:08 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Andrzej Pietrasiewicz, Linux PM, ACPI Devel Maling List,
	Linux Kernel Mailing List, linux-iio, Linux ARM,
	Linux Samsung SoC, linux-input, linux-tegra, patches,
	ibm-acpi-devel, Platform Driver, Rafael J . Wysocki, Len Brown,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh,
	Collabora Kernel ML

On Thu, Jun 25, 2020 at 12:55:29PM +0200, Rafael J. Wysocki wrote:
> On Thu, Jun 25, 2020 at 7:23 AM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > On Wed, Jun 24, 2020 at 05:00:09PM +0200, Rafael J. Wysocki wrote:
> > > On Mon, Jun 8, 2020 at 1:22 PM Andrzej Pietrasiewicz
> > > <andrzej.p@collabora.com> wrote:
> > > >
> > > > Inspecting input device's 'users' member should be done under device's
> > > > mutex, so add appropriate invocations.
> > > >
> > > > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> > >
> > > This looks like a fix that might be applied independently of the other
> > > patches in the series.
> > >
> > > Do you want me to pick it up?
> >
> > If you pick it we'll have to have a dance with this series. Can I apply
> > instead?
> 
> Yes, please.
> 
> Also feel free to add
> 
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> to it.

Looking at the driver I think the patch and the original use of
input->users is not proper. I'll post another patch addressing this
shortly.

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 7/7] Input: Add "inhibited" property
  2020-06-08 11:22         ` [PATCH v4 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
@ 2020-10-05 18:10           ` Dmitry Torokhov
  2020-10-06 13:04             ` Andrzej Pietrasiewicz
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-10-05 18:10 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Patrik Fimml

Hi Andrzej,

On Mon, Jun 08, 2020 at 01:22:11PM +0200, Andrzej Pietrasiewicz wrote:
> @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
>  	case EV_KEY:
>  		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
>  
> -			/* auto-repeat bypasses state updates */
> -			if (value == 2) {
> +			/*
> +			 * auto-repeat bypasses state updates but repeat
> +			 * events are ignored if the key is not pressed
> +			 */
> +			if (value == 2 && test_bit(code, dev->key)) {
>  				disposition = INPUT_PASS_TO_HANDLERS;
>  				break;
>  			}

Is this chunk really part of inhibit support? I'd think we cancel
autorepeat timer when we are releasing a key, no?

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 7/7] Input: Add "inhibited" property
  2020-10-05 18:10           ` Dmitry Torokhov
@ 2020-10-06 13:04             ` Andrzej Pietrasiewicz
  2020-10-07  1:11               ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-10-06 13:04 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Patrik Fimml

Hi Dmitry,

W dniu 05.10.2020 o 20:10, Dmitry Torokhov pisze:
> Hi Andrzej,
> 
> On Mon, Jun 08, 2020 at 01:22:11PM +0200, Andrzej Pietrasiewicz wrote:
>> @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
>>   	case EV_KEY:
>>   		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
>>   
>> -			/* auto-repeat bypasses state updates */
>> -			if (value == 2) {
>> +			/*
>> +			 * auto-repeat bypasses state updates but repeat
>> +			 * events are ignored if the key is not pressed
>> +			 */
>> +			if (value == 2 && test_bit(code, dev->key)) {
>>   				disposition = INPUT_PASS_TO_HANDLERS;
>>   				break;
>>   			}
> 
> Is this chunk really part of inhibit support? I'd think we cancel
> autorepeat timer when we are releasing a key, no?
> 

When I look at it now it seems to me the chunk might be redundant.
But let me explain what I had in mind when adding it.

It is a matter of what we do with input events generated while a
device is inhibited. If ->open()/->close() are not provided by the
driver then inhibiting amounts to merely ignoring input events from
a device while it remains active. What else can you do if the driver
does not provide a method to prepare the device for generating events/
to stop generating events?

In this special case a user might trigger a repeated event while the
device is inhibited, then the user keeps holding the key down and the
device is uninhibited. Do we pass anything to handlers then?

In my opinion we should not. Such an event is "illegal" in a sense that it
was generated at a time when nobody wanted any events from the device.
Hence the test to let only those auto-repeat events through for which
a key is actually pressed.

However, what I see now is that if a device is inhibited, no key
will ever reach neither the "1" nor "2" state because of the "if"
in the very beginning of input_handle_event().

Regards,

Andrzej

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

* Re: [PATCH v4 7/7] Input: Add "inhibited" property
  2020-10-06 13:04             ` Andrzej Pietrasiewicz
@ 2020-10-07  1:11               ` Dmitry Torokhov
  2020-10-07  1:12                 ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-10-07  1:11 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Patrik Fimml

On Tue, Oct 06, 2020 at 03:04:28PM +0200, Andrzej Pietrasiewicz wrote:
> Hi Dmitry,
> 
> W dniu 05.10.2020 o 20:10, Dmitry Torokhov pisze:
> > Hi Andrzej,
> > 
> > On Mon, Jun 08, 2020 at 01:22:11PM +0200, Andrzej Pietrasiewicz wrote:
> > > @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
> > >   	case EV_KEY:
> > >   		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
> > > -			/* auto-repeat bypasses state updates */
> > > -			if (value == 2) {
> > > +			/*
> > > +			 * auto-repeat bypasses state updates but repeat
> > > +			 * events are ignored if the key is not pressed
> > > +			 */
> > > +			if (value == 2 && test_bit(code, dev->key)) {
> > >   				disposition = INPUT_PASS_TO_HANDLERS;
> > >   				break;
> > >   			}
> > 
> > Is this chunk really part of inhibit support? I'd think we cancel
> > autorepeat timer when we are releasing a key, no?
> > 
> 
> When I look at it now it seems to me the chunk might be redundant.
> But let me explain what I had in mind when adding it.
> 
> It is a matter of what we do with input events generated while a
> device is inhibited. If ->open()/->close() are not provided by the
> driver then inhibiting amounts to merely ignoring input events from
> a device while it remains active. What else can you do if the driver
> does not provide a method to prepare the device for generating events/
> to stop generating events?
> 
> In this special case a user might trigger a repeated event while the
> device is inhibited, then the user keeps holding the key down and the
> device is uninhibited. Do we pass anything to handlers then?
> 
> In my opinion we should not. Such an event is "illegal" in a sense that it
> was generated at a time when nobody wanted any events from the device.
> Hence the test to let only those auto-repeat events through for which
> a key is actually pressed.
> 
> However, what I see now is that if a device is inhibited, no key
> will ever reach neither the "1" nor "2" state because of the "if"
> in the very beginning of input_handle_event().

OK, then let's drop it for now. We can revisit if we see that a problem.

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 7/7] Input: Add "inhibited" property
  2020-10-07  1:11               ` Dmitry Torokhov
@ 2020-10-07  1:12                 ` Dmitry Torokhov
  2020-12-03  6:26                   ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-10-07  1:12 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Patrik Fimml

On Tue, Oct 06, 2020 at 06:11:02PM -0700, Dmitry Torokhov wrote:
> On Tue, Oct 06, 2020 at 03:04:28PM +0200, Andrzej Pietrasiewicz wrote:
> > Hi Dmitry,
> > 
> > W dniu 05.10.2020 o 20:10, Dmitry Torokhov pisze:
> > > Hi Andrzej,
> > > 
> > > On Mon, Jun 08, 2020 at 01:22:11PM +0200, Andrzej Pietrasiewicz wrote:
> > > > @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
> > > >   	case EV_KEY:
> > > >   		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
> > > > -			/* auto-repeat bypasses state updates */
> > > > -			if (value == 2) {
> > > > +			/*
> > > > +			 * auto-repeat bypasses state updates but repeat
> > > > +			 * events are ignored if the key is not pressed
> > > > +			 */
> > > > +			if (value == 2 && test_bit(code, dev->key)) {
> > > >   				disposition = INPUT_PASS_TO_HANDLERS;
> > > >   				break;
> > > >   			}
> > > 
> > > Is this chunk really part of inhibit support? I'd think we cancel
> > > autorepeat timer when we are releasing a key, no?
> > > 
> > 
> > When I look at it now it seems to me the chunk might be redundant.
> > But let me explain what I had in mind when adding it.
> > 
> > It is a matter of what we do with input events generated while a
> > device is inhibited. If ->open()/->close() are not provided by the
> > driver then inhibiting amounts to merely ignoring input events from
> > a device while it remains active. What else can you do if the driver
> > does not provide a method to prepare the device for generating events/
> > to stop generating events?
> > 
> > In this special case a user might trigger a repeated event while the
> > device is inhibited, then the user keeps holding the key down and the
> > device is uninhibited. Do we pass anything to handlers then?
> > 
> > In my opinion we should not. Such an event is "illegal" in a sense that it
> > was generated at a time when nobody wanted any events from the device.
> > Hence the test to let only those auto-repeat events through for which
> > a key is actually pressed.
> > 
> > However, what I see now is that if a device is inhibited, no key
> > will ever reach neither the "1" nor "2" state because of the "if"
> > in the very beginning of input_handle_event().
> 
> OK, then let's drop it for now. We can revisit if we see that a problem.

And by that I mean that I will drop it myself, no need to resend. I will
be applying this shortly.

Thanks.

-- 
Dmitry

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

* Re: [PATCH v4 1/7] Input: add input_device_enabled()
  2020-06-08 11:22         ` [PATCH v4 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
@ 2020-12-03  6:25           ` Dmitry Torokhov
  0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-03  6:25 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Mon, Jun 08, 2020 at 01:22:05PM +0200, Andrzej Pietrasiewicz wrote:
> A helper function for drivers to decide if the device is used or not.
> A lockdep check is introduced as inspecting ->users should be done under
> input device's mutex.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>

Applied, thank you.

-- 
Dmitry

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

* Re: [PATCH v4 2/7] Input: use input_device_enabled()
  2020-06-08 11:22         ` [PATCH v4 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
@ 2020-12-03  6:26           ` Dmitry Torokhov
       [not found]           ` <CGME20201207133237eucas1p26f8484944760a14e51dc7353ed33cd28@eucas1p2.samsung.com>
  1 sibling, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-03  6:26 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel

On Mon, Jun 08, 2020 at 01:22:06PM +0200, Andrzej Pietrasiewicz wrote:
> Use the newly added helper in relevant input drivers.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>

Applied, thank you.

-- 
Dmitry

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

* Re: [PATCH v4 7/7] Input: Add "inhibited" property
  2020-10-07  1:12                 ` Dmitry Torokhov
@ 2020-12-03  6:26                   ` Dmitry Torokhov
  0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-03  6:26 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Ferruh Yigit,
	Sangwon Jee, Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Patrik Fimml

On Tue, Oct 06, 2020 at 06:12:49PM -0700, Dmitry Torokhov wrote:
> On Tue, Oct 06, 2020 at 06:11:02PM -0700, Dmitry Torokhov wrote:
> > On Tue, Oct 06, 2020 at 03:04:28PM +0200, Andrzej Pietrasiewicz wrote:
> > > Hi Dmitry,
> > > 
> > > W dniu 05.10.2020 o 20:10, Dmitry Torokhov pisze:
> > > > Hi Andrzej,
> > > > 
> > > > On Mon, Jun 08, 2020 at 01:22:11PM +0200, Andrzej Pietrasiewicz wrote:
> > > > > @@ -284,8 +284,11 @@ static int input_get_disposition(struct input_dev *dev,
> > > > >   	case EV_KEY:
> > > > >   		if (is_event_supported(code, dev->keybit, KEY_MAX)) {
> > > > > -			/* auto-repeat bypasses state updates */
> > > > > -			if (value == 2) {
> > > > > +			/*
> > > > > +			 * auto-repeat bypasses state updates but repeat
> > > > > +			 * events are ignored if the key is not pressed
> > > > > +			 */
> > > > > +			if (value == 2 && test_bit(code, dev->key)) {
> > > > >   				disposition = INPUT_PASS_TO_HANDLERS;
> > > > >   				break;
> > > > >   			}
> > > > 
> > > > Is this chunk really part of inhibit support? I'd think we cancel
> > > > autorepeat timer when we are releasing a key, no?
> > > > 
> > > 
> > > When I look at it now it seems to me the chunk might be redundant.
> > > But let me explain what I had in mind when adding it.
> > > 
> > > It is a matter of what we do with input events generated while a
> > > device is inhibited. If ->open()/->close() are not provided by the
> > > driver then inhibiting amounts to merely ignoring input events from
> > > a device while it remains active. What else can you do if the driver
> > > does not provide a method to prepare the device for generating events/
> > > to stop generating events?
> > > 
> > > In this special case a user might trigger a repeated event while the
> > > device is inhibited, then the user keeps holding the key down and the
> > > device is uninhibited. Do we pass anything to handlers then?
> > > 
> > > In my opinion we should not. Such an event is "illegal" in a sense that it
> > > was generated at a time when nobody wanted any events from the device.
> > > Hence the test to let only those auto-repeat events through for which
> > > a key is actually pressed.
> > > 
> > > However, what I see now is that if a device is inhibited, no key
> > > will ever reach neither the "1" nor "2" state because of the "if"
> > > in the very beginning of input_handle_event().
> > 
> > OK, then let's drop it for now. We can revisit if we see that a problem.
> 
> And by that I mean that I will drop it myself, no need to resend. I will
> be applying this shortly.

Well, "shortly" was just a tad optimistic, but I did apply it ;)

Thanks.

-- 
Dmitry

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

* Re: [PATCH v2] Input: document inhibiting
  2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
                                             ` (2 preceding siblings ...)
  2020-06-23 13:35                           ` Pavel Machek
@ 2020-12-03  6:27                           ` Dmitry Torokhov
  3 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-03  6:27 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz
  Cc: linux-pm, linux-acpi, linux-kernel, linux-iio, linux-arm-kernel,
	linux-samsung-soc, linux-input, linux-tegra, patches,
	ibm-acpi-devel, platform-driver-x86, Rafael J . Wysocki,
	Len Brown, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Kukjin Kim, Krzysztof Kozlowski,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Barry Song,
	Michael Hennerich, Nick Dyer, Hans de Goede, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh,
	Michał Mirosław, kernel

On Wed, Jun 17, 2020 at 12:18:22PM +0200, Andrzej Pietrasiewicz wrote:
> Document inhibiting input devices and its relation to being
> a wakeup source.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>

Applied, thank you.

-- 
Dmitry

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

* Re: [PATCH v4 2/7] Input: use input_device_enabled()
       [not found]           ` <CGME20201207133237eucas1p26f8484944760a14e51dc7353ed33cd28@eucas1p2.samsung.com>
@ 2020-12-07 13:32             ` Marek Szyprowski
  2020-12-07 15:50               ` Andrzej Pietrasiewicz
  0 siblings, 1 reply; 64+ messages in thread
From: Marek Szyprowski @ 2020-12-07 13:32 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

Hi Andrzej,

On 08.06.2020 13:22, Andrzej Pietrasiewicz wrote:
> Use the newly added helper in relevant input drivers.
>
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>

This patch landed recently in linux-next as commit d69f0a43c677 ("Input: 
use input_device_enabled()"). Sadly it causes following warning during 
system suspend/resume cycle on ARM 32bit Samsung Exynos5250-based Snow 
Chromebook with kernel compiled from exynos_defconfig:

------------[ cut here ]------------
WARNING: CPU: 0 PID: 1777 at drivers/input/input.c:2230 
input_device_enabled+0x68/0x6c
Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic 
libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc 
exynos_gsc v4l2_mem2mem videob
CPU: 0 PID: 1777 Comm: rtcwake Not tainted 
5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
[<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
[<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
[<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
[<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>] 
(input_device_enabled+0x68/0x6c)
[<c07fa2fc>] (input_device_enabled) from [<c080a0f8>] 
(cyapa_gen3_set_power_mode+0x128/0x1cc)
[<c080a0f8>] (cyapa_gen3_set_power_mode) from [<c0807894>] 
(cyapa_suspend+0x74/0x114)
[<c0807894>] (cyapa_suspend) from [<c06ae924>] (dpm_run_callback+0xb0/0x3c8)
[<c06ae924>] (dpm_run_callback) from [<c06aefe4>] 
(__device_suspend+0x104/0x784)
[<c06aefe4>] (__device_suspend) from [<c06b2994>] (dpm_suspend+0x184/0x540)
[<c06b2994>] (dpm_suspend) from [<c06b369c>] (dpm_suspend_start+0x98/0xa0)
[<c06b369c>] (dpm_suspend_start) from [<c01a0a10>] 
(suspend_devices_and_enter+0xec/0xbd4)
[<c01a0a10>] (suspend_devices_and_enter) from [<c01a180c>] 
(pm_suspend+0x314/0x42c)
[<c01a180c>] (pm_suspend) from [<c019f6f8>] (state_store+0x6c/0xc8)
[<c019f6f8>] (state_store) from [<c0387b04>] (kernfs_fop_write+0x10c/0x228)
[<c0387b04>] (kernfs_fop_write) from [<c02dbd48>] (vfs_write+0xc8/0x530)
[<c02dbd48>] (vfs_write) from [<c02dc2ec>] (ksys_write+0x60/0xd8)
[<c02dc2ec>] (ksys_write) from [<c0100060>] (ret_fast_syscall+0x0/0x2c)
Exception stack(0xc45bffa8 to 0xc45bfff0)
...
irq event stamp: 14101
hardirqs last  enabled at (14109): [<c01a567c>] vprintk_emit+0x2d8/0x32c
hardirqs last disabled at (14116): [<c01a5640>] vprintk_emit+0x29c/0x32c
softirqs last  enabled at (13264): [<c01017a8>] __do_softirq+0x528/0x684
softirqs last disabled at (13253): [<c01304c4>] irq_exit+0x1ec/0x1f8
---[ end trace 6687a21e6b7e94a9 ]---
------------[ cut here ]------------
WARNING: CPU: 1 PID: 1777 at drivers/input/input.c:2230 
input_device_enabled+0x68/0x6c
Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic 
libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc 
exynos_gsc v4l2_mem2mem videob
CPU: 1 PID: 1777 Comm: rtcwake Tainted: G        W 
5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
[<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
[<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
[<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
[<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>] 
(input_device_enabled+0x68/0x6c)
[<c07fa2fc>] (input_device_enabled) from [<c080a0f8>] 
(cyapa_gen3_set_power_mode+0x128/0x1cc)
[<c080a0f8>] (cyapa_gen3_set_power_mode) from [<c08088b4>] 
(cyapa_reinitialize+0xcc/0x154)
[<c08088b4>] (cyapa_reinitialize) from [<c0808984>] (cyapa_resume+0x48/0x98)
[<c0808984>] (cyapa_resume) from [<c06ae924>] (dpm_run_callback+0xb0/0x3c8)
[<c06ae924>] (dpm_run_callback) from [<c06aecf8>] (device_resume+0xbc/0x260)
[<c06aecf8>] (device_resume) from [<c06b10d8>] (dpm_resume+0x14c/0x51c)
[<c06b10d8>] (dpm_resume) from [<c06b1cac>] (dpm_resume_end+0xc/0x18)
[<c06b1cac>] (dpm_resume_end) from [<c01a0ad8>] 
(suspend_devices_and_enter+0x1b4/0xbd4)
[<c01a0ad8>] (suspend_devices_and_enter) from [<c01a180c>] 
(pm_suspend+0x314/0x42c)
[<c01a180c>] (pm_suspend) from [<c019f6f8>] (state_store+0x6c/0xc8)
[<c019f6f8>] (state_store) from [<c0387b04>] (kernfs_fop_write+0x10c/0x228)
[<c0387b04>] (kernfs_fop_write) from [<c02dbd48>] (vfs_write+0xc8/0x530)
[<c02dbd48>] (vfs_write) from [<c02dc2ec>] (ksys_write+0x60/0xd8)
[<c02dc2ec>] (ksys_write) from [<c0100060>] (ret_fast_syscall+0x0/0x2c)
Exception stack(0xc45bffa8 to 0xc45bfff0)
...
irq event stamp: 55479
hardirqs last  enabled at (55487): [<c01a567c>] vprintk_emit+0x2d8/0x32c
hardirqs last disabled at (55494): [<c01a5640>] vprintk_emit+0x29c/0x32c
softirqs last  enabled at (53552): [<c01017a8>] __do_softirq+0x528/0x684
softirqs last disabled at (53541): [<c01304c4>] irq_exit+0x1ec/0x1f8
---[ end trace 6687a21e6b7e94aa ]---
------------[ cut here ]------------
WARNING: CPU: 1 PID: 1777 at drivers/input/input.c:2230 
input_device_enabled+0x68/0x6c
Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic 
libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc 
exynos_gsc v4l2_mem2mem videob
CPU: 1 PID: 1777 Comm: rtcwake Tainted: G        W 
5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
[<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
[<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
[<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
[<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>] 
(input_device_enabled+0x68/0x6c)
[<c07fa2fc>] (input_device_enabled) from [<c0808834>] 
(cyapa_reinitialize+0x4c/0x154)
[<c0808834>] (cyapa_reinitialize) from [<c0808984>] (cyapa_resume+0x48/0x98)
[<c0808984>] (cyapa_resume) from [<c06ae924>] (dpm_run_callback+0xb0/0x3c8)
[<c06ae924>] (dpm_run_callback) from [<c06aecf8>] (device_resume+0xbc/0x260)
[<c06aecf8>] (device_resume) from [<c06b10d8>] (dpm_resume+0x14c/0x51c)
[<c06b10d8>] (dpm_resume) from [<c06b1cac>] (dpm_resume_end+0xc/0x18)
[<c06b1cac>] (dpm_resume_end) from [<c01a0ad8>] 
(suspend_devices_and_enter+0x1b4/0xbd4)
[<c01a0ad8>] (suspend_devices_and_enter) from [<c01a180c>] 
(pm_suspend+0x314/0x42c)
[<c01a180c>] (pm_suspend) from [<c019f6f8>] (state_store+0x6c/0xc8)
[<c019f6f8>] (state_store) from [<c0387b04>] (kernfs_fop_write+0x10c/0x228)
[<c0387b04>] (kernfs_fop_write) from [<c02dbd48>] (vfs_write+0xc8/0x530)
[<c02dbd48>] (vfs_write) from [<c02dc2ec>] (ksys_write+0x60/0xd8)
[<c02dc2ec>] (ksys_write) from [<c0100060>] (ret_fast_syscall+0x0/0x2c)
Exception stack(0xc45bffa8 to 0xc45bfff0)
...
irq event stamp: 55829
hardirqs last  enabled at (55837): [<c01a567c>] vprintk_emit+0x2d8/0x32c
hardirqs last disabled at (55844): [<c01a5640>] vprintk_emit+0x29c/0x32c
softirqs last  enabled at (53552): [<c01017a8>] __do_softirq+0x528/0x684
softirqs last disabled at (53541): [<c01304c4>] irq_exit+0x1ec/0x1f8
---[ end trace 6687a21e6b7e94ab ]---
------------[ cut here ]------------
WARNING: CPU: 1 PID: 1777 at drivers/input/input.c:2230 
input_device_enabled+0x68/0x6c
Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic 
libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc 
exynos_gsc v4l2_mem2mem videob
CPU: 1 PID: 1777 Comm: rtcwake Tainted: G        W 
5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
[<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
[<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
[<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
[<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>] 
(input_device_enabled+0x68/0x6c)
[<c07fa2fc>] (input_device_enabled) from [<c080a0f8>] 
(cyapa_gen3_set_power_mode+0x128/0x1cc)
[<c080a0f8>] (cyapa_gen3_set_power_mode) from [<c0808890>] 
(cyapa_reinitialize+0xa8/0x154)
[<c0808890>] (cyapa_reinitialize) from [<c0808984>] (cyapa_resume+0x48/0x98)
[<c0808984>] (cyapa_resume) from [<c06ae924>] (dpm_run_callback+0xb0/0x3c8)
[<c06ae924>] (dpm_run_callback) from [<c06aecf8>] (device_resume+0xbc/0x260)
[<c06aecf8>] (device_resume) from [<c06b10d8>] (dpm_resume+0x14c/0x51c)
[<c06b10d8>] (dpm_resume) from [<c06b1cac>] (dpm_resume_end+0xc/0x18)
[<c06b1cac>] (dpm_resume_end) from [<c01a0ad8>] 
(suspend_devices_and_enter+0x1b4/0xbd4)
[<c01a0ad8>] (suspend_devices_and_enter) from [<c01a180c>] 
(pm_suspend+0x314/0x42c)
[<c01a180c>] (pm_suspend) from [<c019f6f8>] (state_store+0x6c/0xc8)
[<c019f6f8>] (state_store) from [<c0387b04>] (kernfs_fop_write+0x10c/0x228)
[<c0387b04>] (kernfs_fop_write) from [<c02dbd48>] (vfs_write+0xc8/0x530)
[<c02dbd48>] (vfs_write) from [<c02dc2ec>] (ksys_write+0x60/0xd8)
[<c02dc2ec>] (ksys_write) from [<c0100060>] (ret_fast_syscall+0x0/0x2c)
Exception stack(0xc45bffa8 to 0xc45bfff0)
...
irq event stamp: 56143
hardirqs last  enabled at (56151): [<c01a567c>] vprintk_emit+0x2d8/0x32c
hardirqs last disabled at (56158): [<c01a5640>] vprintk_emit+0x29c/0x32c
softirqs last  enabled at (53552): [<c01017a8>] __do_softirq+0x528/0x684
softirqs last disabled at (53541): [<c01304c4>] irq_exit+0x1ec/0x1f8
---[ end trace 6687a21e6b7e94ac ]---

Let me know how I can help debugging this issue.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH v4 2/7] Input: use input_device_enabled()
  2020-12-07 13:32             ` Marek Szyprowski
@ 2020-12-07 15:50               ` Andrzej Pietrasiewicz
  2020-12-08 10:05                 ` Marek Szyprowski
  0 siblings, 1 reply; 64+ messages in thread
From: Andrzej Pietrasiewicz @ 2020-12-07 15:50 UTC (permalink / raw)
  To: Marek Szyprowski, linux-pm, linux-acpi, linux-kernel, linux-iio,
	linux-arm-kernel, linux-samsung-soc, linux-input, linux-tegra,
	patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

Hi Marek,

W dniu 07.12.2020 o 14:32, Marek Szyprowski pisze:
> Hi Andrzej,
> 
> On 08.06.2020 13:22, Andrzej Pietrasiewicz wrote:
>> Use the newly added helper in relevant input drivers.
>>
>> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> 
> This patch landed recently in linux-next as commit d69f0a43c677 ("Input:
> use input_device_enabled()"). Sadly it causes following warning during
> system suspend/resume cycle on ARM 32bit Samsung Exynos5250-based Snow
> Chromebook with kernel compiled from exynos_defconfig:
> 
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 1777 at drivers/input/input.c:2230
> input_device_enabled+0x68/0x6c
> Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic
> libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc
> exynos_gsc v4l2_mem2mem videob
> CPU: 0 PID: 1777 Comm: rtcwake Not tainted
> 5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
> Hardware name: Samsung Exynos (Flattened Device Tree)
> [<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
> [<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
> [<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
> [<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
> [<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>]
> (input_device_enabled+0x68/0x6c)
> [<c07fa2fc>] (input_device_enabled) from [<c080a0f8>]

Apparently you are hitting this line of code in drivers/input/input.c:

lockdep_assert_held(&dev->mutex);

Inspecting input device's "users" member should happen under dev's lock.

Regards,

Andrzej

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

* Re: [PATCH v4 2/7] Input: use input_device_enabled()
  2020-12-07 15:50               ` Andrzej Pietrasiewicz
@ 2020-12-08 10:05                 ` Marek Szyprowski
  2020-12-09  6:37                   ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Marek Szyprowski @ 2020-12-08 10:05 UTC (permalink / raw)
  To: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86
  Cc: Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

Hi Andrzej,

On 07.12.2020 16:50, Andrzej Pietrasiewicz wrote:
> Hi Marek,
>
> W dniu 07.12.2020 o 14:32, Marek Szyprowski pisze:
>> Hi Andrzej,
>>
>> On 08.06.2020 13:22, Andrzej Pietrasiewicz wrote:
>>> Use the newly added helper in relevant input drivers.
>>>
>>> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
>>
>> This patch landed recently in linux-next as commit d69f0a43c677 ("Input:
>> use input_device_enabled()"). Sadly it causes following warning during
>> system suspend/resume cycle on ARM 32bit Samsung Exynos5250-based Snow
>> Chromebook with kernel compiled from exynos_defconfig:
>>
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 1777 at drivers/input/input.c:2230
>> input_device_enabled+0x68/0x6c
>> Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic
>> libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc
>> exynos_gsc v4l2_mem2mem videob
>> CPU: 0 PID: 1777 Comm: rtcwake Not tainted
>> 5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
>> Hardware name: Samsung Exynos (Flattened Device Tree)
>> [<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
>> [<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
>> [<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
>> [<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
>> [<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>]
>> (input_device_enabled+0x68/0x6c)
>> [<c07fa2fc>] (input_device_enabled) from [<c080a0f8>]
>
> Apparently you are hitting this line of code in drivers/input/input.c:
>
> lockdep_assert_held(&dev->mutex);
>
> Inspecting input device's "users" member should happen under dev's lock.
>
This check and warning has been introduced by this patch. I assume that 
the suspend/resume paths are correct, but it looks that they were not 
tested with this patch thus it has not been noticed that they are not 
called under the input's lock. This needs a fix. Dmitry: how would you 
like to handle this issue?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH v4 2/7] Input: use input_device_enabled()
  2020-12-08 10:05                 ` Marek Szyprowski
@ 2020-12-09  6:37                   ` Dmitry Torokhov
  2020-12-11  7:09                     ` [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-09  6:37 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

On Tue, Dec 08, 2020 at 11:05:42AM +0100, Marek Szyprowski wrote:
> Hi Andrzej,
> 
> On 07.12.2020 16:50, Andrzej Pietrasiewicz wrote:
> > Hi Marek,
> >
> > W dniu 07.12.2020 o 14:32, Marek Szyprowski pisze:
> >> Hi Andrzej,
> >>
> >> On 08.06.2020 13:22, Andrzej Pietrasiewicz wrote:
> >>> Use the newly added helper in relevant input drivers.
> >>>
> >>> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> >>
> >> This patch landed recently in linux-next as commit d69f0a43c677 ("Input:
> >> use input_device_enabled()"). Sadly it causes following warning during
> >> system suspend/resume cycle on ARM 32bit Samsung Exynos5250-based Snow
> >> Chromebook with kernel compiled from exynos_defconfig:
> >>
> >> ------------[ cut here ]------------
> >> WARNING: CPU: 0 PID: 1777 at drivers/input/input.c:2230
> >> input_device_enabled+0x68/0x6c
> >> Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic
> >> libsha256 sha256_arm cfg80211 btmrvl_sdio btmrvl bluetooth s5p_mfc
> >> exynos_gsc v4l2_mem2mem videob
> >> CPU: 0 PID: 1777 Comm: rtcwake Not tainted
> >> 5.10.0-rc6-next-20201207-00001-g49a0dc04c46d-dirty #9902
> >> Hardware name: Samsung Exynos (Flattened Device Tree)
> >> [<c0111718>] (unwind_backtrace) from [<c010d050>] (show_stack+0x10/0x14)
> >> [<c010d050>] (show_stack) from [<c0b32810>] (dump_stack+0xb4/0xd4)
> >> [<c0b32810>] (dump_stack) from [<c0126e24>] (__warn+0xd8/0x11c)
> >> [<c0126e24>] (__warn) from [<c0126f18>] (warn_slowpath_fmt+0xb0/0xb8)
> >> [<c0126f18>] (warn_slowpath_fmt) from [<c07fa2fc>]
> >> (input_device_enabled+0x68/0x6c)
> >> [<c07fa2fc>] (input_device_enabled) from [<c080a0f8>]
> >
> > Apparently you are hitting this line of code in drivers/input/input.c:
> >
> > lockdep_assert_held(&dev->mutex);
> >
> > Inspecting input device's "users" member should happen under dev's lock.
> >
> This check and warning has been introduced by this patch. I assume that 
> the suspend/resume paths are correct, but it looks that they were not 
> tested with this patch thus it has not been noticed that they are not 
> called under the input's lock. This needs a fix. Dmitry: how would you 
> like to handle this issue?

The check is proper and the warning is legit, cyapa should not be
checking this field without holding the lock. I think we can simply
remove this check from the power ops for gen3 and gen5, and this should
shut up the warning on suspend, but there other places in cyapa that do
check 'users', and they also need to be fixed.

Thanks.

-- 
Dmitry

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

* [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler
  2020-12-09  6:37                   ` Dmitry Torokhov
@ 2020-12-11  7:09                     ` Dmitry Torokhov
  2020-12-11  8:22                       ` Marek Szyprowski
  0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-11  7:09 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

Input device's user counter is supposed to be accessed only while holding
input->mutex.  Commit d69f0a43c677 ("Input: use input_device_enabled()")
recently switched cyapa to using the dedicated API and it uncovered the
fact that cyapa driver violated this constraint.

This patch removes checks whether the input device is open when clearing
device queues when changing device's power mode as there is no harm in
sending input events through closed input device - the events will simply
be dropped by the input core.

Note that there are more places in cyapa driver that call
input_device_enabled() without holding input->mutex, those are left
unfixed for now.

Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

Marek, could you please try this one?

 drivers/input/mouse/cyapa_gen3.c |    5 +----
 drivers/input/mouse/cyapa_gen5.c |    3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
index a97f4acb6452..4a9022faf945 100644
--- a/drivers/input/mouse/cyapa_gen3.c
+++ b/drivers/input/mouse/cyapa_gen3.c
@@ -907,7 +907,6 @@ static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode)
 static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
 		u16 always_unused, enum cyapa_pm_stage pm_stage)
 {
-	struct input_dev *input = cyapa->input;
 	u8 power;
 	int tries;
 	int sleep_time;
@@ -953,7 +952,6 @@ static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
 	 * depending on the command's content.
 	 */
 	if (cyapa->operational &&
-	    input && input_device_enabled(input) &&
 	    (pm_stage == CYAPA_PM_RUNTIME_SUSPEND ||
 	     pm_stage == CYAPA_PM_RUNTIME_RESUME)) {
 		/* Try to polling in 120Hz, read may fail, just ignore it. */
@@ -1223,8 +1221,7 @@ static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa)
 	    (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID)
 		return -EINVAL;
 
-	return cyapa_gen3_event_process(cyapa, &data);
-
+	return cyapa->input ? cyapa_gen3_event_process(cyapa, &data) : 0;
 }
 
 static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; }
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
index abf42f77b4c5..afc5aa4dcf47 100644
--- a/drivers/input/mouse/cyapa_gen5.c
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -518,8 +518,7 @@ int cyapa_empty_pip_output_data(struct cyapa *cyapa,
 			*len = length;
 			/* Response found, success. */
 			return 0;
-		} else if (cyapa->operational &&
-			   input && input_device_enabled(input) &&
+		} else if (cyapa->operational && input &&
 			   (pm_stage == CYAPA_PM_RUNTIME_RESUME ||
 			    pm_stage == CYAPA_PM_RUNTIME_SUSPEND)) {
 			/* Parse the data and report it if it's valid. */

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

* Re: [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler
  2020-12-11  7:09                     ` [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler Dmitry Torokhov
@ 2020-12-11  8:22                       ` Marek Szyprowski
  2020-12-11  8:31                         ` Dmitry Torokhov
  0 siblings, 1 reply; 64+ messages in thread
From: Marek Szyprowski @ 2020-12-11  8:22 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz


On 11.12.2020 08:09, Dmitry Torokhov wrote:
> Input device's user counter is supposed to be accessed only while holding
> input->mutex.  Commit d69f0a43c677 ("Input: use input_device_enabled()")
> recently switched cyapa to using the dedicated API and it uncovered the
> fact that cyapa driver violated this constraint.
>
> This patch removes checks whether the input device is open when clearing
> device queues when changing device's power mode as there is no harm in
> sending input events through closed input device - the events will simply
> be dropped by the input core.
>
> Note that there are more places in cyapa driver that call
> input_device_enabled() without holding input->mutex, those are left
> unfixed for now.
>
> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>
> Marek, could you please try this one?

The warning is still there:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 1787 at drivers/input/input.c:2230 
input_device_enabled+0x68/0x6c
Modules linked in: cmac bnep mwifiex_sdio mwifiex sha256_generic 
libsha256 sha256_arm btmrvl_sdio btmrvl cfg80211 bluetooth s5p_mfc 
exynos_gsc v4l2_mem2mem videob
CPU: 1 PID: 1787 Comm: rtcwake Not tainted 
5.10.0-rc7-next-20201210-00001-g70a81f43fddf #2204
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111a58>] (unwind_backtrace) from [<c010d390>] (show_stack+0x10/0x14)
[<c010d390>] (show_stack) from [<c0b3503c>] (dump_stack+0xb4/0xd4)
[<c0b3503c>] (dump_stack) from [<c0127428>] (__warn+0xd8/0x11c)
[<c0127428>] (__warn) from [<c012751c>] (warn_slowpath_fmt+0xb0/0xb8)
[<c012751c>] (warn_slowpath_fmt) from [<c07fbccc>] 
(input_device_enabled+0x68/0x6c)
[<c07fbccc>] (input_device_enabled) from [<c080a204>] 
(cyapa_reinitialize+0x4c/0x154)
[<c080a204>] (cyapa_reinitialize) from [<c080a354>] (cyapa_resume+0x48/0x98)
[<c080a354>] (cyapa_resume) from [<c06b0230>] (dpm_run_callback+0xb0/0x3c8)
[<c06b0230>] (dpm_run_callback) from [<c06b0604>] (device_resume+0xbc/0x260)
[<c06b0604>] (device_resume) from [<c06b29e4>] (dpm_resume+0x14c/0x51c)
[<c06b29e4>] (dpm_resume) from [<c06b35b8>] (dpm_resume_end+0xc/0x18)
[<c06b35b8>] (dpm_resume_end) from [<c01a1270>] 
(suspend_devices_and_enter+0x1b4/0xbd4)
[<c01a1270>] (suspend_devices_and_enter) from [<c01a1fa4>] 
(pm_suspend+0x314/0x42c)
[<c01a1fa4>] (pm_suspend) from [<c019fe90>] (state_store+0x6c/0xc8)
[<c019fe90>] (state_store) from [<c0388438>] (kernfs_fop_write+0x10c/0x228)
[<c0388438>] (kernfs_fop_write) from [<c02dc3e8>] (vfs_write+0xc8/0x530)
[<c02dc3e8>] (vfs_write) from [<c02dc98c>] (ksys_write+0x60/0xd8)
[<c02dc98c>] (ksys_write) from [<c0100060>] (ret_fast_syscall+0x0/0x2c)
Exception stack(0xc3923fa8 to 0xc3923ff0)
irq event stamp: 54139
hardirqs last  enabled at (54147): [<c01a5f20>] vprintk_emit+0x2b8/0x308
hardirqs last disabled at (54154): [<c01a5ee4>] vprintk_emit+0x27c/0x308
softirqs last  enabled at (50722): [<c01017a8>] __do_softirq+0x528/0x684
softirqs last disabled at (50671): [<c0130ac8>] irq_exit+0x1ec/0x1f8
---[ end trace 1fbefe3f239ae597 ]---

>   drivers/input/mouse/cyapa_gen3.c |    5 +----
>   drivers/input/mouse/cyapa_gen5.c |    3 +--
>   2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
> index a97f4acb6452..4a9022faf945 100644
> --- a/drivers/input/mouse/cyapa_gen3.c
> +++ b/drivers/input/mouse/cyapa_gen3.c
> @@ -907,7 +907,6 @@ static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode)
>   static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
>   		u16 always_unused, enum cyapa_pm_stage pm_stage)
>   {
> -	struct input_dev *input = cyapa->input;
>   	u8 power;
>   	int tries;
>   	int sleep_time;
> @@ -953,7 +952,6 @@ static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
>   	 * depending on the command's content.
>   	 */
>   	if (cyapa->operational &&
> -	    input && input_device_enabled(input) &&
>   	    (pm_stage == CYAPA_PM_RUNTIME_SUSPEND ||
>   	     pm_stage == CYAPA_PM_RUNTIME_RESUME)) {
>   		/* Try to polling in 120Hz, read may fail, just ignore it. */
> @@ -1223,8 +1221,7 @@ static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa)
>   	    (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID)
>   		return -EINVAL;
>   
> -	return cyapa_gen3_event_process(cyapa, &data);
> -
> +	return cyapa->input ? cyapa_gen3_event_process(cyapa, &data) : 0;
>   }
>   
>   static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; }
> diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
> index abf42f77b4c5..afc5aa4dcf47 100644
> --- a/drivers/input/mouse/cyapa_gen5.c
> +++ b/drivers/input/mouse/cyapa_gen5.c
> @@ -518,8 +518,7 @@ int cyapa_empty_pip_output_data(struct cyapa *cyapa,
>   			*len = length;
>   			/* Response found, success. */
>   			return 0;
> -		} else if (cyapa->operational &&
> -			   input && input_device_enabled(input) &&
> +		} else if (cyapa->operational && input &&
>   			   (pm_stage == CYAPA_PM_RUNTIME_RESUME ||
>   			    pm_stage == CYAPA_PM_RUNTIME_SUSPEND)) {
>   			/* Parse the data and report it if it's valid. */
>
Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler
  2020-12-11  8:22                       ` Marek Szyprowski
@ 2020-12-11  8:31                         ` Dmitry Torokhov
  0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Torokhov @ 2020-12-11  8:31 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Andrzej Pietrasiewicz, linux-pm, linux-acpi, linux-kernel,
	linux-iio, linux-arm-kernel, linux-samsung-soc, linux-input,
	linux-tegra, patches, ibm-acpi-devel, platform-driver-x86,
	Rafael J . Wysocki, Len Brown, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Kukjin Kim,
	Krzysztof Kozlowski, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Barry Song, Michael Hennerich,
	Nick Dyer, Hans de Goede, Ferruh Yigit, Sangwon Jee,
	Peter Hutterer, Henrique de Moraes Holschuh, kernel,
	Bartlomiej Zolnierkiewicz

On Fri, Dec 11, 2020 at 09:22:44AM +0100, Marek Szyprowski wrote:
> 
> On 11.12.2020 08:09, Dmitry Torokhov wrote:
> > Input device's user counter is supposed to be accessed only while holding
> > input->mutex.  Commit d69f0a43c677 ("Input: use input_device_enabled()")
> > recently switched cyapa to using the dedicated API and it uncovered the
> > fact that cyapa driver violated this constraint.
> >
> > This patch removes checks whether the input device is open when clearing
> > device queues when changing device's power mode as there is no harm in
> > sending input events through closed input device - the events will simply
> > be dropped by the input core.
> >
> > Note that there are more places in cyapa driver that call
> > input_device_enabled() without holding input->mutex, those are left
> > unfixed for now.
> >
> > Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > ---
> >
> > Marek, could you please try this one?
> 
> The warning is still there:

Ah, yes, we are hitting another instance right after setting power mode.
I need to think more how to handle that one.

Thanks.

-- 
Dmitry

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

end of thread, other threads:[~2020-12-11  8:34 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20200604072853.GP89269@dtor-ws>
2020-06-05 17:33 ` [PATCH v3 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
2020-06-05 19:49     ` Michał Mirosław
2020-06-05 17:33   ` [PATCH v3 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
2020-06-05 17:33   ` [PATCH v3 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
2020-06-05 17:41     ` Hans de Goede
2020-06-08 11:22       ` [PATCH v4 0/7] Support inhibiting input devices Andrzej Pietrasiewicz
2020-06-08 11:22         ` [PATCH v4 1/7] Input: add input_device_enabled() Andrzej Pietrasiewicz
2020-12-03  6:25           ` Dmitry Torokhov
2020-06-08 11:22         ` [PATCH v4 2/7] Input: use input_device_enabled() Andrzej Pietrasiewicz
2020-12-03  6:26           ` Dmitry Torokhov
     [not found]           ` <CGME20201207133237eucas1p26f8484944760a14e51dc7353ed33cd28@eucas1p2.samsung.com>
2020-12-07 13:32             ` Marek Szyprowski
2020-12-07 15:50               ` Andrzej Pietrasiewicz
2020-12-08 10:05                 ` Marek Szyprowski
2020-12-09  6:37                   ` Dmitry Torokhov
2020-12-11  7:09                     ` [PATCH] Input: cyapa - do not call input_device_enabled from power mode handler Dmitry Torokhov
2020-12-11  8:22                       ` Marek Szyprowski
2020-12-11  8:31                         ` Dmitry Torokhov
2020-06-08 11:22         ` [PATCH v4 3/7] ACPI: button: Access input device's users under appropriate mutex Andrzej Pietrasiewicz
2020-06-24 15:00           ` Rafael J. Wysocki
2020-06-25  5:23             ` Dmitry Torokhov
2020-06-25 10:55               ` Rafael J. Wysocki
2020-10-05  5:08                 ` Dmitry Torokhov
2020-06-08 11:22         ` [PATCH v4 4/7] ACPI: button: Use input_device_enabled() helper Andrzej Pietrasiewicz
2020-06-25  5:24           ` Dmitry Torokhov
2020-10-05  5:06             ` Dmitry Torokhov
2020-06-08 11:22         ` [PATCH v4 5/7] iio: adc: exynos: Use input_device_enabled() Andrzej Pietrasiewicz
2020-06-10  1:28           ` Michał Mirosław
2020-06-10  7:52             ` [FIXED PATCH " Andrzej Pietrasiewicz
2020-06-08 11:22         ` [PATCH v4 6/7] platform/x86: thinkpad_acpi: " Andrzej Pietrasiewicz
2020-06-08 11:22         ` [PATCH v4 7/7] Input: Add "inhibited" property Andrzej Pietrasiewicz
2020-10-05 18:10           ` Dmitry Torokhov
2020-10-06 13:04             ` Andrzej Pietrasiewicz
2020-10-07  1:11               ` Dmitry Torokhov
2020-10-07  1:12                 ` Dmitry Torokhov
2020-12-03  6:26                   ` Dmitry Torokhov
2020-06-10  9:49         ` [PATCH v4 0/7] Support inhibiting input devices Hans de Goede
2020-06-10 10:38           ` Rafael J. Wysocki
2020-06-10 13:12             ` Andrzej Pietrasiewicz
2020-06-10 13:21               ` Hans de Goede
2020-06-10 13:41                 ` Andrzej Pietrasiewicz
2020-06-12  8:30                   ` Hans de Goede
2020-06-12  8:47                     ` Andrzej Pietrasiewicz
2020-06-16 17:29                     ` [PATCH] Input: document inhibiting Andrzej Pietrasiewicz
2020-06-16 17:38                       ` Randy Dunlap
2020-06-17  7:44                       ` Hans de Goede
2020-06-17 10:18                         ` [PATCH v2] " Andrzej Pietrasiewicz
2020-06-17 10:21                           ` Hans de Goede
2020-06-17 16:52                           ` Randy Dunlap
2020-06-23 13:35                           ` Pavel Machek
2020-12-03  6:27                           ` Dmitry Torokhov
2020-06-10 14:01                 ` [PATCH v4 0/7] Support inhibiting input devices Rafael J. Wysocki
2020-06-10 13:52             ` Hans de Goede
2020-06-10 18:28             ` Dmitry Torokhov
2020-06-12  8:14               ` Hans de Goede
2020-06-12  8:17         ` Hans de Goede
2020-08-03 14:40           ` Andrzej Pietrasiewicz
2020-06-07 20:24   ` [PATCH v3 " Pavel Machek
2020-06-08  5:37     ` Dmitry Torokhov
2020-06-08  9:28       ` Andrzej Pietrasiewicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).