All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq
@ 2022-08-30 23:15 Raul E Rangel
  2022-08-30 23:15 ` [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage " Raul E Rangel
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Alistair Francis, Andy Shevchenko, Angela Czubak,
	Bartosz Golaszewski, Bartosz Szczepanek, Benjamin Tissoires,
	Dmitry Torokhov, Jiri Kosina, Len Brown, Linus Walleij,
	Matthias Kaehlcke, Mika Westerberg, Rob Herring, Wolfram Sang,
	Yang Li, jingle.wu, linux-gpio, linux-i2c, linux-kernel

Today, i2c drivers are making the assumption that their IRQs can also
be used as wake IRQs. This isn't always the case and it can lead to
spurious wakes. This has recently started to affect AMD Chromebooks.
With the introduction of
d62bd5ce12d7 ("pinctrl: amd: Implement irq_set_wake"), the AMD GPIO
controller gained the capability to set the wake bit on each GPIO. The
ACPI specification defines two ways to inform the system if a device is
wake capable:
1) The _PRW object defines the GPE that can be used to wake the system.
2) Setting ExclusiveAndWake or SharedAndWake in the _CRS GpioInt.

Currently only the first method is supported. The i2c drivers don't have
any indication that the IRQ is wake capable, so they guess. This causes
spurious interrupts, for example:
* We have an ACPI HID device that has `_PR0` and `_PR3`. It doesn't have
  `_PRW` or `ExclusiveAndWake` so that means the device can't wake the
  system.
* The IRQ line is active level low for this device and is pulled up by
  the power resource defined in `_PR0`/`_PR3`.
* The i2c driver will (incorrectly) arm the GPIO for wake by calling
  `enable_irq_wake` as part of its suspend hook.
* ACPI will power down the device since it doesn't have a wake GPE
  associated with it.
* When the device is powered down, the IRQ line will drop, and it will
  trigger a wake event.

See the following debug log:
[   42.335804] PM: Suspending system (s2idle)
[   42.340186] amd_gpio AMD0030:00: RX: Setting wake for pin 89 to enable
[   42.467736]     power-0416 __acpi_power_off      : Power resource [PR00] turned off
[   42.467739] device_pm-0280 device_set_power      : Device [H05D] transitioned to D3cold
[   42.475210] PM: pm_system_irq_wakeup: 11 triggered pinctrl_amd
[   42.535293] PM: Wakeup unrelated to ACPI SCI
[   42.535294] PM: resume from suspend-to-idle

In order to fix this, we need to take into account the wake capable bit
defined on the GpioInt. This is accomplished by:
* Migrating some of the i2c drivers over to using the PM subsystem to
  manage the wake IRQ. max8925-i2c, elants_i2c, and raydium_i2c_ts still
  need to be migrated, I can do that depending on the feedback to this
  patch series.
* Expose the wake_capable bit from the ACPI GpioInt resource to the
  i2c core.
* Use the wake_capable bit in the i2c core to call
  `dev_pm_set_wake_irq`. This reuses the existing device tree flow.
* Make the i2c drivers stop calling `dev_pm_set_wake_irq` since it's now
  handled by the i2c core.
* Make the ACPI device PM system aware of the wake_irq. This is
  necessary so the device doesn't incorrectly get powered down when a
  wake_irq is enabled.

I've tested this code with various combinations of having _PRW,
ExclusiveAndWake and power resources all defined or not defined, but it
would be great if others could test this out on their hardware.

Thanks,
Raul


Raul E Rangel (8):
  Input: elan_i2c - Use PM subsystem to manage wake irq
  HID: i2c-hid: Use PM subsystem to manage wake irq
  gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by
  i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  HID: i2c-hid: acpi: Stop setting wakeup_capable
  Input: elan_i2c - Don't set wake_irq when using ACPI
  HID: i2c-hid: Don't set wake_irq when using ACPI
  ACPI: PM: Take wake IRQ into consideration when entering
    suspend-to-idle

 drivers/acpi/device_pm.c            | 19 +++++++++++++++--
 drivers/gpio/gpio-pca953x.c         |  3 ++-
 drivers/gpio/gpiolib-acpi.c         | 11 +++++++++-
 drivers/gpio/gpiolib-acpi.h         |  2 ++
 drivers/hid/i2c-hid/i2c-hid-acpi.c  |  5 -----
 drivers/hid/i2c-hid/i2c-hid-core.c  | 33 +++++++++++------------------
 drivers/i2c/i2c-core-acpi.c         |  8 +++++--
 drivers/i2c/i2c-core-base.c         | 17 +++++++++------
 drivers/i2c/i2c-core.h              |  4 ++--
 drivers/input/mouse/elan_i2c_core.c | 14 +++++-------
 include/linux/acpi.h                | 14 +++++++++---
 11 files changed, 78 insertions(+), 52 deletions(-)

-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-31 18:01   ` Rafael J. Wysocki
  2022-08-30 23:15 ` [PATCH 2/8] HID: i2c-hid: " Raul E Rangel
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Dmitry Torokhov, jingle.wu, linux-kernel

The Elan I2C touchpad driver is currently manually managing the wake
IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
and instead relies on the PM subsystem. This is done by calling
dev_pm_set_wake_irq.

i2c_device_probe already calls dev_pm_set_wake_irq when using device
tree, so it's only required when using ACPI. The net result is that this
change should be a no-op. i2c_device_remove also already calls
dev_pm_clear_wake_irq, so we don't need to do that in this driver.

I tested this on an ACPI system where the touchpad doesn't have _PRW
defined. I verified I can still wake the system and that the wake source
was the touchpad IRQ GPIO.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/input/mouse/elan_i2c_core.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index e1758d5ffe4218..7d997d2b56436b 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -33,6 +33,7 @@
 #include <linux/jiffies.h>
 #include <linux/completion.h>
 #include <linux/of.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
@@ -86,8 +87,6 @@ struct elan_tp_data {
 	u16			fw_page_size;
 	u32			fw_signature_address;
 
-	bool			irq_wake;
-
 	u8			min_baseline;
 	u8			max_baseline;
 	bool			baseline_ready;
@@ -1337,8 +1336,10 @@ static int elan_probe(struct i2c_client *client,
 	 * Systems using device tree should set up wakeup via DTS,
 	 * the rest will configure device as wakeup source by default.
 	 */
-	if (!dev->of_node)
+	if (!dev->of_node) {
 		device_init_wakeup(dev, true);
+		dev_pm_set_wake_irq(dev, client->irq);
+	}
 
 	return 0;
 }
@@ -1362,8 +1363,6 @@ static int __maybe_unused elan_suspend(struct device *dev)
 
 	if (device_may_wakeup(dev)) {
 		ret = elan_sleep(data);
-		/* Enable wake from IRQ */
-		data->irq_wake = (enable_irq_wake(client->irq) == 0);
 	} else {
 		ret = elan_set_power(data, false);
 		if (ret)
@@ -1394,9 +1393,6 @@ static int __maybe_unused elan_resume(struct device *dev)
 			dev_err(dev, "error %d enabling regulator\n", error);
 			goto err;
 		}
-	} else if (data->irq_wake) {
-		disable_irq_wake(client->irq);
-		data->irq_wake = false;
 	}
 
 	error = elan_set_power(data, true);
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 2/8] HID: i2c-hid: Use PM subsystem to manage wake irq
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
  2022-08-30 23:15 ` [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage " Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-30 23:15 ` [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by Raul E Rangel
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Angela Czubak, Bartosz Szczepanek, Benjamin Tissoires,
	Dmitry Torokhov, Jiri Kosina, Yang Li, linux-kernel

The I2C hid driver is currently manually managing the wake
IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
and instead relies on the PM subsystem. This is done by calling
dev_pm_set_wake_irq.

i2c_device_probe already calls dev_pm_set_wake_irq when using device
tree, so it's only required when using ACPI. The net result is that this
change should be a no-op. i2c_device_remove also already calls
dev_pm_clear_wake_irq, so we don't need to do that in this driver.

I tested this on an ACPI system that has a HID touchscreen and verified
the IRQ was armed for wake on suspend.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/hid/i2c-hid/i2c-hid-core.c | 33 +++++++++++-------------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index baa169fadd6632..0b7a1a8b3e9a33 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pm.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/err.h>
@@ -116,7 +117,6 @@ struct i2c_hid {
 
 	wait_queue_head_t	wait;		/* For waiting the interrupt */
 
-	bool			irq_wake_enabled;
 	struct mutex		reset_lock;
 
 	struct i2chid_ops	*ops;
@@ -1036,6 +1036,15 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
 	if (ret < 0)
 		goto err_powered;
 
+	/*
+	 * Systems using device tree should set up wakeup via DTS,
+	 * the rest will configure device as wakeup source by default.
+	 */
+	if (!client->dev.of_node) {
+		device_init_wakeup(&client->dev, true);
+		dev_pm_set_wake_irq(&client->dev, client->irq);
+	}
+
 	hid = hid_allocate_device();
 	if (IS_ERR(hid)) {
 		ret = PTR_ERR(hid);
@@ -1119,7 +1128,6 @@ static int i2c_hid_core_suspend(struct device *dev)
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 	struct hid_device *hid = ihid->hid;
 	int ret;
-	int wake_status;
 
 	ret = hid_driver_suspend(hid, PMSG_SUSPEND);
 	if (ret < 0)
@@ -1130,16 +1138,8 @@ static int i2c_hid_core_suspend(struct device *dev)
 
 	disable_irq(client->irq);
 
-	if (device_may_wakeup(&client->dev)) {
-		wake_status = enable_irq_wake(client->irq);
-		if (!wake_status)
-			ihid->irq_wake_enabled = true;
-		else
-			hid_warn(hid, "Failed to enable irq wake: %d\n",
-				wake_status);
-	} else {
+	if (!device_may_wakeup(&client->dev))
 		i2c_hid_core_power_down(ihid);
-	}
 
 	return 0;
 }
@@ -1150,18 +1150,9 @@ static int i2c_hid_core_resume(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 	struct hid_device *hid = ihid->hid;
-	int wake_status;
 
-	if (!device_may_wakeup(&client->dev)) {
+	if (!device_may_wakeup(&client->dev))
 		i2c_hid_core_power_up(ihid);
-	} else if (ihid->irq_wake_enabled) {
-		wake_status = disable_irq_wake(client->irq);
-		if (!wake_status)
-			ihid->irq_wake_enabled = false;
-		else
-			hid_warn(hid, "Failed to disable irq wake: %d\n",
-				wake_status);
-	}
 
 	enable_irq(client->irq);
 
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
  2022-08-30 23:15 ` [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage " Raul E Rangel
  2022-08-30 23:15 ` [PATCH 2/8] HID: i2c-hid: " Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-31  4:58   ` kernel test robot
  2022-08-30 23:15 ` [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq Raul E Rangel
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Andy Shevchenko, Bartosz Golaszewski, Len Brown, Linus Walleij,
	Mika Westerberg, linux-gpio, linux-kernel

The ACPI spec defines the SharedAndWake and ExclusiveAndWake share type
keywords. This is an indication that the GPIO IRQ can also be used as a
wake source. This change exposes the wake_capable bit so drivers can
correctly enable wake functionality instead of making an assumption.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/gpio/gpio-pca953x.c |  3 ++-
 drivers/gpio/gpiolib-acpi.c | 11 ++++++++++-
 drivers/gpio/gpiolib-acpi.h |  2 ++
 include/linux/acpi.h        | 14 +++++++++++---
 4 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index ecd7d169470b06..df02c3eb34a294 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -130,7 +130,8 @@ static int pca953x_acpi_get_irq(struct device *dev)
 	if (ret)
 		dev_warn(dev, "can't add GPIO ACPI mapping\n");
 
-	ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0);
+	ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0,
+				       NULL);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 9be1376f9a627f..5cda2fcf7f43df 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -741,6 +741,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
 		lookup->info.pin_config = agpio->pin_config;
 		lookup->info.debounce = agpio->debounce_timeout;
 		lookup->info.gpioint = gpioint;
+		lookup->info.wake_capable = agpio->wake_capable;
 
 		/*
 		 * Polarity and triggering are only specified for GpioInt
@@ -991,6 +992,7 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
  * @adev: pointer to a ACPI device to get IRQ from
  * @name: optional name of GpioInt resource
  * @index: index of GpioInt resource (starting from %0)
+ * @wake_capable: Set to 1 if the IRQ is wake capable
  *
  * If the device has one or more GpioInt resources, this function can be
  * used to translate from the GPIO offset in the resource to the Linux IRQ
@@ -1002,9 +1004,13 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
  * The function takes optional @name parameter. If the resource has a property
  * name, then only those will be taken into account.
  *
+ * The GPIO is considered wake capable if GpioInt specifies SharedAndWake or
+ * ExclusiveAndWake.
+ *
  * Return: Linux IRQ number (> %0) on success, negative errno on failure.
  */
-int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index)
+int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name,
+			     int index, int *wake_capable)
 {
 	int idx, i;
 	unsigned int irq_flags;
@@ -1061,6 +1067,9 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
 				dev_dbg(&adev->dev, "IRQ %d already in use\n", irq);
 			}
 
+			if (wake_capable)
+				*wake_capable = info.wake_capable;
+
 			return irq;
 		}
 
diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h
index e476558d947136..1ac6816839dbce 100644
--- a/drivers/gpio/gpiolib-acpi.h
+++ b/drivers/gpio/gpiolib-acpi.h
@@ -18,6 +18,7 @@ struct acpi_device;
  * @pin_config: pin bias as provided by ACPI
  * @polarity: interrupt polarity as provided by ACPI
  * @triggering: triggering type as provided by ACPI
+ * @wake_capable: wake capability as provided by ACPI
  * @debounce: debounce timeout as provided by ACPI
  * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
  */
@@ -28,6 +29,7 @@ struct acpi_gpio_info {
 	int pin_config;
 	int polarity;
 	int triggering;
+	bool wake_capable;
 	unsigned int debounce;
 	unsigned int quirks;
 };
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 6f64b2f3dc5479..7ee946758c5bcc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1202,7 +1202,8 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
 				struct acpi_resource_gpio **agpio);
 bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
 			       struct acpi_resource_gpio **agpio);
-int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
+int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name,
+			     int index, int *wake_capable);
 #else
 static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
 					      struct acpi_resource_gpio **agpio)
@@ -1215,7 +1216,8 @@ static inline bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
 	return false;
 }
 static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
-					   const char *name, int index)
+					   const char *name, int index,
+					   int *wake_capable)
 {
 	return -ENXIO;
 }
@@ -1223,7 +1225,13 @@ static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
 
 static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
 {
-	return acpi_dev_gpio_irq_get_by(adev, NULL, index);
+	return acpi_dev_gpio_irq_get_by(adev, NULL, index, NULL);
+}
+
+static inline int acpi_dev_gpio_irq_get_wake(struct acpi_device *adev,
+					     int index, int *wake_capable)
+{
+	return acpi_dev_gpio_irq_get_by(adev, NULL, index, wake_capable);
 }
 
 /* Device properties */
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (2 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-09-07  1:00   ` Dmitry Torokhov
  2022-08-30 23:15 ` [PATCH 5/8] HID: i2c-hid: acpi: Stop setting wakeup_capable Raul E Rangel
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Mika Westerberg, Wolfram Sang, linux-i2c, linux-kernel

Device tree already has a mechanism to pass the wake_irq. It does this
by looking for the wakeup-source property and setting the
I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
ACPI GpioInt wake flag to determine if the interrupt can be used to wake
the system. Previously the i2c drivers had to make assumptions and
blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
If there is a device with an Active Low interrupt and the device gets
powered off while suspending, the interrupt line will go low since it's
no longer powered and wake the system. For this reason we should respect
the board designers wishes and honor the wake bit defined on the
GpioInt.

This change does not cover the ACPI Interrupt or IRQ resources.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/i2c/i2c-core-acpi.c |  8 ++++++--
 drivers/i2c/i2c-core-base.c | 17 +++++++++++------
 drivers/i2c/i2c-core.h      |  4 ++--
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index c762a879c4cc6b..cfe82a6ba3ef28 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
 /**
  * i2c_acpi_get_irq - get device IRQ number from ACPI
  * @client: Pointer to the I2C client device
+ * @wake_capable: Set to 1 if the IRQ is wake capable
  *
  * Find the IRQ number used by a specific client device.
  *
  * Return: The IRQ number or an error code.
  */
-int i2c_acpi_get_irq(struct i2c_client *client)
+int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
 {
 	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
 	struct list_head resource_list;
@@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
 
 	INIT_LIST_HEAD(&resource_list);
 
+	if (wake_capable)
+		*wake_capable = 0;
+
 	ret = acpi_dev_get_resources(adev, &resource_list,
 				     i2c_acpi_add_resource, &irq);
 	if (ret < 0)
@@ -204,7 +208,7 @@ int i2c_acpi_get_irq(struct i2c_client *client)
 	acpi_dev_free_resource_list(&resource_list);
 
 	if (irq == -ENOENT)
-		irq = acpi_dev_gpio_irq_get(adev, 0);
+		irq = acpi_dev_gpio_irq_get_wake(adev, 0, wake_capable);
 
 	return irq;
 }
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 91007558bcb260..88f4ef76235f4e 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -468,6 +468,7 @@ static int i2c_device_probe(struct device *dev)
 	struct i2c_client	*client = i2c_verify_client(dev);
 	struct i2c_driver	*driver;
 	int status;
+	int acpi_wake_capable = 0;
 
 	if (!client)
 		return 0;
@@ -487,7 +488,7 @@ static int i2c_device_probe(struct device *dev)
 			if (irq == -EINVAL || irq == -ENODATA)
 				irq = of_irq_get(dev->of_node, 0);
 		} else if (ACPI_COMPANION(dev)) {
-			irq = i2c_acpi_get_irq(client);
+			irq = i2c_acpi_get_irq(client, &acpi_wake_capable);
 		}
 		if (irq == -EPROBE_DEFER) {
 			status = irq;
@@ -513,13 +514,17 @@ static int i2c_device_probe(struct device *dev)
 		goto put_sync_adapter;
 	}
 
-	if (client->flags & I2C_CLIENT_WAKE) {
+	if (client->flags & I2C_CLIENT_WAKE || acpi_wake_capable) {
 		int wakeirq;
 
-		wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
-		if (wakeirq == -EPROBE_DEFER) {
-			status = wakeirq;
-			goto put_sync_adapter;
+		if (acpi_wake_capable) {
+			wakeirq = client->irq;
+		} else {
+			wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
+			if (wakeirq == -EPROBE_DEFER) {
+				status = wakeirq;
+				goto put_sync_adapter;
+			}
 		}
 
 		device_init_wakeup(&client->dev, true);
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 87e2c914f1c57b..8e336638a0cd2e 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -61,11 +61,11 @@ static inline int __i2c_check_suspended(struct i2c_adapter *adap)
 #ifdef CONFIG_ACPI
 void i2c_acpi_register_devices(struct i2c_adapter *adap);
 
-int i2c_acpi_get_irq(struct i2c_client *client);
+int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable);
 #else /* CONFIG_ACPI */
 static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
 
-static inline int i2c_acpi_get_irq(struct i2c_client *client)
+static inline int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
 {
 	return 0;
 }
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 5/8] HID: i2c-hid: acpi: Stop setting wakeup_capable
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (3 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-30 23:15 ` [PATCH 6/8] Input: elan_i2c - Don't set wake_irq when using ACPI Raul E Rangel
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Alistair Francis, Benjamin Tissoires, Jiri Kosina, Rob Herring,
	linux-kernel

This is now handled by the i2c-core driver.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/hid/i2c-hid/i2c-hid-acpi.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
index b96ae15e0ad917..375c77c3db74d9 100644
--- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -105,11 +105,6 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
 
 	acpi_device_fix_up_power(adev);
 
-	if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
-		device_set_wakeup_capable(dev, true);
-		device_set_wakeup_enable(dev, false);
-	}
-
 	return i2c_hid_core_probe(client, &ihid_acpi->ops,
 				  hid_descriptor_address, 0);
 }
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 6/8] Input: elan_i2c - Don't set wake_irq when using ACPI
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (4 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 5/8] HID: i2c-hid: acpi: Stop setting wakeup_capable Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-30 23:15 ` [PATCH 7/8] HID: i2c-hid: " Raul E Rangel
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Dmitry Torokhov, jingle.wu, linux-kernel

The i2c-core will now handle setting the wake_irq for ACPI systems.

I didn't delete the whole block since this also covers systems that
don't use ACPI or DT, but I'm honestly not sure if that's a valid
config.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/input/mouse/elan_i2c_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 7d997d2b56436b..d434c8ff8c4ca2 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -1333,10 +1333,10 @@ static int elan_probe(struct i2c_client *client,
 	}
 
 	/*
-	 * Systems using device tree should set up wakeup via DTS,
+	 * Systems using device tree should set up wakeup via DTS or ACPI,
 	 * the rest will configure device as wakeup source by default.
 	 */
-	if (!dev->of_node) {
+	if (!dev->of_node && !has_acpi_companion(dev)) {
 		device_init_wakeup(dev, true);
 		dev_pm_set_wake_irq(dev, client->irq);
 	}
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 7/8] HID: i2c-hid: Don't set wake_irq when using ACPI
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (5 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 6/8] Input: elan_i2c - Don't set wake_irq when using ACPI Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-30 23:15 ` [PATCH 8/8] ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle Raul E Rangel
  2022-08-31 11:52 ` [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Andy Shevchenko
  8 siblings, 0 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Alistair Francis, Angela Czubak, Benjamin Tissoires,
	Dmitry Torokhov, Jiri Kosina, Matthias Kaehlcke, linux-kernel

The i2c-core will now handle setting the wake_irq for ACPI systems.

I didn't delete the whole block since this also covers systems that
don't use ACPI or DT, but I'm honestly not sure if that's a valid
config.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/hid/i2c-hid/i2c-hid-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 0b7a1a8b3e9a33..630e8dcda1100d 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -1037,10 +1037,10 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
 		goto err_powered;
 
 	/*
-	 * Systems using device tree should set up wakeup via DTS,
+	 * Systems using device tree should set up wakeup via DTS or ACPI,
 	 * the rest will configure device as wakeup source by default.
 	 */
-	if (!client->dev.of_node) {
+	if (!client->dev.of_node && !has_acpi_companion(&client->dev)) {
 		device_init_wakeup(&client->dev, true);
 		dev_pm_set_wake_irq(&client->dev, client->irq);
 	}
-- 
2.37.2.672.g94769d06f0-goog


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

* [PATCH 8/8] ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (6 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 7/8] HID: i2c-hid: " Raul E Rangel
@ 2022-08-30 23:15 ` Raul E Rangel
  2022-08-31 11:52 ` [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Andy Shevchenko
  8 siblings, 0 replies; 31+ messages in thread
From: Raul E Rangel @ 2022-08-30 23:15 UTC (permalink / raw)
  To: linux-acpi, linux-input
  Cc: hdegoede, mario.limonciello, timvp, rafael, Raul E Rangel,
	Len Brown, linux-kernel

This change adds support for ACPI devices that use ExclusiveAndWake or
SharedAndWake in their _CRS GpioInt definition (instead of using _PRW),
and also provide power resources. Previously the ACPI subsystem had no
idea if the device had a wake capable interrupt armed. This resulted
in the ACPI device PM system placing the device into D3Cold, and thus
cutting power to the device. With this change we will now query the
_S0W method to figure out the appropriate wake capable D-state.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
---

 drivers/acpi/device_pm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 9dce1245689ca2..6bc81f525d5160 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -681,8 +681,23 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
 		d_min = ret;
 		wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
 			&& adev->wakeup.sleep_state >= target_state;
-	} else {
-		wakeup = adev->wakeup.flags.valid;
+	} else if (acpi_device_can_wakeup(adev)) {
+		/* ACPI GPE from specified by _PRW. */
+		wakeup = true;
+	} else if (device_may_wakeup(dev) && dev->power.wakeirq) {
+		/*
+		 * The ACPI subsystem doesn't manage the wake bit for IRQs
+		 * defined with ExclusiveAndWake and SharedAndWake. Instead we
+		 * expect them to be managed via the PM subsystem. Drivers
+		 * should call dev_pm_set_wake_irq to register an IRQ as a wake
+		 * source.
+		 *
+		 * If a device has a wake IRQ attached we need to check the
+		 * _S0W method to get the correct wake D-state. Otherwise we
+		 * end up putting the device into D3Cold which will more than
+		 * likely disable wake functionality.
+		 */
+		wakeup = true;
 	}
 
 	/*
-- 
2.37.2.672.g94769d06f0-goog


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

* Re: [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by
  2022-08-30 23:15 ` [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by Raul E Rangel
@ 2022-08-31  4:58   ` kernel test robot
  0 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2022-08-31  4:58 UTC (permalink / raw)
  To: Raul E Rangel, linux-acpi, linux-input
  Cc: kbuild-all, hdegoede, mario.limonciello, timvp, rafael,
	Raul E Rangel, Andy Shevchenko, Bartosz Golaszewski, Len Brown,
	Linus Walleij, Mika Westerberg, linux-gpio, linux-kernel

Hi Raul,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hid/for-next]
[also build test ERROR on brgl/gpio/for-next rafael-pm/linux-next linus/master v6.0-rc3 next-20220830]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Raul-E-Rangel/acpi-i2c-Use-SharedAndWake-and-ExclusiveAndWake-to-enable-wake-irq/20220831-071916
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220831/202208311235.pxWOoHPE-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/131a07025a591f4ca6d7540f1055bc03f8cf64af
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Raul-E-Rangel/acpi-i2c-Use-SharedAndWake-and-ExclusiveAndWake-to-enable-wake-irq/20220831-071916
        git checkout 131a07025a591f4ca6d7540f1055bc03f8cf64af
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sh SHELL=/bin/bash drivers/net/ethernet/mellanox/mlxbf_gige/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c: In function 'mlxbf_gige_probe':
>> drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c:343:19: error: too few arguments to function 'acpi_dev_gpio_irq_get_by'
     343 |         phy_irq = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(&pdev->dev), "phy-gpios", 0);
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c:8:
   include/linux/acpi.h:1212:19: note: declared here
    1212 | static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~


vim +/acpi_dev_gpio_irq_get_by +343 drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c

f92e1869d74e1a David Thompson 2021-06-24  272  
f92e1869d74e1a David Thompson 2021-06-24  273  static int mlxbf_gige_probe(struct platform_device *pdev)
f92e1869d74e1a David Thompson 2021-06-24  274  {
f92e1869d74e1a David Thompson 2021-06-24  275  	struct phy_device *phydev;
f92e1869d74e1a David Thompson 2021-06-24  276  	struct net_device *netdev;
f92e1869d74e1a David Thompson 2021-06-24  277  	struct mlxbf_gige *priv;
f92e1869d74e1a David Thompson 2021-06-24  278  	void __iomem *llu_base;
f92e1869d74e1a David Thompson 2021-06-24  279  	void __iomem *plu_base;
f92e1869d74e1a David Thompson 2021-06-24  280  	void __iomem *base;
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  281  	int addr, phy_irq;
f92e1869d74e1a David Thompson 2021-06-24  282  	u64 control;
f92e1869d74e1a David Thompson 2021-06-24  283  	int err;
f92e1869d74e1a David Thompson 2021-06-24  284  
464a57281f29af Cai Huoqing    2021-08-31  285  	base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC);
f92e1869d74e1a David Thompson 2021-06-24  286  	if (IS_ERR(base))
f92e1869d74e1a David Thompson 2021-06-24  287  		return PTR_ERR(base);
f92e1869d74e1a David Thompson 2021-06-24  288  
464a57281f29af Cai Huoqing    2021-08-31  289  	llu_base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_LLU);
f92e1869d74e1a David Thompson 2021-06-24  290  	if (IS_ERR(llu_base))
f92e1869d74e1a David Thompson 2021-06-24  291  		return PTR_ERR(llu_base);
f92e1869d74e1a David Thompson 2021-06-24  292  
464a57281f29af Cai Huoqing    2021-08-31  293  	plu_base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_PLU);
f92e1869d74e1a David Thompson 2021-06-24  294  	if (IS_ERR(plu_base))
f92e1869d74e1a David Thompson 2021-06-24  295  		return PTR_ERR(plu_base);
f92e1869d74e1a David Thompson 2021-06-24  296  
f92e1869d74e1a David Thompson 2021-06-24  297  	/* Perform general init of GigE block */
f92e1869d74e1a David Thompson 2021-06-24  298  	control = readq(base + MLXBF_GIGE_CONTROL);
f92e1869d74e1a David Thompson 2021-06-24  299  	control |= MLXBF_GIGE_CONTROL_PORT_EN;
f92e1869d74e1a David Thompson 2021-06-24  300  	writeq(control, base + MLXBF_GIGE_CONTROL);
f92e1869d74e1a David Thompson 2021-06-24  301  
f92e1869d74e1a David Thompson 2021-06-24  302  	netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv));
f92e1869d74e1a David Thompson 2021-06-24  303  	if (!netdev)
f92e1869d74e1a David Thompson 2021-06-24  304  		return -ENOMEM;
f92e1869d74e1a David Thompson 2021-06-24  305  
f92e1869d74e1a David Thompson 2021-06-24  306  	SET_NETDEV_DEV(netdev, &pdev->dev);
f92e1869d74e1a David Thompson 2021-06-24  307  	netdev->netdev_ops = &mlxbf_gige_netdev_ops;
f92e1869d74e1a David Thompson 2021-06-24  308  	netdev->ethtool_ops = &mlxbf_gige_ethtool_ops;
f92e1869d74e1a David Thompson 2021-06-24  309  	priv = netdev_priv(netdev);
f92e1869d74e1a David Thompson 2021-06-24  310  	priv->netdev = netdev;
f92e1869d74e1a David Thompson 2021-06-24  311  
f92e1869d74e1a David Thompson 2021-06-24  312  	platform_set_drvdata(pdev, priv);
f92e1869d74e1a David Thompson 2021-06-24  313  	priv->dev = &pdev->dev;
f92e1869d74e1a David Thompson 2021-06-24  314  	priv->pdev = pdev;
f92e1869d74e1a David Thompson 2021-06-24  315  
f92e1869d74e1a David Thompson 2021-06-24  316  	spin_lock_init(&priv->lock);
f92e1869d74e1a David Thompson 2021-06-24  317  
f92e1869d74e1a David Thompson 2021-06-24  318  	/* Attach MDIO device */
f92e1869d74e1a David Thompson 2021-06-24  319  	err = mlxbf_gige_mdio_probe(pdev, priv);
f92e1869d74e1a David Thompson 2021-06-24  320  	if (err)
f92e1869d74e1a David Thompson 2021-06-24  321  		return err;
f92e1869d74e1a David Thompson 2021-06-24  322  
f92e1869d74e1a David Thompson 2021-06-24  323  	priv->base = base;
f92e1869d74e1a David Thompson 2021-06-24  324  	priv->llu_base = llu_base;
f92e1869d74e1a David Thompson 2021-06-24  325  	priv->plu_base = plu_base;
f92e1869d74e1a David Thompson 2021-06-24  326  
f92e1869d74e1a David Thompson 2021-06-24  327  	priv->rx_q_entries = MLXBF_GIGE_DEFAULT_RXQ_SZ;
f92e1869d74e1a David Thompson 2021-06-24  328  	priv->tx_q_entries = MLXBF_GIGE_DEFAULT_TXQ_SZ;
f92e1869d74e1a David Thompson 2021-06-24  329  
f92e1869d74e1a David Thompson 2021-06-24  330  	/* Write initial MAC address to hardware */
f92e1869d74e1a David Thompson 2021-06-24  331  	mlxbf_gige_initial_mac(priv);
f92e1869d74e1a David Thompson 2021-06-24  332  
f92e1869d74e1a David Thompson 2021-06-24  333  	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
f92e1869d74e1a David Thompson 2021-06-24  334  	if (err) {
f92e1869d74e1a David Thompson 2021-06-24  335  		dev_err(&pdev->dev, "DMA configuration failed: 0x%x\n", err);
f92e1869d74e1a David Thompson 2021-06-24  336  		goto out;
f92e1869d74e1a David Thompson 2021-06-24  337  	}
f92e1869d74e1a David Thompson 2021-06-24  338  
f92e1869d74e1a David Thompson 2021-06-24  339  	priv->error_irq = platform_get_irq(pdev, MLXBF_GIGE_ERROR_INTR_IDX);
f92e1869d74e1a David Thompson 2021-06-24  340  	priv->rx_irq = platform_get_irq(pdev, MLXBF_GIGE_RECEIVE_PKT_INTR_IDX);
f92e1869d74e1a David Thompson 2021-06-24  341  	priv->llu_plu_irq = platform_get_irq(pdev, MLXBF_GIGE_LLU_PLU_INTR_IDX);
f92e1869d74e1a David Thompson 2021-06-24  342  
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15 @343  	phy_irq = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(&pdev->dev), "phy-gpios", 0);
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  344  	if (phy_irq < 0) {
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  345  		dev_err(&pdev->dev, "Error getting PHY irq. Use polling instead");
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  346  		phy_irq = PHY_POLL;
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  347  	}
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  348  
f92e1869d74e1a David Thompson 2021-06-24  349  	phydev = phy_find_first(priv->mdiobus);
f92e1869d74e1a David Thompson 2021-06-24  350  	if (!phydev) {
f92e1869d74e1a David Thompson 2021-06-24  351  		err = -ENODEV;
f92e1869d74e1a David Thompson 2021-06-24  352  		goto out;
f92e1869d74e1a David Thompson 2021-06-24  353  	}
f92e1869d74e1a David Thompson 2021-06-24  354  
f92e1869d74e1a David Thompson 2021-06-24  355  	addr = phydev->mdio.addr;
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  356  	priv->mdiobus->irq[addr] = phy_irq;
6c2a6ddca76327 Asmaa Mnebhi   2021-10-15  357  	phydev->irq = phy_irq;
f92e1869d74e1a David Thompson 2021-06-24  358  
f92e1869d74e1a David Thompson 2021-06-24  359  	err = phy_connect_direct(netdev, phydev,
f92e1869d74e1a David Thompson 2021-06-24  360  				 mlxbf_gige_adjust_link,
f92e1869d74e1a David Thompson 2021-06-24  361  				 PHY_INTERFACE_MODE_GMII);
f92e1869d74e1a David Thompson 2021-06-24  362  	if (err) {
f92e1869d74e1a David Thompson 2021-06-24  363  		dev_err(&pdev->dev, "Could not attach to PHY\n");
f92e1869d74e1a David Thompson 2021-06-24  364  		goto out;
f92e1869d74e1a David Thompson 2021-06-24  365  	}
f92e1869d74e1a David Thompson 2021-06-24  366  
f92e1869d74e1a David Thompson 2021-06-24  367  	/* MAC only supports 1000T full duplex mode */
f92e1869d74e1a David Thompson 2021-06-24  368  	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
f92e1869d74e1a David Thompson 2021-06-24  369  	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
f92e1869d74e1a David Thompson 2021-06-24  370  	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
f92e1869d74e1a David Thompson 2021-06-24  371  	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
f92e1869d74e1a David Thompson 2021-06-24  372  	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
f92e1869d74e1a David Thompson 2021-06-24  373  
f92e1869d74e1a David Thompson 2021-06-24  374  	/* Only symmetric pause with flow control enabled is supported so no
f92e1869d74e1a David Thompson 2021-06-24  375  	 * need to negotiate pause.
f92e1869d74e1a David Thompson 2021-06-24  376  	 */
f92e1869d74e1a David Thompson 2021-06-24  377  	linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising);
f92e1869d74e1a David Thompson 2021-06-24  378  	linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising);
f92e1869d74e1a David Thompson 2021-06-24  379  
f92e1869d74e1a David Thompson 2021-06-24  380  	/* Display information about attached PHY device */
f92e1869d74e1a David Thompson 2021-06-24  381  	phy_attached_info(phydev);
f92e1869d74e1a David Thompson 2021-06-24  382  
f92e1869d74e1a David Thompson 2021-06-24  383  	err = register_netdev(netdev);
f92e1869d74e1a David Thompson 2021-06-24  384  	if (err) {
f92e1869d74e1a David Thompson 2021-06-24  385  		dev_err(&pdev->dev, "Failed to register netdev\n");
f92e1869d74e1a David Thompson 2021-06-24  386  		phy_disconnect(phydev);
f92e1869d74e1a David Thompson 2021-06-24  387  		goto out;
f92e1869d74e1a David Thompson 2021-06-24  388  	}
f92e1869d74e1a David Thompson 2021-06-24  389  
f92e1869d74e1a David Thompson 2021-06-24  390  	return 0;
f92e1869d74e1a David Thompson 2021-06-24  391  
f92e1869d74e1a David Thompson 2021-06-24  392  out:
f92e1869d74e1a David Thompson 2021-06-24  393  	mlxbf_gige_mdio_remove(priv);
f92e1869d74e1a David Thompson 2021-06-24  394  	return err;
f92e1869d74e1a David Thompson 2021-06-24  395  }
f92e1869d74e1a David Thompson 2021-06-24  396  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq
  2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
                   ` (7 preceding siblings ...)
  2022-08-30 23:15 ` [PATCH 8/8] ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle Raul E Rangel
@ 2022-08-31 11:52 ` Andy Shevchenko
  2022-08-31 14:37   ` Raul Rangel
  8 siblings, 1 reply; 31+ messages in thread
From: Andy Shevchenko @ 2022-08-31 11:52 UTC (permalink / raw)
  To: Raul E Rangel
  Cc: linux-acpi, linux-input, hdegoede, mario.limonciello, timvp,
	rafael, Alistair Francis, Angela Czubak, Bartosz Golaszewski,
	Bartosz Szczepanek, Benjamin Tissoires, Dmitry Torokhov,
	Jiri Kosina, Len Brown, Linus Walleij, Matthias Kaehlcke,
	Mika Westerberg, Rob Herring, Wolfram Sang, Yang Li, jingle.wu,
	linux-gpio, linux-i2c, linux-kernel

On Tue, Aug 30, 2022 at 05:15:33PM -0600, Raul E Rangel wrote:
> Today, i2c drivers are making the assumption that their IRQs can also
> be used as wake IRQs. This isn't always the case and it can lead to
> spurious wakes. This has recently started to affect AMD Chromebooks.
> With the introduction of
> d62bd5ce12d7 ("pinctrl: amd: Implement irq_set_wake"), the AMD GPIO
> controller gained the capability to set the wake bit on each GPIO. The
> ACPI specification defines two ways to inform the system if a device is
> wake capable:
> 1) The _PRW object defines the GPE that can be used to wake the system.
> 2) Setting ExclusiveAndWake or SharedAndWake in the _CRS GpioInt.
> 
> Currently only the first method is supported. The i2c drivers don't have
> any indication that the IRQ is wake capable, so they guess. This causes
> spurious interrupts, for example:
> * We have an ACPI HID device that has `_PR0` and `_PR3`. It doesn't have
>   `_PRW` or `ExclusiveAndWake` so that means the device can't wake the
>   system.
> * The IRQ line is active level low for this device and is pulled up by
>   the power resource defined in `_PR0`/`_PR3`.
> * The i2c driver will (incorrectly) arm the GPIO for wake by calling
>   `enable_irq_wake` as part of its suspend hook.
> * ACPI will power down the device since it doesn't have a wake GPE
>   associated with it.
> * When the device is powered down, the IRQ line will drop, and it will
>   trigger a wake event.
> 
> See the following debug log:
> [   42.335804] PM: Suspending system (s2idle)
> [   42.340186] amd_gpio AMD0030:00: RX: Setting wake for pin 89 to enable
> [   42.467736]     power-0416 __acpi_power_off      : Power resource [PR00] turned off
> [   42.467739] device_pm-0280 device_set_power      : Device [H05D] transitioned to D3cold
> [   42.475210] PM: pm_system_irq_wakeup: 11 triggered pinctrl_amd
> [   42.535293] PM: Wakeup unrelated to ACPI SCI
> [   42.535294] PM: resume from suspend-to-idle
> 
> In order to fix this, we need to take into account the wake capable bit
> defined on the GpioInt. This is accomplished by:
> * Migrating some of the i2c drivers over to using the PM subsystem to
>   manage the wake IRQ. max8925-i2c, elants_i2c, and raydium_i2c_ts still
>   need to be migrated, I can do that depending on the feedback to this
>   patch series.
> * Expose the wake_capable bit from the ACPI GpioInt resource to the
>   i2c core.
> * Use the wake_capable bit in the i2c core to call
>   `dev_pm_set_wake_irq`. This reuses the existing device tree flow.
> * Make the i2c drivers stop calling `dev_pm_set_wake_irq` since it's now
>   handled by the i2c core.
> * Make the ACPI device PM system aware of the wake_irq. This is
>   necessary so the device doesn't incorrectly get powered down when a
>   wake_irq is enabled.
> 
> I've tested this code with various combinations of having _PRW,
> ExclusiveAndWake and power resources all defined or not defined, but it
> would be great if others could test this out on their hardware.

I have got only cover letter and a single patch (#3). What's going on?

Note: I'm also reviewer of I²C DesignWare driver, you really have to
fix your tools / submission process and try again. No review for this
series.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq
  2022-08-31 11:52 ` [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Andy Shevchenko
@ 2022-08-31 14:37   ` Raul Rangel
  2022-08-31 15:18     ` Hans de Goede
  0 siblings, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-08-31 14:37 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Linux ACPI, linux-input, Hans de Goede, Limonciello, Mario,
	Tim Van Patten, Rafael J. Wysocki, Alistair Francis,
	Angela Czubak, Bartosz Golaszewski, Bartosz Szczepanek,
	Benjamin Tissoires, Dmitry Torokhov, Jiri Kosina, Len Brown,
	Linus Walleij, Matthias Kaehlcke, Mika Westerberg, Rob Herring,
	Wolfram Sang, Yang Li, jingle.wu, open list:GPIO SUBSYSTEM,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

Interesting... The patch series is here:
https://patchwork.kernel.org/project/linux-input/cover/20220830231541.1135813-1-rrangel@chromium.org/

I'll look into why you only got added to 2 of the emails.

On Wed, Aug 31, 2022 at 5:52 AM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Tue, Aug 30, 2022 at 05:15:33PM -0600, Raul E Rangel wrote:
> > Today, i2c drivers are making the assumption that their IRQs can also
> > be used as wake IRQs. This isn't always the case and it can lead to
> > spurious wakes. This has recently started to affect AMD Chromebooks.
> > With the introduction of
> > d62bd5ce12d7 ("pinctrl: amd: Implement irq_set_wake"), the AMD GPIO
> > controller gained the capability to set the wake bit on each GPIO. The
> > ACPI specification defines two ways to inform the system if a device is
> > wake capable:
> > 1) The _PRW object defines the GPE that can be used to wake the system.
> > 2) Setting ExclusiveAndWake or SharedAndWake in the _CRS GpioInt.
> >
> > Currently only the first method is supported. The i2c drivers don't have
> > any indication that the IRQ is wake capable, so they guess. This causes
> > spurious interrupts, for example:
> > * We have an ACPI HID device that has `_PR0` and `_PR3`. It doesn't have
> >   `_PRW` or `ExclusiveAndWake` so that means the device can't wake the
> >   system.
> > * The IRQ line is active level low for this device and is pulled up by
> >   the power resource defined in `_PR0`/`_PR3`.
> > * The i2c driver will (incorrectly) arm the GPIO for wake by calling
> >   `enable_irq_wake` as part of its suspend hook.
> > * ACPI will power down the device since it doesn't have a wake GPE
> >   associated with it.
> > * When the device is powered down, the IRQ line will drop, and it will
> >   trigger a wake event.
> >
> > See the following debug log:
> > [   42.335804] PM: Suspending system (s2idle)
> > [   42.340186] amd_gpio AMD0030:00: RX: Setting wake for pin 89 to enable
> > [   42.467736]     power-0416 __acpi_power_off      : Power resource [PR00] turned off
> > [   42.467739] device_pm-0280 device_set_power      : Device [H05D] transitioned to D3cold
> > [   42.475210] PM: pm_system_irq_wakeup: 11 triggered pinctrl_amd
> > [   42.535293] PM: Wakeup unrelated to ACPI SCI
> > [   42.535294] PM: resume from suspend-to-idle
> >
> > In order to fix this, we need to take into account the wake capable bit
> > defined on the GpioInt. This is accomplished by:
> > * Migrating some of the i2c drivers over to using the PM subsystem to
> >   manage the wake IRQ. max8925-i2c, elants_i2c, and raydium_i2c_ts still
> >   need to be migrated, I can do that depending on the feedback to this
> >   patch series.
> > * Expose the wake_capable bit from the ACPI GpioInt resource to the
> >   i2c core.
> > * Use the wake_capable bit in the i2c core to call
> >   `dev_pm_set_wake_irq`. This reuses the existing device tree flow.
> > * Make the i2c drivers stop calling `dev_pm_set_wake_irq` since it's now
> >   handled by the i2c core.
> > * Make the ACPI device PM system aware of the wake_irq. This is
> >   necessary so the device doesn't incorrectly get powered down when a
> >   wake_irq is enabled.
> >
> > I've tested this code with various combinations of having _PRW,
> > ExclusiveAndWake and power resources all defined or not defined, but it
> > would be great if others could test this out on their hardware.
>
> I have got only cover letter and a single patch (#3). What's going on?
>
> Note: I'm also reviewer of I涎 DesignWare driver, you really have to
> fix your tools / submission process and try again. No review for this
> series.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

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

* Re: [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq
  2022-08-31 14:37   ` Raul Rangel
@ 2022-08-31 15:18     ` Hans de Goede
  0 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2022-08-31 15:18 UTC (permalink / raw)
  To: Raul Rangel, Andy Shevchenko
  Cc: Linux ACPI, linux-input, Limonciello, Mario, Tim Van Patten,
	Rafael J. Wysocki, Alistair Francis, Angela Czubak,
	Bartosz Golaszewski, Bartosz Szczepanek, Benjamin Tissoires,
	Dmitry Torokhov, Jiri Kosina, Len Brown, Linus Walleij,
	Matthias Kaehlcke, Mika Westerberg, Rob Herring, Wolfram Sang,
	Yang Li, jingle.wu, open list:GPIO SUBSYSTEM,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

Hi,

On 8/31/22 16:37, Raul Rangel wrote:
> Interesting... The patch series is here:
> https://patchwork.kernel.org/project/linux-input/cover/20220830231541.1135813-1-rrangel@chromium.org/
> 
> I'll look into why you only got added to 2 of the emails.

FWIW I also received the full series without problems.

I'll try to reply to this soon-ish, but I have a bit of
a patch backlog to process and I'm trying to process
the backlog in FIFO order and this is one of the last
series in the backlog ...

Regards,

Hans


> 
> On Wed, Aug 31, 2022 at 5:52 AM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
>>
>> On Tue, Aug 30, 2022 at 05:15:33PM -0600, Raul E Rangel wrote:
>>> Today, i2c drivers are making the assumption that their IRQs can also
>>> be used as wake IRQs. This isn't always the case and it can lead to
>>> spurious wakes. This has recently started to affect AMD Chromebooks.
>>> With the introduction of
>>> d62bd5ce12d7 ("pinctrl: amd: Implement irq_set_wake"), the AMD GPIO
>>> controller gained the capability to set the wake bit on each GPIO. The
>>> ACPI specification defines two ways to inform the system if a device is
>>> wake capable:
>>> 1) The _PRW object defines the GPE that can be used to wake the system.
>>> 2) Setting ExclusiveAndWake or SharedAndWake in the _CRS GpioInt.
>>>
>>> Currently only the first method is supported. The i2c drivers don't have
>>> any indication that the IRQ is wake capable, so they guess. This causes
>>> spurious interrupts, for example:
>>> * We have an ACPI HID device that has `_PR0` and `_PR3`. It doesn't have
>>>   `_PRW` or `ExclusiveAndWake` so that means the device can't wake the
>>>   system.
>>> * The IRQ line is active level low for this device and is pulled up by
>>>   the power resource defined in `_PR0`/`_PR3`.
>>> * The i2c driver will (incorrectly) arm the GPIO for wake by calling
>>>   `enable_irq_wake` as part of its suspend hook.
>>> * ACPI will power down the device since it doesn't have a wake GPE
>>>   associated with it.
>>> * When the device is powered down, the IRQ line will drop, and it will
>>>   trigger a wake event.
>>>
>>> See the following debug log:
>>> [   42.335804] PM: Suspending system (s2idle)
>>> [   42.340186] amd_gpio AMD0030:00: RX: Setting wake for pin 89 to enable
>>> [   42.467736]     power-0416 __acpi_power_off      : Power resource [PR00] turned off
>>> [   42.467739] device_pm-0280 device_set_power      : Device [H05D] transitioned to D3cold
>>> [   42.475210] PM: pm_system_irq_wakeup: 11 triggered pinctrl_amd
>>> [   42.535293] PM: Wakeup unrelated to ACPI SCI
>>> [   42.535294] PM: resume from suspend-to-idle
>>>
>>> In order to fix this, we need to take into account the wake capable bit
>>> defined on the GpioInt. This is accomplished by:
>>> * Migrating some of the i2c drivers over to using the PM subsystem to
>>>   manage the wake IRQ. max8925-i2c, elants_i2c, and raydium_i2c_ts still
>>>   need to be migrated, I can do that depending on the feedback to this
>>>   patch series.
>>> * Expose the wake_capable bit from the ACPI GpioInt resource to the
>>>   i2c core.
>>> * Use the wake_capable bit in the i2c core to call
>>>   `dev_pm_set_wake_irq`. This reuses the existing device tree flow.
>>> * Make the i2c drivers stop calling `dev_pm_set_wake_irq` since it's now
>>>   handled by the i2c core.
>>> * Make the ACPI device PM system aware of the wake_irq. This is
>>>   necessary so the device doesn't incorrectly get powered down when a
>>>   wake_irq is enabled.
>>>
>>> I've tested this code with various combinations of having _PRW,
>>> ExclusiveAndWake and power resources all defined or not defined, but it
>>> would be great if others could test this out on their hardware.
>>
>> I have got only cover letter and a single patch (#3). What's going on?
>>
>> Note: I'm also reviewer of I涎 DesignWare driver, you really have to
>> fix your tools / submission process and try again. No review for this
>> series.
>>
>> --
>> With Best Regards,
>> Andy Shevchenko
>>
>>
> 


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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-30 23:15 ` [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage " Raul E Rangel
@ 2022-08-31 18:01   ` Rafael J. Wysocki
  2022-08-31 18:13     ` Raul Rangel
  2022-08-31 19:12     ` Dmitry Torokhov
  0 siblings, 2 replies; 31+ messages in thread
From: Rafael J. Wysocki @ 2022-08-31 18:01 UTC (permalink / raw)
  To: Raul E Rangel
  Cc: ACPI Devel Maling List, linux-input, Hans de Goede,
	Mario Limonciello, timvp, Rafael J. Wysocki, Dmitry Torokhov,
	jingle.wu, Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
>
> The Elan I2C touchpad driver is currently manually managing the wake
> IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> and instead relies on the PM subsystem. This is done by calling
> dev_pm_set_wake_irq.
>
> i2c_device_probe already calls dev_pm_set_wake_irq when using device
> tree, so it's only required when using ACPI. The net result is that this
> change should be a no-op. i2c_device_remove also already calls
> dev_pm_clear_wake_irq, so we don't need to do that in this driver.
>
> I tested this on an ACPI system where the touchpad doesn't have _PRW
> defined. I verified I can still wake the system and that the wake source
> was the touchpad IRQ GPIO.
>
> Signed-off-by: Raul E Rangel <rrangel@chromium.org>

I like this a lot, but the assumption in the wakeirq code is that the
IRQ in question will be dedicated for signaling wakeup.  Does it hold
here?

> ---
>
>  drivers/input/mouse/elan_i2c_core.c | 12 ++++--------
>  1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
> index e1758d5ffe4218..7d997d2b56436b 100644
> --- a/drivers/input/mouse/elan_i2c_core.c
> +++ b/drivers/input/mouse/elan_i2c_core.c
> @@ -33,6 +33,7 @@
>  #include <linux/jiffies.h>
>  #include <linux/completion.h>
>  #include <linux/of.h>
> +#include <linux/pm_wakeirq.h>
>  #include <linux/property.h>
>  #include <linux/regulator/consumer.h>
>  #include <asm/unaligned.h>
> @@ -86,8 +87,6 @@ struct elan_tp_data {
>         u16                     fw_page_size;
>         u32                     fw_signature_address;
>
> -       bool                    irq_wake;
> -
>         u8                      min_baseline;
>         u8                      max_baseline;
>         bool                    baseline_ready;
> @@ -1337,8 +1336,10 @@ static int elan_probe(struct i2c_client *client,
>          * Systems using device tree should set up wakeup via DTS,
>          * the rest will configure device as wakeup source by default.
>          */
> -       if (!dev->of_node)
> +       if (!dev->of_node) {
>                 device_init_wakeup(dev, true);
> +               dev_pm_set_wake_irq(dev, client->irq);
> +       }
>
>         return 0;
>  }
> @@ -1362,8 +1363,6 @@ static int __maybe_unused elan_suspend(struct device *dev)
>
>         if (device_may_wakeup(dev)) {
>                 ret = elan_sleep(data);
> -               /* Enable wake from IRQ */
> -               data->irq_wake = (enable_irq_wake(client->irq) == 0);
>         } else {
>                 ret = elan_set_power(data, false);
>                 if (ret)
> @@ -1394,9 +1393,6 @@ static int __maybe_unused elan_resume(struct device *dev)
>                         dev_err(dev, "error %d enabling regulator\n", error);
>                         goto err;
>                 }
> -       } else if (data->irq_wake) {
> -               disable_irq_wake(client->irq);
> -               data->irq_wake = false;
>         }
>
>         error = elan_set_power(data, true);
> --
> 2.37.2.672.g94769d06f0-goog
>

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 18:01   ` Rafael J. Wysocki
@ 2022-08-31 18:13     ` Raul Rangel
  2022-08-31 18:42       ` Rafael J. Wysocki
  2022-08-31 19:12     ` Dmitry Torokhov
  1 sibling, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-08-31 18:13 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: ACPI Devel Maling List, linux-input, Hans de Goede,
	Mario Limonciello, Tim Van Patten, Dmitry Torokhov, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 12:01 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> >
> > The Elan I2C touchpad driver is currently manually managing the wake
> > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > and instead relies on the PM subsystem. This is done by calling
> > dev_pm_set_wake_irq.
> >
> > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > tree, so it's only required when using ACPI. The net result is that this
> > change should be a no-op. i2c_device_remove also already calls
> > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> >
> > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > defined. I verified I can still wake the system and that the wake source
> > was the touchpad IRQ GPIO.
> >
> > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
>


> I like this a lot, but the assumption in the wakeirq code is that the
> IRQ in question will be dedicated for signaling wakeup.  Does it hold
> here?

The wakeirq code defines two methods: `dev_pm_set_wake_irq` and
`dev_pm_set_dedicated_wake_irq`.
The latter is used when you have a dedicated wakeup signal. In this
driver it's currently assumed
that the IRQ and the wake IRQ are the same, so I used `dev_pm_set_wake_irq`.

This change in theory also fixes a bug where you define a dedicated
wake irq in DT, but
then the driver enables the `client->irq` as a wake source. In
practice this doesn't happen
since the elan touchpads only have a single IRQ line.

>
> > ---
> >
> >  drivers/input/mouse/elan_i2c_core.c | 12 ++++--------
> >  1 file changed, 4 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
> > index e1758d5ffe4218..7d997d2b56436b 100644
> > --- a/drivers/input/mouse/elan_i2c_core.c
> > +++ b/drivers/input/mouse/elan_i2c_core.c
> > @@ -33,6 +33,7 @@
> >  #include <linux/jiffies.h>
> >  #include <linux/completion.h>
> >  #include <linux/of.h>
> > +#include <linux/pm_wakeirq.h>
> >  #include <linux/property.h>
> >  #include <linux/regulator/consumer.h>
> >  #include <asm/unaligned.h>
> > @@ -86,8 +87,6 @@ struct elan_tp_data {
> >         u16                     fw_page_size;
> >         u32                     fw_signature_address;
> >
> > -       bool                    irq_wake;
> > -
> >         u8                      min_baseline;
> >         u8                      max_baseline;
> >         bool                    baseline_ready;
> > @@ -1337,8 +1336,10 @@ static int elan_probe(struct i2c_client *client,
> >          * Systems using device tree should set up wakeup via DTS,
> >          * the rest will configure device as wakeup source by default.
> >          */
> > -       if (!dev->of_node)
> > +       if (!dev->of_node) {
> >                 device_init_wakeup(dev, true);
> > +               dev_pm_set_wake_irq(dev, client->irq);
> > +       }
> >
> >         return 0;
> >  }
> > @@ -1362,8 +1363,6 @@ static int __maybe_unused elan_suspend(struct device *dev)
> >
> >         if (device_may_wakeup(dev)) {
> >                 ret = elan_sleep(data);
> > -               /* Enable wake from IRQ */
> > -               data->irq_wake = (enable_irq_wake(client->irq) == 0);
> >         } else {
> >                 ret = elan_set_power(data, false);
> >                 if (ret)
> > @@ -1394,9 +1393,6 @@ static int __maybe_unused elan_resume(struct device *dev)
> >                         dev_err(dev, "error %d enabling regulator\n", error);
> >                         goto err;
> >                 }
> > -       } else if (data->irq_wake) {
> > -               disable_irq_wake(client->irq);
> > -               data->irq_wake = false;
> >         }
> >
> >         error = elan_set_power(data, true);
> > --
> > 2.37.2.672.g94769d06f0-goog
> >

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 18:13     ` Raul Rangel
@ 2022-08-31 18:42       ` Rafael J. Wysocki
  2022-09-01  6:57         ` Tony Lindgren
  0 siblings, 1 reply; 31+ messages in thread
From: Rafael J. Wysocki @ 2022-08-31 18:42 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, Tim Van Patten,
	Dmitry Torokhov, jingle.wu, Linux Kernel Mailing List,
	Tony Lindgren

On Wed, Aug 31, 2022 at 8:14 PM Raul Rangel <rrangel@chromium.org> wrote:
>
> On Wed, Aug 31, 2022 at 12:01 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> >
> > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > >
> > > The Elan I2C touchpad driver is currently manually managing the wake
> > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > and instead relies on the PM subsystem. This is done by calling
> > > dev_pm_set_wake_irq.
> > >
> > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > tree, so it's only required when using ACPI. The net result is that this
> > > change should be a no-op. i2c_device_remove also already calls
> > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > >
> > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > defined. I verified I can still wake the system and that the wake source
> > > was the touchpad IRQ GPIO.
> > >
> > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> >
>
>
> > I like this a lot, but the assumption in the wakeirq code is that the
> > IRQ in question will be dedicated for signaling wakeup.  Does it hold
> > here?
>
> The wakeirq code defines two methods: `dev_pm_set_wake_irq` and
> `dev_pm_set_dedicated_wake_irq`.
> The latter is used when you have a dedicated wakeup signal. In this
> driver it's currently assumed
> that the IRQ and the wake IRQ are the same, so I used `dev_pm_set_wake_irq`.
>
> This change in theory also fixes a bug where you define a dedicated
> wake irq in DT, but
> then the driver enables the `client->irq` as a wake source. In
> practice this doesn't happen
> since the elan touchpads only have a single IRQ line.

OK, thanks!

Please feel free to add

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

to the patch.

> >
> > > ---
> > >
> > >  drivers/input/mouse/elan_i2c_core.c | 12 ++++--------
> > >  1 file changed, 4 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
> > > index e1758d5ffe4218..7d997d2b56436b 100644
> > > --- a/drivers/input/mouse/elan_i2c_core.c
> > > +++ b/drivers/input/mouse/elan_i2c_core.c
> > > @@ -33,6 +33,7 @@
> > >  #include <linux/jiffies.h>
> > >  #include <linux/completion.h>
> > >  #include <linux/of.h>
> > > +#include <linux/pm_wakeirq.h>
> > >  #include <linux/property.h>
> > >  #include <linux/regulator/consumer.h>
> > >  #include <asm/unaligned.h>
> > > @@ -86,8 +87,6 @@ struct elan_tp_data {
> > >         u16                     fw_page_size;
> > >         u32                     fw_signature_address;
> > >
> > > -       bool                    irq_wake;
> > > -
> > >         u8                      min_baseline;
> > >         u8                      max_baseline;
> > >         bool                    baseline_ready;
> > > @@ -1337,8 +1336,10 @@ static int elan_probe(struct i2c_client *client,
> > >          * Systems using device tree should set up wakeup via DTS,
> > >          * the rest will configure device as wakeup source by default.
> > >          */
> > > -       if (!dev->of_node)
> > > +       if (!dev->of_node) {
> > >                 device_init_wakeup(dev, true);
> > > +               dev_pm_set_wake_irq(dev, client->irq);
> > > +       }
> > >
> > >         return 0;
> > >  }
> > > @@ -1362,8 +1363,6 @@ static int __maybe_unused elan_suspend(struct device *dev)
> > >
> > >         if (device_may_wakeup(dev)) {
> > >                 ret = elan_sleep(data);
> > > -               /* Enable wake from IRQ */
> > > -               data->irq_wake = (enable_irq_wake(client->irq) == 0);
> > >         } else {
> > >                 ret = elan_set_power(data, false);
> > >                 if (ret)
> > > @@ -1394,9 +1393,6 @@ static int __maybe_unused elan_resume(struct device *dev)
> > >                         dev_err(dev, "error %d enabling regulator\n", error);
> > >                         goto err;
> > >                 }
> > > -       } else if (data->irq_wake) {
> > > -               disable_irq_wake(client->irq);
> > > -               data->irq_wake = false;
> > >         }
> > >
> > >         error = elan_set_power(data, true);
> > > --
> > > 2.37.2.672.g94769d06f0-goog
> > >

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 18:01   ` Rafael J. Wysocki
  2022-08-31 18:13     ` Raul Rangel
@ 2022-08-31 19:12     ` Dmitry Torokhov
  2022-08-31 19:16       ` Dmitry Torokhov
  1 sibling, 1 reply; 31+ messages in thread
From: Dmitry Torokhov @ 2022-08-31 19:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Raul E Rangel, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, timvp, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> >
> > The Elan I2C touchpad driver is currently manually managing the wake
> > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > and instead relies on the PM subsystem. This is done by calling
> > dev_pm_set_wake_irq.
> >
> > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > tree, so it's only required when using ACPI. The net result is that this
> > change should be a no-op. i2c_device_remove also already calls
> > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> >
> > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > defined. I verified I can still wake the system and that the wake source
> > was the touchpad IRQ GPIO.
> >
> > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> 
> I like this a lot [...]

I also like this a lot, but this assumes that firmware has correct
settings for the interrupt... Unfortunately it is not always the case
and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
ect) do not mark interrupt as wakeup:

src/mainboard/google/glados/variants/chell/overridetree.cb

                        chip drivers/i2c/generic
                                register "hid" = ""ELAN0000""
                                register "desc" = ""ELAN Touchpad""
                                register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
                                register "wake" = "GPE0_DW0_05"
                                device i2c 15 on end

I assume it should have been ACPI_IRQ_WAKE_LEVEL_LOW for the interrupt
to be marked as wakeup.

(we do correctly mark GPE as wakeup).

So we need to do something about older devices....

-- 
Dmitry

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 19:12     ` Dmitry Torokhov
@ 2022-08-31 19:16       ` Dmitry Torokhov
  2022-09-01  2:17         ` Raul Rangel
  0 siblings, 1 reply; 31+ messages in thread
From: Dmitry Torokhov @ 2022-08-31 19:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Raul E Rangel, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, timvp, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 12:12:41PM -0700, Dmitry Torokhov wrote:
> On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > >
> > > The Elan I2C touchpad driver is currently manually managing the wake
> > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > and instead relies on the PM subsystem. This is done by calling
> > > dev_pm_set_wake_irq.
> > >
> > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > tree, so it's only required when using ACPI. The net result is that this
> > > change should be a no-op. i2c_device_remove also already calls
> > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > >
> > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > defined. I verified I can still wake the system and that the wake source
> > > was the touchpad IRQ GPIO.
> > >
> > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > 
> > I like this a lot [...]
> 
> I also like this a lot, but this assumes that firmware has correct
> settings for the interrupt... Unfortunately it is not always the case
> and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
> ect) do not mark interrupt as wakeup:
> 
> src/mainboard/google/glados/variants/chell/overridetree.cb
> 
>                         chip drivers/i2c/generic
>                                 register "hid" = ""ELAN0000""
>                                 register "desc" = ""ELAN Touchpad""
>                                 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
>                                 register "wake" = "GPE0_DW0_05"
>                                 device i2c 15 on end
> 
> I assume it should have been ACPI_IRQ_WAKE_LEVEL_LOW for the interrupt
> to be marked as wakeup.
> 
> (we do correctly mark GPE as wakeup).
> 
> So we need to do something about older devices....

