[PATCH 1/2] i2c: designware: Fix clock issue when PM is disabled

Kunihiko Hayashi posted 2 patches 2 months, 2 weeks ago
There is a newer version of this series
[PATCH 1/2] i2c: designware: Fix clock issue when PM is disabled
Posted by Kunihiko Hayashi 2 months, 2 weeks ago
When removing the driver, enable the clocks once by calling
pm_runtime_get_sync(), and call pm_runtime_put_sync() to disable
the clocks.

If CONFIG_PM=y, clocks for this controller are disabled when it's in
the idle state. So the clocks are properly disabled when the driver
exits.

Othewise, the clocks are always enabled and the PM functions have
no effect. Therefore, the driver exits without disabling the clocks.

    # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
    18
    # echo 1214a000.i2c > /sys/bus/platform/drivers/i2c_designware/bind
    # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
    20
    # echo 1214a000.i2c > /sys/bus/platform/drivers/i2c_designware/unbind
    # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
    20

To ensure that the clocks can be disabled correctly even without
CONFIG_PM=y, should add the following fixes:

- Replace with pm_runtime_put_noidle(), which only decrements the clock
  count.
- Call i2c_dw_prepare_clk(false) to explicitly disable the clocks.

Fixes: 7272194ed391f ("i2c-designware: add minimal support for runtime PM")
Co-developed-by: Kohei Ito <ito.kohei@socionext.com>
Signed-off-by: Kohei Ito <ito.kohei@socionext.com>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
---
 drivers/i2c/busses/i2c-designware-platdrv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index d6e1ee935399..edaebfb165f9 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -325,9 +325,11 @@ static void dw_i2c_plat_remove(struct platform_device *pdev)
 	i2c_dw_disable(dev);
 
 	pm_runtime_dont_use_autosuspend(device);
-	pm_runtime_put_sync(device);
+	pm_runtime_put_noidle(device);
 	dw_i2c_plat_pm_cleanup(dev);
 
+	i2c_dw_prepare_clk(dev, false);
+
 	i2c_dw_remove_lock_support(dev);
 
 	reset_control_assert(dev->rst);
-- 
2.34.1
Re: [PATCH 1/2] i2c: designware: Fix clock issue when PM is disabled
Posted by Kunihiko Hayashi 2 months, 2 weeks ago
On 2025/07/24 11:13, Kunihiko Hayashi wrote:
> When removing the driver, enable the clocks once by calling
> pm_runtime_get_sync(), and call pm_runtime_put_sync() to disable
> the clocks.
> 
> If CONFIG_PM=y, clocks for this controller are disabled when it's in
> the idle state. So the clocks are properly disabled when the driver
> exits.
> 
> Othewise, the clocks are always enabled and the PM functions have
> no effect. Therefore, the driver exits without disabling the clocks.
> 
>      # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
>      18
>      # echo 1214a000.i2c > /sys/bus/platform/drivers/i2c_designware/bind
>      # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
>      20
>      # echo 1214a000.i2c > /sys/bus/platform/drivers/i2c_designware/unbind
>      # cat /sys/kernel/debug/clk/clk-pclk/clk_enable_count
>      20
> 
> To ensure that the clocks can be disabled correctly even without
> CONFIG_PM=y, should add the following fixes:
> 
> - Replace with pm_runtime_put_noidle(), which only decrements the clock
>    count.

This description is wrong.
The pm_runtime_put_noidle() decrements the runtime PM usage count.

> - Call i2c_dw_prepare_clk(false) to explicitly disable the clocks.

This decrements the clock count.

I'll fix it and resend as v2.

Thanks,

---
Best Regards
Kunihiko Hayashi