From bd6cd97a2c9f2831dd75f23a01fc7e9d75da7213 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Wed, 22 Jun 2022 15:10:58 +0800 Subject: [PATCH] spi: rockchip: Avoid redundant clock disable in pm operation Fix WARN_ON: [ 22.869352][ T1885] clk_spi0 already unprepared [ 22.869379][ T1885] WARNING: CPU: 3 PID: 1885 at drivers/clk/clk.c:813 clk_core_unprepare+0xbc4 [ 22.869380][ T1885] Modules linked in: bcmdhd dhd_static_buf [ 22.869391][ T1885] CPU: 3 PID: 1885 Comm: Binder:355_2 Tainted: G W 5.10.66 #59 [ 22.869393][ T1885] Hardware name: Rockchip RK3588 EVB1 LP4 V10 Board (DT) [ 22.869397][ T1885] pstate: 60400009 (nZCv daif +PAN -UAO -TCO BTYPE=--) [ 22.869401][ T1885] pc : clk_core_unprepare+0xbc/0x214 [ 22.869404][ T1885] lr : clk_core_unprepare+0xbc/0x214 Fixes: decf7c21 ("spi: rockchip: Suspend and resume the bus during NOIRQ_SYSTEM_SLEEP_PM ops") Change-Id: Ie1c2e2a27c85e205e27a997676183aab7a0354ee Signed-off-by: Jon Lin --- drivers/spi/spi-rockchip.c | 85 ++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index a1530bd0e092..9cd47cb2c46a 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -1019,51 +1019,6 @@ static int rockchip_spi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int rockchip_spi_suspend(struct device *dev) -{ - int ret; - struct spi_controller *ctlr = dev_get_drvdata(dev); - struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); - - ret = spi_controller_suspend(ctlr); - if (ret < 0) - return ret; - - clk_disable_unprepare(rs->spiclk); - clk_disable_unprepare(rs->apb_pclk); - - pinctrl_pm_select_sleep_state(dev); - - return 0; -} - -static int rockchip_spi_resume(struct device *dev) -{ - int ret; - struct spi_controller *ctlr = dev_get_drvdata(dev); - struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); - - pinctrl_pm_select_default_state(dev); - - ret = clk_prepare_enable(rs->apb_pclk); - if (ret < 0) - return ret; - - ret = clk_prepare_enable(rs->spiclk); - if (ret < 0) - clk_disable_unprepare(rs->apb_pclk); - - ret = spi_controller_resume(ctlr); - if (ret < 0) { - clk_disable_unprepare(rs->spiclk); - clk_disable_unprepare(rs->apb_pclk); - } - - return 0; -} -#endif /* CONFIG_PM_SLEEP */ - #ifdef CONFIG_PM static int rockchip_spi_runtime_suspend(struct device *dev) { @@ -1094,6 +1049,46 @@ static int rockchip_spi_runtime_resume(struct device *dev) } #endif /* CONFIG_PM */ +#ifdef CONFIG_PM_SLEEP +static int rockchip_spi_suspend(struct device *dev) +{ + int ret; + struct spi_controller *ctlr = dev_get_drvdata(dev); + + ret = spi_controller_suspend(ctlr); + if (ret < 0) + return ret; + + /* Avoid redundant clock disable */ + if (!pm_runtime_status_suspended(dev)) + rockchip_spi_runtime_suspend(dev); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int rockchip_spi_resume(struct device *dev) +{ + int ret; + struct spi_controller *ctlr = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (!pm_runtime_status_suspended(dev)) { + ret = rockchip_spi_runtime_resume(dev); + if (ret < 0) + return ret; + } + + ret = spi_controller_resume(ctlr); + if (ret < 0) + rockchip_spi_runtime_suspend(dev); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + static const struct dev_pm_ops rockchip_spi_pm = { SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume) SET_RUNTIME_PM_OPS(rockchip_spi_runtime_suspend,