After re-reading the patch I believe this comment is more applicable to
the followup patch to elan_i2c, not this one, which is fine on its own.

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Thanks.

-- 
Dmitry

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 19:16       ` Dmitry Torokhov
@ 2022-09-01  2:17         ` Raul Rangel
  2022-09-03  5:06           ` Dmitry Torokhov
  0 siblings, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-09-01  2:17 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, Tim Van Patten, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 1:16 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> On Wed, Aug 31, 2022 at 12:12:41PM -0700, Dmitry Torokhov wrote:
> > On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> > > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > > >
> > > > The Elan I2C touchpad driver is currently manually managing the wake
> > > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > > and instead relies on the PM subsystem. This is done by calling
> > > > dev_pm_set_wake_irq.
> > > >
> > > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > > tree, so it's only required when using ACPI. The net result is that this
> > > > change should be a no-op. i2c_device_remove also already calls
> > > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > > >
> > > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > > defined. I verified I can still wake the system and that the wake source
> > > > was the touchpad IRQ GPIO.
> > > >
> > > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > >
> > > I like this a lot [...]
> >

> > I also like this a lot, but this assumes that firmware has correct
> > settings for the interrupt... Unfortunately it is not always the case
> > and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
> > ect) do not mark interrupt as wakeup:
> >
> > src/mainboard/google/glados/variants/chell/overridetree.cb
> >
> >                         chip drivers/i2c/generic
> >                                 register "hid" = ""ELAN0000""
> >                                 register "desc" = ""ELAN Touchpad""
> >                                 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
> >                                 register "wake" = "GPE0_DW0_05"
> >                                 device i2c 15 on end
> >

So the above entry specifies the `wake` register. This generates an
ACPI _PRW resource. The patch series will actually fix devices like
this. Today without this patch series we get two wake events for a
device. The ACPI wake GPE specified by the _PRW resource, and the
erroneous GPIO wake event. But you bring up a good point.

I wrote a quick and dirty script (https://0paste.com/391849) to parse
the coreboot device tree entries. Open source firmware is great isn't
it? ;)

$ find src/mainboard/google/ -iname '*.cb' | xargs awk -f touch.awk --
src/mainboard/google/eve/devicetree.cb
1
chip drivers/i2c/hid
register "generic.hid" = ""ACPI0C50""
register "generic.desc" = ""Touchpad""
register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
register "hid_desc_reg_offset" = "0x1"
device i2c 49 on end
end
src/mainboard/google/eve/devicetree.cb
1
chip drivers/i2c/generic
register "hid" = ""GOOG0008""
register "desc" = ""Touchpad EC Interface""
device i2c 1e on end
end
src/mainboard/google/drallion/variants/drallion/devicetree.cb
1
chip drivers/i2c/generic
register "hid" = ""ELAN0000""
register "desc" = ""ELAN Touchpad""
register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
register "probed" = "1"
device i2c 2c on end
end
src/mainboard/google/drallion/variants/drallion/devicetree.cb
1
chip drivers/i2c/generic
register "hid" = ""ELAN0000""
register "desc" = ""ELAN Touchpad""
register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
register "probed" = "1"
device i2c 15 on end
end
src/mainboard/google/sarien/variants/arcada/devicetree.cb
1
chip drivers/i2c/generic
register "hid" = ""ELAN0000""
register "desc" = ""ELAN Touchpad""
register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
register "probed" = "1"
device i2c 2c on end
end
src/mainboard/google/sarien/variants/arcada/devicetree.cb
1
chip drivers/i2c/hid
register "generic.hid" = ""PNP0C50""
register "generic.desc" = ""Cirque Touchpad""
register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
register "generic.probed" = "1"
register "hid_desc_reg_offset" = "0x20"
device i2c 2a on end
end
src/mainboard/google/sarien/variants/sarien/devicetree.cb
1
chip drivers/i2c/generic
register "hid" = ""ELAN0000""
register "desc" = ""ELAN Touchpad""
register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
register "probed" = "1"
device i2c 2c on end
end
Total Touchpad: 202
Total Wake: 195

Out of all the touchpads defined on ChromeOS it looks like only 4
devices are missing a wake declaration. I omitted touchpanels because
ChromeOS doesn't use those as a wake source. chromeos_laptop.c already
defines some devices with i2c board_info and it sets the
`I2C_CLIENT_WAKE` flag. I'm not sure if this is actually working as
expected. `i2c_device_probe` requires a `wakeup` irq to be present in
the device tree if the `I2C_CLIENT_WAKE` flag is set, but I'm assuming
the device tree was missing wake attributes.

Anyway, patches 6, and 7 are the ones that drop the legacy behavior. I
can figure out how to add the above boards to chromeos_laptop.c and
get the wake attribute plumbed, or I can add something directly to the
elan_i2c_core, etc so others can add overrides for their boards there.
I'll also send out CLs to fix the device tree configs (not that we
would run a FW qual just for this change).


> > I assume it should have been ACPI_IRQ_WAKE_LEVEL_LOW for the interrupt
> > to be marked as wakeup.
> >
> > (we do correctly mark GPE as wakeup).
> >
> > So we need to do something about older devices....
>
> After re-reading the patch I believe this comment is more applicable to
> the followup patch to elan_i2c, not this one, which is fine on its own.
>
> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>
> Thanks.
>
> --
> Dmitry

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-08-31 18:42       ` Rafael J. Wysocki
@ 2022-09-01  6:57         ` Tony Lindgren
  0 siblings, 0 replies; 31+ messages in thread
From: Tony Lindgren @ 2022-09-01  6:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Raul Rangel, ACPI Devel Maling List, linux-input, Hans de Goede,
	Mario Limonciello, Tim Van Patten, Dmitry Torokhov, jingle.wu,
	Linux Kernel Mailing List

* Rafael J. Wysocki <rafael@kernel.org> [220831 18:35]:
> On Wed, Aug 31, 2022 at 8:14 PM Raul Rangel <rrangel@chromium.org> wrote:
> >
> > On Wed, Aug 31, 2022 at 12:01 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > >
> > > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > > >
> > > > The Elan I2C touchpad driver is currently manually managing the wake
> > > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > > and instead relies on the PM subsystem. This is done by calling
> > > > dev_pm_set_wake_irq.
> > > >
> > > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > > tree, so it's only required when using ACPI. The net result is that this
> > > > change should be a no-op. i2c_device_remove also already calls
> > > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > > >
> > > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > > defined. I verified I can still wake the system and that the wake source
> > > > was the touchpad IRQ GPIO.
> > > >
> > > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > >
> >
> >
> > > I like this a lot, but the assumption in the wakeirq code is that the
> > > IRQ in question will be dedicated for signaling wakeup.  Does it hold
> > > here?
> >
> > The wakeirq code defines two methods: `dev_pm_set_wake_irq` and
> > `dev_pm_set_dedicated_wake_irq`.
> > The latter is used when you have a dedicated wakeup signal. In this
> > driver it's currently assumed
> > that the IRQ and the wake IRQ are the same, so I used `dev_pm_set_wake_irq`.
> >
> > This change in theory also fixes a bug where you define a dedicated
> > wake irq in DT, but
> > then the driver enables the `client->irq` as a wake source. In
> > practice this doesn't happen
> > since the elan touchpads only have a single IRQ line.
> 
> OK, thanks!
> 
> Please feel free to add
> 
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> to the patch.

Looks good to me too:

Reviewed-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-09-01  2:17         ` Raul Rangel
@ 2022-09-03  5:06           ` Dmitry Torokhov
  2022-09-06 17:18             ` Raul Rangel
  0 siblings, 1 reply; 31+ messages in thread
