We have discovered that some power lines were always on even if the devices on that power line was not used.
This happens because we failed to probe a device on the i2c bus, and the ACPI Power Resource were never turned off.
This patch tries to fix this issue.
To: Mika Westerberg mika.westerberg@linux.intel.com To: Wolfram Sang wsa@kernel.org To: Sakari Ailus sakari.ailus@linux.intel.com To: Tomasz Figa tfiga@chromium.org To: "Rafael J. Wysocki" rafael.j.wysocki@intel.com Cc: Hidenori Kobayashi hidenorik@google.com Cc: Sergey Senozhatsky senozhatsky@chromium.org Cc: linux-i2c@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Ricardo Ribalda ribalda@chromium.org --- Changes in v6: - Add Reviewed-by: Hidenori (Thanks!). - Set device always off at remove. - Link to v5: https://lore.kernel.org/r/20221109-i2c-waive-v5-0-2839667f8f6a@chromium.org
Changes in v5: - Add Cc: stable - Add Reviewed-by Sakary (Thanks!). - Renamed turn-off as power-off, in the name of consistency (Thanks Sergey!) - Link to v4: https://lore.kernel.org/r/20221109-i2c-waive-v4-0-e4496462833b@chromium.org
Changes in v4: - Rename full_power to do_power_on. - Link to v3: https://lore.kernel.org/r/20221109-i2c-waive-v3-0-d8651cb4b88d@chromium.org
Changes in v3: - Introduce full_power variable to make more clear what we are doing. - Link to v2: https://lore.kernel.org/r/20221109-i2c-waive-v2-0-07550bf2dacc@chromium.org
Changes in v2: - Cover also device remove - Link to v1: https://lore.kernel.org/r/20221109-i2c-waive-v1-0-ed70a99b990d@chromium.org
--- Ricardo Ribalda (1): i2c: Restore initial power state if probe fails
drivers/i2c/i2c-core-base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) --- base-commit: f141df371335645ce29a87d9683a3f79fba7fd67 change-id: 20221109-i2c-waive-ae97fea1f1b5
Best regards,
A driver that supports I2C_DRV_ACPI_WAIVE_D0_PROBE is not expected to power off a device that it has not powered on previously.
For devices operating in "full_power" mode, the first call to `i2c_acpi_waive_d0_probe` will return 0, which means that the device will be turned on with `dev_pm_domain_attach`.
If probe fails the second call to `i2c_acpi_waive_d0_probe` will return 1, which means that the device will not be turned off. This is, it will be left in a different power state. Lets fix it.
Reviewed-by: Hidenori Kobayashi hidenorik@chromium.org Reviewed-by: Sergey Senozhatsky senozhatsky@chromium.org Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Cc: stable@vger.kernel.org Fixes: b18c1ad685d9 ("i2c: Allow an ACPI driver to manage the device's power state during probe") Signed-off-by: Ricardo Ribalda ribalda@chromium.org
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index b4edf10e8fd0..7539b0740351 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -467,6 +467,7 @@ static int i2c_device_probe(struct device *dev) { struct i2c_client *client = i2c_verify_client(dev); struct i2c_driver *driver; + bool do_power_on; int status;
if (!client) @@ -545,8 +546,8 @@ static int i2c_device_probe(struct device *dev) if (status < 0) goto err_clear_wakeup_irq;
- status = dev_pm_domain_attach(&client->dev, - !i2c_acpi_waive_d0_probe(dev)); + do_power_on = !i2c_acpi_waive_d0_probe(dev); + status = dev_pm_domain_attach(&client->dev, do_power_on); if (status) goto err_clear_wakeup_irq;
@@ -585,7 +586,7 @@ static int i2c_device_probe(struct device *dev) err_release_driver_resources: devres_release_group(&client->dev, client->devres_group_id); err_detach_pm_domain: - dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); + dev_pm_domain_detach(&client->dev, do_power_on); err_clear_wakeup_irq: dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); @@ -610,7 +611,7 @@ static void i2c_device_remove(struct device *dev)
devres_release_group(&client->dev, client->devres_group_id);
- dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); + dev_pm_domain_detach(&client->dev, true);
dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false);
On Mon, Nov 14, 2022 at 01:20:34PM +0100, Ricardo Ribalda wrote:
A driver that supports I2C_DRV_ACPI_WAIVE_D0_PROBE is not expected to power off a device that it has not powered on previously.
For devices operating in "full_power" mode, the first call to `i2c_acpi_waive_d0_probe` will return 0, which means that the device will be turned on with `dev_pm_domain_attach`.
If probe fails the second call to `i2c_acpi_waive_d0_probe` will return 1, which means that the device will not be turned off. This is, it will be left in a different power state. Lets fix it.
Reviewed-by: Hidenori Kobayashi hidenorik@chromium.org Reviewed-by: Sergey Senozhatsky senozhatsky@chromium.org Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com
Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com
wOn Mon, Nov 14, 2022 at 01:20:34PM +0100, Ricardo Ribalda wrote:
A driver that supports I2C_DRV_ACPI_WAIVE_D0_PROBE is not expected to power off a device that it has not powered on previously.
For devices operating in "full_power" mode, the first call to `i2c_acpi_waive_d0_probe` will return 0, which means that the device will be turned on with `dev_pm_domain_attach`.
If probe fails the second call to `i2c_acpi_waive_d0_probe` will return 1, which means that the device will not be turned off. This is, it will be left in a different power state. Lets fix it.
Reviewed-by: Hidenori Kobayashi hidenorik@chromium.org Reviewed-by: Sergey Senozhatsky senozhatsky@chromium.org Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Cc: stable@vger.kernel.org Fixes: b18c1ad685d9 ("i2c: Allow an ACPI driver to manage the device's power state during probe") Signed-off-by: Ricardo Ribalda ribalda@chromium.org
Applied to for-current, thanks!
linux-stable-mirror@lists.linaro.org