Skip to content

Commit

Permalink
spi: rockchip: Resolve unbalanced runtime PM / system PM handling
Browse files Browse the repository at this point in the history
commit be721b4 upstream.

Commit e882575 ("spi: rockchip: Suspend and resume the bus during
NOIRQ_SYSTEM_SLEEP_PM ops") stopped respecting runtime PM status and
simply disabled clocks unconditionally when suspending the system. This
causes problems when the device is already runtime suspended when we go
to sleep -- in which case we double-disable clocks and produce a
WARNing.

Switch back to pm_runtime_force_{suspend,resume}(), because that still
seems like the right thing to do, and the aforementioned commit makes no
explanation why it stopped using it.

Also, refactor some of the resume() error handling, because it's not
actually a good idea to re-disable clocks on failure.

Fixes: e882575 ("spi: rockchip: Suspend and resume the bus during NOIRQ_SYSTEM_SLEEP_PM ops")
Cc: stable@vger.kernel.org
Reported-by: Ondřej Jirman <megi@xff.cz>
Closes: https://lore.kernel.org/lkml/20220621154218.sau54jeij4bunf56@core/
Signed-off-by: Brian Norris <briannorris@chromium.org>
Link: https://patch.msgid.link/20240827171126.1115748-1-briannorris@chromium.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
computersforpeace authored and gregkh committed Sep 12, 2024
1 parent 1b2770e commit d034bff
Showing 1 changed file with 7 additions and 16 deletions.
23 changes: 7 additions & 16 deletions drivers/spi/spi-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -974,14 +974,16 @@ 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);
ret = pm_runtime_force_suspend(dev);
if (ret < 0) {
spi_controller_resume(ctlr);
return ret;
}

pinctrl_pm_select_sleep_state(dev);

Expand All @@ -992,25 +994,14 @@ 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);
ret = pm_runtime_force_resume(dev);
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;
return spi_controller_resume(ctlr);
}
#endif /* CONFIG_PM_SLEEP */

Expand Down

0 comments on commit d034bff

Please sign in to comment.