From: Dmitry Torokhov @ 2022-09-03  5:06 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, Tim Van Patten, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Wed, Aug 31, 2022 at 08:17:23PM -0600, Raul Rangel wrote:
> On Wed, Aug 31, 2022 at 1:16 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > On Wed, Aug 31, 2022 at 12:12:41PM -0700, Dmitry Torokhov wrote:
> > > On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> > > > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > > > >
> > > > > The Elan I2C touchpad driver is currently manually managing the wake
> > > > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > > > and instead relies on the PM subsystem. This is done by calling
> > > > > dev_pm_set_wake_irq.
> > > > >
> > > > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > > > tree, so it's only required when using ACPI. The net result is that this
> > > > > change should be a no-op. i2c_device_remove also already calls
> > > > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > > > >
> > > > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > > > defined. I verified I can still wake the system and that the wake source
> > > > > was the touchpad IRQ GPIO.
> > > > >
> > > > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > > >
> > > > I like this a lot [...]
> > >
> 
> > > I also like this a lot, but this assumes that firmware has correct
> > > settings for the interrupt... Unfortunately it is not always the case
> > > and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
> > > ect) do not mark interrupt as wakeup:
> > >
> > > src/mainboard/google/glados/variants/chell/overridetree.cb
> > >
> > >                         chip drivers/i2c/generic
> > >                                 register "hid" = ""ELAN0000""
> > >                                 register "desc" = ""ELAN Touchpad""
> > >                                 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
> > >                                 register "wake" = "GPE0_DW0_05"
> > >                                 device i2c 15 on end
> > >
> 
> So the above entry specifies the `wake` register. This generates an
> ACPI _PRW resource. The patch series will actually fix devices like
> this. Today without this patch series we get two wake events for a
> device. The ACPI wake GPE specified by the _PRW resource, and the
> erroneous GPIO wake event. But you bring up a good point.

Does this mean that the example that we currently have in coreboot
documentation (Documentation/acpi/devicetree.md) is not correct:

device pci 15.0 on
        chip drivers/i2c/generic
                register "hid" = ""ELAN0000""
                register "desc" = ""ELAN Touchpad""
                register "irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_A21_IRQ)"
                register "wake" = "GPE0_DW0_21"
                device i2c 15 on end
        end
end # I2C #0

Doesn't in say that we have both GpioIrq and GPE wakeup methods defined
for the same device?

> 
> I wrote a quick and dirty script (https://0paste.com/391849) to parse
> the coreboot device tree entries. Open source firmware is great isn't
> it? ;)
> 
> $ find src/mainboard/google/ -iname '*.cb' | xargs awk -f touch.awk --
> src/mainboard/google/eve/devicetree.cb

...

> src/mainboard/google/sarien/variants/sarien/devicetree.cb
> 1
> chip drivers/i2c/generic
> register "hid" = ""ELAN0000""
> register "desc" = ""ELAN Touchpad""
> register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
> register "probed" = "1"
> device i2c 2c on end
> end
> Total Touchpad: 202
> Total Wake: 195
> 
> Out of all the touchpads defined on ChromeOS it looks like only 4
> devices are missing a wake declaration. I omitted touchpanels because
> ChromeOS doesn't use those as a wake source. chromeos_laptop.c already
> defines some devices with i2c board_info and it sets the
> `I2C_CLIENT_WAKE` flag. I'm not sure if this is actually working as
> expected. `i2c_device_probe` requires a `wakeup` irq to be present in
> the device tree if the `I2C_CLIENT_WAKE` flag is set, but I'm assuming

No it does not. If there is no wakeup IRQ defined of_irq_get_byname()
will return an error and we'll take the "else if (client->irq > 0)"
branch and will set up client->irq as the wakeup irq.

> the device tree was missing wake attributes.

> 
> Anyway, patches 6, and 7 are the ones that drop the legacy behavior. I
> can figure out how to add the above boards to chromeos_laptop.c and
> get the wake attribute plumbed, or I can add something directly to the
> elan_i2c_core, etc so others can add overrides for their boards there.
> I'll also send out CLs to fix the device tree configs (not that we
> would run a FW qual just for this change).

My preference is to limit board-specific hacks in drivers if we can, so
adding missing properties to chromeos_laptop.c would be my preference.

Thanks.

-- 
Dmitry

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-09-03  5:06           ` Dmitry Torokhov
@ 2022-09-06 17:18             ` Raul Rangel
  2022-09-06 18:40               ` Dmitry Torokhov
  0 siblings, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-09-06 17:18 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, Tim Van Patten, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Fri, Sep 2, 2022 at 11:07 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> On Wed, Aug 31, 2022 at 08:17:23PM -0600, Raul Rangel wrote:
> > On Wed, Aug 31, 2022 at 1:16 PM Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> > >
> > > On Wed, Aug 31, 2022 at 12:12:41PM -0700, Dmitry Torokhov wrote:
> > > > On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> > > > > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > > > > >
> > > > > > The Elan I2C touchpad driver is currently manually managing the wake
> > > > > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > > > > and instead relies on the PM subsystem. This is done by calling
> > > > > > dev_pm_set_wake_irq.
> > > > > >
> > > > > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > > > > tree, so it's only required when using ACPI. The net result is that this
> > > > > > change should be a no-op. i2c_device_remove also already calls
> > > > > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > > > > >
> > > > > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > > > > defined. I verified I can still wake the system and that the wake source
> > > > > > was the touchpad IRQ GPIO.
> > > > > >
> > > > > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > > > >
> > > > > I like this a lot [...]
> > > >
> >
> > > > I also like this a lot, but this assumes that firmware has correct
> > > > settings for the interrupt... Unfortunately it is not always the case
> > > > and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
> > > > ect) do not mark interrupt as wakeup:
> > > >
> > > > src/mainboard/google/glados/variants/chell/overridetree.cb
> > > >
> > > >                         chip drivers/i2c/generic
> > > >                                 register "hid" = ""ELAN0000""
> > > >                                 register "desc" = ""ELAN Touchpad""
> > > >                                 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
> > > >                                 register "wake" = "GPE0_DW0_05"
> > > >                                 device i2c 15 on end
> > > >
> >
> > So the above entry specifies the `wake` register. This generates an
> > ACPI _PRW resource. The patch series will actually fix devices like
> > this. Today without this patch series we get two wake events for a
> > device. The ACPI wake GPE specified by the _PRW resource, and the
> > erroneous GPIO wake event. But you bring up a good point.
>


> Does this mean that the example that we currently have in coreboot
> documentation (Documentation/acpi/devicetree.md) is not correct:
>
> device pci 15.0 on
>         chip drivers/i2c/generic
>                 register "hid" = ""ELAN0000""
>                 register "desc" = ""ELAN Touchpad""
>                 register "irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_A21_IRQ)"
>                 register "wake" = "GPE0_DW0_21"
>                 device i2c 15 on end
>         end
> end # I2C #0
>
> Doesn't in say that we have both GpioIrq and GPE wakeup methods defined
> for the same device?

Hrmm, yeah that is wrong and will cause duplicate wake events for the
device. I'll push a CL to clean up the documentation.

>
> >
> > I wrote a quick and dirty script (https://0paste.com/391849) to parse
> > the coreboot device tree entries. Open source firmware is great isn't
> > it? ;)
> >
> > $ find src/mainboard/google/ -iname '*.cb' | xargs awk -f touch.awk --
> > src/mainboard/google/eve/devicetree.cb
>
> ...
>
> > src/mainboard/google/sarien/variants/sarien/devicetree.cb
> > 1
> > chip drivers/i2c/generic
> > register "hid" = ""ELAN0000""
> > register "desc" = ""ELAN Touchpad""
> > register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
> > register "probed" = "1"
> > device i2c 2c on end
> > end
> > Total Touchpad: 202
> > Total Wake: 195
> >
> > Out of all the touchpads defined on ChromeOS it looks like only 4
> > devices are missing a wake declaration. I omitted touchpanels because
> > ChromeOS doesn't use those as a wake source. chromeos_laptop.c already
> > defines some devices with i2c board_info and it sets the
> > `I2C_CLIENT_WAKE` flag. I'm not sure if this is actually working as
> > expected. `i2c_device_probe` requires a `wakeup` irq to be present in
> > the device tree if the `I2C_CLIENT_WAKE` flag is set, but I'm assuming
>
> No it does not. If there is no wakeup IRQ defined of_irq_get_byname()
> will return an error and we'll take the "else if (client->irq > 0)"
> branch and will set up client->irq as the wakeup irq.
>
> > the device tree was missing wake attributes.

Oh thanks for pointing that out. I might refactor patch #4 to just set
the `I2C_CLIENT_WAKE` flag when `acpi_wake_capable` is true.

>
> >
> > Anyway, patches 6, and 7 are the ones that drop the legacy behavior. I
> > can figure out how to add the above boards to chromeos_laptop.c and
> > get the wake attribute plumbed, or I can add something directly to the
> > elan_i2c_core, etc so others can add overrides for their boards there.
> > I'll also send out CLs to fix the device tree configs (not that we
> > would run a FW qual just for this change).
>
> My preference is to limit board-specific hacks in drivers if we can, so
> adding missing properties to chromeos_laptop.c would be my preference.

How should we handle non chromeos boards?

>
> Thanks.
>
> --
> Dmitry

Thanks!

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

* Re: [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage wake irq
  2022-09-06 17:18             ` Raul Rangel
@ 2022-09-06 18:40               ` Dmitry Torokhov
  0 siblings, 0 replies; 31+ messages in thread
From: Dmitry Torokhov @ 2022-09-06 18:40 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Rafael J. Wysocki, ACPI Devel Maling List, linux-input,
	Hans de Goede, Mario Limonciello, Tim Van Patten, jingle.wu,
	Linux Kernel Mailing List, Tony Lindgren

On Tue, Sep 06, 2022 at 11:18:49AM -0600, Raul Rangel wrote:
> On Fri, Sep 2, 2022 at 11:07 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > On Wed, Aug 31, 2022 at 08:17:23PM -0600, Raul Rangel wrote:
> > > On Wed, Aug 31, 2022 at 1:16 PM Dmitry Torokhov
> > > <dmitry.torokhov@gmail.com> wrote:
> > > >
> > > > On Wed, Aug 31, 2022 at 12:12:41PM -0700, Dmitry Torokhov wrote:
> > > > > On Wed, Aug 31, 2022 at 08:01:12PM +0200, Rafael J. Wysocki wrote:
> > > > > > On Wed, Aug 31, 2022 at 1:16 AM Raul E Rangel <rrangel@chromium.org> wrote:
> > > > > > >
> > > > > > > The Elan I2C touchpad driver is currently manually managing the wake
> > > > > > > IRQ. This change removes the explicit enable_irq_wake/disable_irq_wake
> > > > > > > and instead relies on the PM subsystem. This is done by calling
> > > > > > > dev_pm_set_wake_irq.
> > > > > > >
> > > > > > > i2c_device_probe already calls dev_pm_set_wake_irq when using device
> > > > > > > tree, so it's only required when using ACPI. The net result is that this
> > > > > > > change should be a no-op. i2c_device_remove also already calls
> > > > > > > dev_pm_clear_wake_irq, so we don't need to do that in this driver.
> > > > > > >
> > > > > > > I tested this on an ACPI system where the touchpad doesn't have _PRW
> > > > > > > defined. I verified I can still wake the system and that the wake source
> > > > > > > was the touchpad IRQ GPIO.
> > > > > > >
> > > > > > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > > > > >
> > > > > > I like this a lot [...]
> > > > >
> > >
> > > > > I also like this a lot, but this assumes that firmware has correct
> > > > > settings for the interrupt... Unfortunately it is not always the case
> > > > > and I see that at least Chrome OS devices, such as glados line (cave, chell, sentry,
> > > > > ect) do not mark interrupt as wakeup:
> > > > >
> > > > > src/mainboard/google/glados/variants/chell/overridetree.cb
> > > > >
> > > > >                         chip drivers/i2c/generic
> > > > >                                 register "hid" = ""ELAN0000""
> > > > >                                 register "desc" = ""ELAN Touchpad""
> > > > >                                 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
> > > > >                                 register "wake" = "GPE0_DW0_05"
> > > > >                                 device i2c 15 on end
> > > > >
> > >
> > > So the above entry specifies the `wake` register. This generates an
> > > ACPI _PRW resource. The patch series will actually fix devices like
> > > this. Today without this patch series we get two wake events for a
> > > device. The ACPI wake GPE specified by the _PRW resource, and the
> > > erroneous GPIO wake event. But you bring up a good point.
> >
> 
> 
> > Does this mean that the example that we currently have in coreboot
> > documentation (Documentation/acpi/devicetree.md) is not correct:
> >
> > device pci 15.0 on
> >         chip drivers/i2c/generic
> >                 register "hid" = ""ELAN0000""
> >                 register "desc" = ""ELAN Touchpad""
> >                 register "irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_A21_IRQ)"
> >                 register "wake" = "GPE0_DW0_21"
> >                 device i2c 15 on end
> >         end
> > end # I2C #0
> >
> > Doesn't in say that we have both GpioIrq and GPE wakeup methods defined
> > for the same device?
> 
> Hrmm, yeah that is wrong and will cause duplicate wake events for the
> device. I'll push a CL to clean up the documentation.

Thanks. I think we also need to clean up our ADL boards (and likely
more).

> 
> >
> > >
> > > I wrote a quick and dirty script (https://0paste.com/391849) to parse
> > > the coreboot device tree entries. Open source firmware is great isn't
> > > it? ;)
> > >
> > > $ find src/mainboard/google/ -iname '*.cb' | xargs awk -f touch.awk --
> > > src/mainboard/google/eve/devicetree.cb
> >
> > ...
> >
> > > src/mainboard/google/sarien/variants/sarien/devicetree.cb
> > > 1
> > > chip drivers/i2c/generic
> > > register "hid" = ""ELAN0000""
> > > register "desc" = ""ELAN Touchpad""
> > > register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B3_IRQ)"
> > > register "probed" = "1"
> > > device i2c 2c on end
> > > end
> > > Total Touchpad: 202
> > > Total Wake: 195
> > >
> > > Out of all the touchpads defined on ChromeOS it looks like only 4
> > > devices are missing a wake declaration. I omitted touchpanels because
> > > ChromeOS doesn't use those as a wake source. chromeos_laptop.c already
> > > defines some devices with i2c board_info and it sets the
> > > `I2C_CLIENT_WAKE` flag. I'm not sure if this is actually working as
> > > expected. `i2c_device_probe` requires a `wakeup` irq to be present in
> > > the device tree if the `I2C_CLIENT_WAKE` flag is set, but I'm assuming
> >
> > No it does not. If there is no wakeup IRQ defined of_irq_get_byname()
> > will return an error and we'll take the "else if (client->irq > 0)"
> > branch and will set up client->irq as the wakeup irq.
> >
> > > the device tree was missing wake attributes.
> 
> Oh thanks for pointing that out. I might refactor patch #4 to just set
> the `I2C_CLIENT_WAKE` flag when `acpi_wake_capable` is true.
> 
> >
> > >
> > > Anyway, patches 6, and 7 are the ones that drop the legacy behavior. I
> > > can figure out how to add the above boards to chromeos_laptop.c and
> > > get the wake attribute plumbed, or I can add something directly to the
> > > elan_i2c_core, etc so others can add overrides for their boards there.
> > > I'll also send out CLs to fix the device tree configs (not that we
> > > would run a FW qual just for this change).
> >
> > My preference is to limit board-specific hacks in drivers if we can, so
> > adding missing properties to chromeos_laptop.c would be my preference.
> 
> How should we handle non chromeos boards?

My preference would be to shove something like chromeos_laptop into
drivers/platform/x86... Something like
drivers/platform/x86/x86-android-tablets.c

Thanks.

-- 
Dmitry

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-08-30 23:15 ` [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq Raul E Rangel
@ 2022-09-07  1:00   ` Dmitry Torokhov
  2022-09-07  2:00     ` Raul Rangel
  0 siblings, 1 reply; 31+ messages in thread
From: Dmitry Torokhov @ 2022-09-07  1:00 UTC (permalink / raw)
  To: Raul E Rangel
  Cc: linux-acpi, linux-input, hdegoede, mario.limonciello, timvp,
	rafael, Mika Westerberg, Wolfram Sang, linux-i2c, linux-kernel

On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> Device tree already has a mechanism to pass the wake_irq. It does this
> by looking for the wakeup-source property and setting the
> I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> the system. Previously the i2c drivers had to make assumptions and
> blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> If there is a device with an Active Low interrupt and the device gets
> powered off while suspending, the interrupt line will go low since it's
> no longer powered and wake the system. For this reason we should respect
> the board designers wishes and honor the wake bit defined on the
> GpioInt.
> 
> This change does not cover the ACPI Interrupt or IRQ resources.
> 
> Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> ---
> 
>  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
>  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
>  drivers/i2c/i2c-core.h      |  4 ++--
>  3 files changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> index c762a879c4cc6b..cfe82a6ba3ef28 100644
> --- a/drivers/i2c/i2c-core-acpi.c
> +++ b/drivers/i2c/i2c-core-acpi.c
> @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
>  /**
>   * i2c_acpi_get_irq - get device IRQ number from ACPI
>   * @client: Pointer to the I2C client device
> + * @wake_capable: Set to 1 if the IRQ is wake capable
>   *
>   * Find the IRQ number used by a specific client device.
>   *
>   * Return: The IRQ number or an error code.
>   */
> -int i2c_acpi_get_irq(struct i2c_client *client)
> +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
>  {
>  	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
>  	struct list_head resource_list;
> @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
>  
>  	INIT_LIST_HEAD(&resource_list);
>  
> +	if (wake_capable)
> +		*wake_capable = 0;
> +
>  	ret = acpi_dev_get_resources(adev, &resource_list,
>  				     i2c_acpi_add_resource, &irq);

You also need to handle "Interrupt(..., ...AndWake)" case here. I would
look into maybe defining

#define IORESOURCE_IRQ_WAKECAPABLE	(1<<6)

in include/linux/ioport.h and plumbing it through from ACPI layer.

Thanks.

-- 
Dmitry

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-07  1:00   ` Dmitry Torokhov
@ 2022-09-07  2:00     ` Raul Rangel
  2022-09-07  2:04       ` Dmitry Torokhov
  2022-09-07  8:12       ` Hans de Goede
  0 siblings, 2 replies; 31+ messages in thread
From: Raul Rangel @ 2022-09-07  2:00 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Linux ACPI, linux-input, Hans de Goede, Limonciello, Mario,
	Tim Van Patten, Rafael J. Wysocki, Mika Westerberg, Wolfram Sang,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> > Device tree already has a mechanism to pass the wake_irq. It does this
> > by looking for the wakeup-source property and setting the
> > I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> > ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> > the system. Previously the i2c drivers had to make assumptions and
> > blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> > If there is a device with an Active Low interrupt and the device gets
> > powered off while suspending, the interrupt line will go low since it's
> > no longer powered and wake the system. For this reason we should respect
> > the board designers wishes and honor the wake bit defined on the
> > GpioInt.
> >
> > This change does not cover the ACPI Interrupt or IRQ resources.
> >
> > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > ---
> >
> >  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
> >  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
> >  drivers/i2c/i2c-core.h      |  4 ++--
> >  3 files changed, 19 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> > index c762a879c4cc6b..cfe82a6ba3ef28 100644
> > --- a/drivers/i2c/i2c-core-acpi.c
> > +++ b/drivers/i2c/i2c-core-acpi.c
> > @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
> >  /**
> >   * i2c_acpi_get_irq - get device IRQ number from ACPI
> >   * @client: Pointer to the I2C client device
> > + * @wake_capable: Set to 1 if the IRQ is wake capable
> >   *
> >   * Find the IRQ number used by a specific client device.
> >   *
> >   * Return: The IRQ number or an error code.
> >   */
> > -int i2c_acpi_get_irq(struct i2c_client *client)
> > +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
> >  {
> >       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> >       struct list_head resource_list;
> > @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
> >
> >       INIT_LIST_HEAD(&resource_list);
> >
> > +     if (wake_capable)
> > +             *wake_capable = 0;
> > +
> >       ret = acpi_dev_get_resources(adev, &resource_list,
> >                                    i2c_acpi_add_resource, &irq);
>


> You also need to handle "Interrupt(..., ...AndWake)" case here. I would
> look into maybe defining
>
> #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
>
> in include/linux/ioport.h and plumbing it through from ACPI layer.
>
> Thanks.

AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
wake a system from suspend/suspend-to-idle. It requires either a GPE
or GPIO controller to wake the system. This is the reason I haven't
pushed patches to handle the Interrupt/IRQ resource. Can anyone
confirm?

Thanks

>
> --
> Dmitry

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-07  2:00     ` Raul Rangel
@ 2022-09-07  2:04       ` Dmitry Torokhov
  2022-09-07  8:12       ` Hans de Goede
  1 sibling, 0 replies; 31+ messages in thread
From: Dmitry Torokhov @ 2022-09-07  2:04 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Linux ACPI, linux-input, Hans de Goede, Limonciello, Mario,
	Tim Van Patten, Rafael J. Wysocki, Mika Westerberg, Wolfram Sang,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

On Tue, Sep 06, 2022 at 08:00:00PM -0600, Raul Rangel wrote:
> On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> > > Device tree already has a mechanism to pass the wake_irq. It does this
> > > by looking for the wakeup-source property and setting the
> > > I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> > > ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> > > the system. Previously the i2c drivers had to make assumptions and
> > > blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> > > If there is a device with an Active Low interrupt and the device gets
> > > powered off while suspending, the interrupt line will go low since it's
> > > no longer powered and wake the system. For this reason we should respect
> > > the board designers wishes and honor the wake bit defined on the
> > > GpioInt.
> > >
> > > This change does not cover the ACPI Interrupt or IRQ resources.
> > >
> > > Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > > ---
> > >
> > >  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
> > >  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
> > >  drivers/i2c/i2c-core.h      |  4 ++--
> > >  3 files changed, 19 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> > > index c762a879c4cc6b..cfe82a6ba3ef28 100644
> > > --- a/drivers/i2c/i2c-core-acpi.c
> > > +++ b/drivers/i2c/i2c-core-acpi.c
> > > @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
> > >  /**
> > >   * i2c_acpi_get_irq - get device IRQ number from ACPI
> > >   * @client: Pointer to the I2C client device
> > > + * @wake_capable: Set to 1 if the IRQ is wake capable
> > >   *
> > >   * Find the IRQ number used by a specific client device.
> > >   *
> > >   * Return: The IRQ number or an error code.
> > >   */
> > > -int i2c_acpi_get_irq(struct i2c_client *client)
> > > +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
> > >  {
> > >       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> > >       struct list_head resource_list;
> > > @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
> > >
> > >       INIT_LIST_HEAD(&resource_list);
> > >
> > > +     if (wake_capable)
> > > +             *wake_capable = 0;
> > > +
> > >       ret = acpi_dev_get_resources(adev, &resource_list,
> > >                                    i2c_acpi_add_resource, &irq);
> >
> 
> 
> > You also need to handle "Interrupt(..., ...AndWake)" case here. I would
> > look into maybe defining
> >
> > #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
> >
> > in include/linux/ioport.h and plumbing it through from ACPI layer.
> >
> > Thanks.
> 
> AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
> wake a system from suspend/suspend-to-idle. It requires either a GPE
> or GPIO controller to wake the system. This is the reason I haven't
> pushed patches to handle the Interrupt/IRQ resource. Can anyone
> confirm?

I've heard there are ARM ACPI systems...

Thanks.

-- 
Dmitry

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-07  2:00     ` Raul Rangel
  2022-09-07  2:04       ` Dmitry Torokhov
@ 2022-09-07  8:12       ` Hans de Goede
  2022-09-08 14:40         ` Raul Rangel
  1 sibling, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2022-09-07  8:12 UTC (permalink / raw)
  To: Raul Rangel, Dmitry Torokhov
  Cc: Linux ACPI, linux-input, Limonciello, Mario, Tim Van Patten,
	Rafael J. Wysocki, Mika Westerberg, Wolfram Sang,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

Hi,

On 9/7/22 04:00, Raul Rangel wrote:
> On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
>>
>> On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
>>> Device tree already has a mechanism to pass the wake_irq. It does this
>>> by looking for the wakeup-source property and setting the
>>> I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
>>> ACPI GpioInt wake flag to determine if the interrupt can be used to wake
>>> the system. Previously the i2c drivers had to make assumptions and
>>> blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
>>> If there is a device with an Active Low interrupt and the device gets
>>> powered off while suspending, the interrupt line will go low since it's
>>> no longer powered and wake the system. For this reason we should respect
>>> the board designers wishes and honor the wake bit defined on the
>>> GpioInt.
>>>
>>> This change does not cover the ACPI Interrupt or IRQ resources.
>>>
>>> Signed-off-by: Raul E Rangel <rrangel@chromium.org>
>>> ---
>>>
>>>  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
>>>  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
>>>  drivers/i2c/i2c-core.h      |  4 ++--
>>>  3 files changed, 19 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
>>> index c762a879c4cc6b..cfe82a6ba3ef28 100644
>>> --- a/drivers/i2c/i2c-core-acpi.c
>>> +++ b/drivers/i2c/i2c-core-acpi.c
>>> @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
>>>  /**
>>>   * i2c_acpi_get_irq - get device IRQ number from ACPI
>>>   * @client: Pointer to the I2C client device
>>> + * @wake_capable: Set to 1 if the IRQ is wake capable
>>>   *
>>>   * Find the IRQ number used by a specific client device.
>>>   *
>>>   * Return: The IRQ number or an error code.
>>>   */
>>> -int i2c_acpi_get_irq(struct i2c_client *client)
>>> +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
>>>  {
>>>       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
>>>       struct list_head resource_list;
>>> @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
>>>
>>>       INIT_LIST_HEAD(&resource_list);
>>>
>>> +     if (wake_capable)
>>> +             *wake_capable = 0;
>>> +
>>>       ret = acpi_dev_get_resources(adev, &resource_list,
>>>                                    i2c_acpi_add_resource, &irq);
>>
> 
> 
>> You also need to handle "Interrupt(..., ...AndWake)" case here. I would
>> look into maybe defining
>>
>> #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
>>
>> in include/linux/ioport.h and plumbing it through from ACPI layer.
>>
>> Thanks.
> 
> AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
> wake a system from suspend/suspend-to-idle.

That may be true for S3 suspend (it sounds about right) there
certainly is no way to "arm for wakeup" on the APIC, but with
s2idle all IRQs which are not explicitly disabled by the OS
still function normally so there any IRQ can be a wakeup
source (AFAIK).

And even with S3 suspend I think some IRQs can act as wakeup,
but that is configured by the BIOS then and not something which
linux can enable/disable. E.g IIRC the parent IRQ of the GPIO
controllers on x86 is an APIC IRQ ...

Regards,

Hans


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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-07  8:12       ` Hans de Goede
@ 2022-09-08 14:40         ` Raul Rangel
  2022-09-08 15:23           ` Rafael J. Wysocki
  0 siblings, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-09-08 14:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Dmitry Torokhov, Linux ACPI, linux-input, Limonciello, Mario,
	Tim Van Patten, Rafael J. Wysocki, Mika Westerberg, Wolfram Sang,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

On Wed, Sep 7, 2022 at 2:12 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 9/7/22 04:00, Raul Rangel wrote:
> > On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> >>
> >> On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> >>> Device tree already has a mechanism to pass the wake_irq. It does this
> >>> by looking for the wakeup-source property and setting the
> >>> I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> >>> ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> >>> the system. Previously the i2c drivers had to make assumptions and
> >>> blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> >>> If there is a device with an Active Low interrupt and the device gets
> >>> powered off while suspending, the interrupt line will go low since it's
> >>> no longer powered and wake the system. For this reason we should respect
> >>> the board designers wishes and honor the wake bit defined on the
> >>> GpioInt.
> >>>
> >>> This change does not cover the ACPI Interrupt or IRQ resources.
> >>>
> >>> Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> >>> ---
> >>>
> >>>  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
> >>>  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
> >>>  drivers/i2c/i2c-core.h      |  4 ++--
> >>>  3 files changed, 19 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> >>> index c762a879c4cc6b..cfe82a6ba3ef28 100644
> >>> --- a/drivers/i2c/i2c-core-acpi.c
> >>> +++ b/drivers/i2c/i2c-core-acpi.c
> >>> @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
> >>>  /**
> >>>   * i2c_acpi_get_irq - get device IRQ number from ACPI
> >>>   * @client: Pointer to the I2C client device
> >>> + * @wake_capable: Set to 1 if the IRQ is wake capable
> >>>   *
> >>>   * Find the IRQ number used by a specific client device.
> >>>   *
> >>>   * Return: The IRQ number or an error code.
> >>>   */
> >>> -int i2c_acpi_get_irq(struct i2c_client *client)
> >>> +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
> >>>  {
> >>>       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> >>>       struct list_head resource_list;
> >>> @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
> >>>
> >>>       INIT_LIST_HEAD(&resource_list);
> >>>
> >>> +     if (wake_capable)
> >>> +             *wake_capable = 0;
> >>> +
> >>>       ret = acpi_dev_get_resources(adev, &resource_list,
> >>>                                    i2c_acpi_add_resource, &irq);
> >>
> >
> >
> >> You also need to handle "Interrupt(..., ...AndWake)" case here. I would
> >> look into maybe defining
> >>
> >> #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
> >>
> >> in include/linux/ioport.h and plumbing it through from ACPI layer.
> >>
> >> Thanks.
> >
> > AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
> > wake a system from suspend/suspend-to-idle.
>
> That may be true for S3 suspend (it sounds about right) there
> certainly is no way to "arm for wakeup" on the APIC, but with
> s2idle all IRQs which are not explicitly disabled by the OS
> still function normally so there any IRQ can be a wakeup
> source (AFAIK).
>
> And even with S3 suspend I think some IRQs can act as wakeup,
> but that is configured by the BIOS then and not something which
> linux can enable/disable. E.g IIRC the parent IRQ of the GPIO
> controllers on x86 is an APIC IRQ ...
>
> Regards,
>
> Hans
>

SGTM. I wanted to make sure there was interest before I invested the
time in adding the functionality. Hopefully I can push up a new patch
set tomorrow.

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-08 14:40         ` Raul Rangel
@ 2022-09-08 15:23           ` Rafael J. Wysocki
  2022-09-09 18:47             ` Raul Rangel
  0 siblings, 1 reply; 31+ messages in thread
From: Rafael J. Wysocki @ 2022-09-08 15:23 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Hans de Goede, Dmitry Torokhov, Linux ACPI, linux-input,
	Limonciello, Mario, Tim Van Patten, Rafael J. Wysocki,
	Mika Westerberg, Wolfram Sang,
	open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

On Thu, Sep 8, 2022 at 4:40 PM Raul Rangel <rrangel@chromium.org> wrote:
>
> On Wed, Sep 7, 2022 at 2:12 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >
> > Hi,
> >
> > On 9/7/22 04:00, Raul Rangel wrote:
> > > On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
> > > <dmitry.torokhov@gmail.com> wrote:
> > >>
> > >> On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> > >>> Device tree already has a mechanism to pass the wake_irq. It does this
> > >>> by looking for the wakeup-source property and setting the
> > >>> I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> > >>> ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> > >>> the system. Previously the i2c drivers had to make assumptions and
> > >>> blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> > >>> If there is a device with an Active Low interrupt and the device gets
> > >>> powered off while suspending, the interrupt line will go low since it's
> > >>> no longer powered and wake the system. For this reason we should respect
> > >>> the board designers wishes and honor the wake bit defined on the
> > >>> GpioInt.
> > >>>
> > >>> This change does not cover the ACPI Interrupt or IRQ resources.
> > >>>
> > >>> Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > >>> ---
> > >>>
> > >>>  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
> > >>>  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
> > >>>  drivers/i2c/i2c-core.h      |  4 ++--
> > >>>  3 files changed, 19 insertions(+), 10 deletions(-)
> > >>>
> > >>> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> > >>> index c762a879c4cc6b..cfe82a6ba3ef28 100644
> > >>> --- a/drivers/i2c/i2c-core-acpi.c
> > >>> +++ b/drivers/i2c/i2c-core-acpi.c
> > >>> @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
> > >>>  /**
> > >>>   * i2c_acpi_get_irq - get device IRQ number from ACPI
> > >>>   * @client: Pointer to the I2C client device
> > >>> + * @wake_capable: Set to 1 if the IRQ is wake capable
> > >>>   *
> > >>>   * Find the IRQ number used by a specific client device.
> > >>>   *
> > >>>   * Return: The IRQ number or an error code.
> > >>>   */
> > >>> -int i2c_acpi_get_irq(struct i2c_client *client)
> > >>> +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
> > >>>  {
> > >>>       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> > >>>       struct list_head resource_list;
> > >>> @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
> > >>>
> > >>>       INIT_LIST_HEAD(&resource_list);
> > >>>
> > >>> +     if (wake_capable)
> > >>> +             *wake_capable = 0;
> > >>> +
> > >>>       ret = acpi_dev_get_resources(adev, &resource_list,
> > >>>                                    i2c_acpi_add_resource, &irq);
> > >>
> > >
> > >
> > >> You also need to handle "Interrupt(..., ...AndWake)" case here. I would
> > >> look into maybe defining
> > >>
> > >> #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
> > >>
> > >> in include/linux/ioport.h and plumbing it through from ACPI layer.
> > >>
> > >> Thanks.
> > >
> > > AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
> > > wake a system from suspend/suspend-to-idle.
> >
> > That may be true for S3 suspend (it sounds about right) there
> > certainly is no way to "arm for wakeup" on the APIC, but with
> > s2idle all IRQs which are not explicitly disabled by the OS
> > still function normally so there any IRQ can be a wakeup
> > source (AFAIK).

That's true.

Moreover, even for S3 there are transitions into it and there may be
wakeup interrupts taking place during those transitions.  Those may be
any IRQs too.

> > And even with S3 suspend I think some IRQs can act as wakeup,
> > but that is configured by the BIOS then and not something which
> > linux can enable/disable. E.g IIRC the parent IRQ of the GPIO
> > controllers on x86 is an APIC IRQ ...

It's more about how the system is wired up AFAICS.  Basically, in
order to wake up the system from S3, the given IRQ needs to be
physically attached to an input that will trigger the platform wakeup
logic while in S3.

> >
>
> SGTM. I wanted to make sure there was interest before I invested the
> time in adding the functionality. Hopefully I can push up a new patch
> set tomorrow.

Sounds good. :-)

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-08 15:23           ` Rafael J. Wysocki
@ 2022-09-09 18:47             ` Raul Rangel
  2022-09-10  1:25               ` Dmitry Torokhov
  0 siblings, 1 reply; 31+ messages in thread
From: Raul Rangel @ 2022-09-09 18:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Hans de Goede, Dmitry Torokhov, Linux ACPI, linux-input,
	Limonciello, Mario, Tim Van Patten, Mika Westerberg,
	Wolfram Sang, open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

It looks like `i2c_acpi_get_irq` and `platform_get_irq_optional` are
doing pretty much the same thing. Can we replace `i2c_acpi_get_irq`
and switch over to `platform_get_irq_optional`? Is it possible to get
a `platform_device` from an `i2c_client`?

On Thu, Sep 8, 2022 at 9:23 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Thu, Sep 8, 2022 at 4:40 PM Raul Rangel <rrangel@chromium.org> wrote:
> >
> > On Wed, Sep 7, 2022 at 2:12 AM Hans de Goede <hdegoede@redhat.com> wrote:
> > >
> > > Hi,
> > >
> > > On 9/7/22 04:00, Raul Rangel wrote:
> > > > On Tue, Sep 6, 2022 at 7:00 PM Dmitry Torokhov
> > > > <dmitry.torokhov@gmail.com> wrote:
> > > >>
> > > >> On Tue, Aug 30, 2022 at 05:15:37PM -0600, Raul E Rangel wrote:
> > > >>> Device tree already has a mechanism to pass the wake_irq. It does this
> > > >>> by looking for the wakeup-source property and setting the
> > > >>> I2C_CLIENT_WAKE flag. This CL adds the ACPI equivalent. It uses at the
> > > >>> ACPI GpioInt wake flag to determine if the interrupt can be used to wake
> > > >>> the system. Previously the i2c drivers had to make assumptions and
> > > >>> blindly enable the wake IRQ. This can cause spurious wake events. e.g.,
> > > >>> If there is a device with an Active Low interrupt and the device gets
> > > >>> powered off while suspending, the interrupt line will go low since it's
> > > >>> no longer powered and wake the system. For this reason we should respect
> > > >>> the board designers wishes and honor the wake bit defined on the
> > > >>> GpioInt.
> > > >>>
> > > >>> This change does not cover the ACPI Interrupt or IRQ resources.
> > > >>>
> > > >>> Signed-off-by: Raul E Rangel <rrangel@chromium.org>
> > > >>> ---
> > > >>>
> > > >>>  drivers/i2c/i2c-core-acpi.c |  8 ++++++--
> > > >>>  drivers/i2c/i2c-core-base.c | 17 +++++++++++------
> > > >>>  drivers/i2c/i2c-core.h      |  4 ++--
> > > >>>  3 files changed, 19 insertions(+), 10 deletions(-)
> > > >>>
> > > >>> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> > > >>> index c762a879c4cc6b..cfe82a6ba3ef28 100644
> > > >>> --- a/drivers/i2c/i2c-core-acpi.c
> > > >>> +++ b/drivers/i2c/i2c-core-acpi.c
> > > >>> @@ -182,12 +182,13 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
> > > >>>  /**
> > > >>>   * i2c_acpi_get_irq - get device IRQ number from ACPI
> > > >>>   * @client: Pointer to the I2C client device
> > > >>> + * @wake_capable: Set to 1 if the IRQ is wake capable
> > > >>>   *
> > > >>>   * Find the IRQ number used by a specific client device.
> > > >>>   *
> > > >>>   * Return: The IRQ number or an error code.
> > > >>>   */
> > > >>> -int i2c_acpi_get_irq(struct i2c_client *client)
> > > >>> +int i2c_acpi_get_irq(struct i2c_client *client, int *wake_capable)
> > > >>>  {
> > > >>>       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> > > >>>       struct list_head resource_list;
> > > >>> @@ -196,6 +197,9 @@ int i2c_acpi_get_irq(struct i2c_client *client)
> > > >>>
> > > >>>       INIT_LIST_HEAD(&resource_list);
> > > >>>
> > > >>> +     if (wake_capable)
> > > >>> +             *wake_capable = 0;
> > > >>> +
> > > >>>       ret = acpi_dev_get_resources(adev, &resource_list,
> > > >>>                                    i2c_acpi_add_resource, &irq);
> > > >>
> > > >
> > > >
> > > >> You also need to handle "Interrupt(..., ...AndWake)" case here. I would
> > > >> look into maybe defining
> > > >>
> > > >> #define IORESOURCE_IRQ_WAKECAPABLE      (1<<6)
> > > >>
> > > >> in include/linux/ioport.h and plumbing it through from ACPI layer.
> > > >>
> > > >> Thanks.
> > > >
> > > > AFAIK the Intel (Not 100% certain) and AMD IO-APIC's can't actually
> > > > wake a system from suspend/suspend-to-idle.
> > >
> > > That may be true for S3 suspend (it sounds about right) there
> > > certainly is no way to "arm for wakeup" on the APIC, but with
> > > s2idle all IRQs which are not explicitly disabled by the OS
> > > still function normally so there any IRQ can be a wakeup
> > > source (AFAIK).
>
> That's true.
>
> Moreover, even for S3 there are transitions into it and there may be
> wakeup interrupts taking place during those transitions.  Those may be
> any IRQs too.
>
> > > And even with S3 suspend I think some IRQs can act as wakeup,
> > > but that is configured by the BIOS then and not something which
> > > linux can enable/disable. E.g IIRC the parent IRQ of the GPIO
> > > controllers on x86 is an APIC IRQ ...
>
> It's more about how the system is wired up AFAICS.  Basically, in
> order to wake up the system from S3, the given IRQ needs to be
> physically attached to an input that will trigger the platform wakeup
> logic while in S3.
>
> > >
> >
> > SGTM. I wanted to make sure there was interest before I invested the
> > time in adding the functionality. Hopefully I can push up a new patch
> > set tomorrow.
>
> Sounds good. :-)

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

* Re: [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq
  2022-09-09 18:47             ` Raul Rangel
@ 2022-09-10  1:25               ` Dmitry Torokhov
  0 siblings, 0 replies; 31+ messages in thread
From: Dmitry Torokhov @ 2022-09-10  1:25 UTC (permalink / raw)
  To: Raul Rangel
  Cc: Rafael J. Wysocki, Hans de Goede, Linux ACPI, linux-input,
	Limonciello, Mario, Tim Van Patten, Mika Westerberg,
	Wolfram Sang, open list:I2C SUBSYSTEM HOST DRIVERS, linux-kernel

On Fri, Sep 09, 2022 at 12:47:11PM -0600, Raul Rangel wrote:
> It looks like `i2c_acpi_get_irq` and `platform_get_irq_optional` are
> doing pretty much the same thing. Can we replace `i2c_acpi_get_irq`
> and switch over to `platform_get_irq_optional`? Is it possible to get
> a `platform_device` from an `i2c_client`?

No, they are completely different objects.


		struct device
	/		|		\
platform_device		i2c_client	spi_device ...

Also, please no top-posting on kernel mailing lists.

Thanks.

-- 
Dmitry

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

end of thread, other threads:[~2022-09-10  1:25 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-30 23:15 [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Raul E Rangel
2022-08-30 23:15 ` [PATCH 1/8] Input: elan_i2c - Use PM subsystem to manage " Raul E Rangel
2022-08-31 18:01   ` Rafael J. Wysocki
2022-08-31 18:13     ` Raul Rangel
2022-08-31 18:42       ` Rafael J. Wysocki
2022-09-01  6:57         ` Tony Lindgren
2022-08-31 19:12     ` Dmitry Torokhov
2022-08-31 19:16       ` Dmitry Torokhov
2022-09-01  2:17         ` Raul Rangel
2022-09-03  5:06           ` Dmitry Torokhov
2022-09-06 17:18             ` Raul Rangel
2022-09-06 18:40               ` Dmitry Torokhov
2022-08-30 23:15 ` [PATCH 2/8] HID: i2c-hid: " Raul E Rangel
2022-08-30 23:15 ` [PATCH 3/8] gpiolib: acpi: Add wake_capable parameter to acpi_dev_gpio_irq_get_by Raul E Rangel
2022-08-31  4:58   ` kernel test robot
2022-08-30 23:15 ` [PATCH 4/8] i2c: acpi: Use ACPI GPIO wake capability bit to set wake_irq Raul E Rangel
2022-09-07  1:00   ` Dmitry Torokhov
2022-09-07  2:00     ` Raul Rangel
2022-09-07  2:04       ` Dmitry Torokhov
2022-09-07  8:12       ` Hans de Goede
2022-09-08 14:40         ` Raul Rangel
2022-09-08 15:23           ` Rafael J. Wysocki
2022-09-09 18:47             ` Raul Rangel
2022-09-10  1:25               ` Dmitry Torokhov
2022-08-30 23:15 ` [PATCH 5/8] HID: i2c-hid: acpi: Stop setting wakeup_capable Raul E Rangel
2022-08-30 23:15 ` [PATCH 6/8] Input: elan_i2c - Don't set wake_irq when using ACPI Raul E Rangel
2022-08-30 23:15 ` [PATCH 7/8] HID: i2c-hid: " Raul E Rangel
2022-08-30 23:15 ` [PATCH 8/8] ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle Raul E Rangel
2022-08-31 11:52 ` [PATCH 0/8] acpi: i2c: Use SharedAndWake and ExclusiveAndWake to enable wake irq Andy Shevchenko
2022-08-31 14:37   ` Raul Rangel
2022-08-31 15:18     ` Hans de Goede

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