* [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths
@ 2026-08-06 19:18 Alexander Shiyan
2026-11-06 14:58 ` Mark Brown
0 siblings, 1 reply; 4+ messages in thread
From: Alexander Shiyan @ 2026-08-06 19:18 UTC (permalink / raw)
To: linux-spi; +Cc: linux-rockchip, Mark Brown, Heiko Stuebner, Alexander Shiyan
The Rockchip SPI driver manages runtime PM reference counting around
chip select (CS) assertion: pm_runtime_get_sync() is called when CS is
asserted, and pm_runtime_put() when deasserted. This balanced pair is
expected.
However, when a transfer is aborted due to an error (e.g., power domain
timeout, DMA failure, or suspend/resume), the CS may remain in asserted
state while the transfer is terminated early. In such cases the
corresponding pm_runtime_put() is never called, leaving the usage count
artificially high. A later attempt to deassert CS (either explicitly or
during a new transfer) will call pm_runtime_put() without a prior get(),
triggering a "Runtime PM usage count underflow" warning and breaking
subsequent SPI operations.
Furthermore, the error handler may already have released the PM
reference and cleared the CS, but the SPI core may still call
rockchip_spi_set_cs() to deassert CS at message completion. Without
additional state tracking, this results in an extra pm_runtime_put()
and another underflow.
Add a cs_claimed flag to struct rockchip_spi to track whether the
runtime PM reference is currently held. Set it in the CS assertion path
after pm_runtime_get_sync(), clear it in deassertion path after
pm_runtime_put(). In error paths (rockchip_spi_handle_err() and
rockchip_spi_target_abort()), check this flag and release the reference
if still held. In rockchip_spi_set_cs() deassertion branch, only call
pm_runtime_put() if cs_claimed is true, preventing double decrement.
---
[root@diasom-evb ~]# rtcwake -s 15 -v -m freeze
rtcwake: assuming RTC uses UTC ...
Using UTC time.
delta = 37
tzone = 0
tzname = UTC
systime = 1773421731, (UTC) Fri Mar 13 17:08:51 2026
rtctime = 1773421694, (UTC) Fri Mar 13 17:08:14 2026
alarm 0, sys_time 1773421731, rtc_time 1773421694, seconds 15
rtcwake: wakeup from "freeze" using /dev/rtc0 at Fri Mar 13 17:08:30 2026
suspend mode: freeze; suspending system
[ 28.951039] PM: suspend entry (s2idle)
[ 28.957997] Filesystems sync: 0.006 seconds
[ 28.963184] Freezing user space processes
[ 28.966553] Freezing user space processes completed (elapsed 0.003 seconds)
[ 28.967162] OOM killer disabled.
[ 28.967464] Freezing remaining freezable tasks
[ 28.968457] Freezing remaining freezable tasks completed (elapsed 0.000 seconds)
...
[ 33.249429] spi_master spi2: Failed to power device: -13
[ 33.249893] spi_master spi2: noqueue transfer failed
[ 33.250331] spi_master spi2: Failed to power device: -13
[ 33.250797] spi_master spi2: noqueue transfer failed
[ 33.251230] rockchip-spi feb20000.spi: Runtime PM usage count underflow!
---
Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
drivers/spi/spi-rockchip.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 231fbcf0e7aa..fb5795bc734d 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -191,6 +191,7 @@ struct rockchip_spi {
bool target_abort;
bool cs_inactive; /* spi target transmission stop when cs inactive */
bool cs_high_supported; /* native CS supports active-high polarity */
+ bool cs_claimed; /* runtime PM reference taken for CS */
struct spi_transfer *xfer; /* Store xfer temporarily */
};
@@ -256,6 +257,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
if (cs_asserted) {
/* Keep things powered as long as CS is asserted */
pm_runtime_get_sync(rs->dev);
+ rs->cs_claimed = true;
if (spi_get_csgpiod(spi, 0))
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
@@ -263,14 +265,18 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER,
BIT(spi_get_chipselect(spi, 0)));
} else {
+ /* Clear CS first, then release PM */
if (spi_get_csgpiod(spi, 0))
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
else
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER,
BIT(spi_get_chipselect(spi, 0)));
- /* Drop reference from when we first asserted CS */
- pm_runtime_put(rs->dev);
+ /* Only release PM if we still hold the reference */
+ if (rs->cs_claimed) {
+ pm_runtime_put(rs->dev);
+ rs->cs_claimed = false;
+ }
}
}
@@ -279,6 +285,12 @@ static void rockchip_spi_handle_err(struct spi_controller *ctlr,
{
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+ /* If CS was claimed, release it to avoid PM underflow */
+ if (rs->cs_claimed) {
+ pm_runtime_put(rs->dev);
+ rs->cs_claimed = false;
+ }
+
/* stop running spi transfer
* this also flushes both rx and tx fifos
*/
@@ -624,6 +636,12 @@ static int rockchip_spi_target_abort(struct spi_controller *ctlr)
struct dma_tx_state state;
enum dma_status status;
+ /* If CS was claimed, release it */
+ if (rs->cs_claimed) {
+ pm_runtime_put(rs->dev);
+ rs->cs_claimed = false;
+ }
+
/* Get current dma rx point */
if (atomic_read(&rs->state) & RXDMA) {
dmaengine_pause(ctlr->dma_rx);
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths
2026-08-06 19:18 [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths Alexander Shiyan
@ 2026-11-06 14:58 ` Mark Brown
2026-11-07 2:35 ` Sebastian Reichel
0 siblings, 1 reply; 4+ messages in thread
From: Mark Brown @ 2026-11-06 14:58 UTC (permalink / raw)
To: Alexander Shiyan; +Cc: linux-spi, linux-rockchip, Mark Brown, Heiko Stuebner
> The Rockchip SPI driver manages runtime PM reference counting around
> chip select (CS) assertion: pm_runtime_get_sync() is called when CS is
> asserted, and pm_runtime_put() when deasserted. This balanced pair is
> expected.
> @@ -256,6 +257,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
> if (cs_asserted) {
> /* Keep things powered as long as CS is asserted */
> pm_runtime_get_sync(rs->dev);
> + rs->cs_claimed = true;
This sort of boolean tracking of reference counts is extremely error
prone, and note that there are two chip selects on the device. This
should probably at least be per chip select.
--
Mark Brown <broonie@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths
2026-11-06 14:58 ` Mark Brown
@ 2026-11-07 2:35 ` Sebastian Reichel
2026-11-07 12:33 ` Mark Brown
0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Reichel @ 2026-11-07 2:35 UTC (permalink / raw)
To: Mark Brown; +Cc: Alexander Shiyan, linux-spi, linux-rockchip, Heiko Stuebner
[-- Attachment #1: Type: text/plain, Size: 2728 bytes --]
Hi,
On Fri, Nov 06, 2026 at 02:58:38PM +0000, Mark Brown wrote:
> > The Rockchip SPI driver manages runtime PM reference counting around
> > chip select (CS) assertion: pm_runtime_get_sync() is called when CS is
> > asserted, and pm_runtime_put() when deasserted. This balanced pair is
> > expected.
>
> > @@ -256,6 +257,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
> > if (cs_asserted) {
> > /* Keep things powered as long as CS is asserted */
> > pm_runtime_get_sync(rs->dev);
> > + rs->cs_claimed = true;
>
> This sort of boolean tracking of reference counts is extremely error
> prone, and note that there are two chip selects on the device. This
> should probably at least be per chip select.
I ran into the same symptom while working on RK3588 system suspend
and came up with a way different root cause.
I haven't found the time to investigate more closely, check for a
proper Fixes references e.t.c., hence it has not yet been send. So
take this with a grain of salt, but it seems to be not Rockchip
specific:
-----
From: Sebastian Reichel <sebastian.reichel@collabora.com>
Date: Sat, 5 Sep 2026 00:26:40 +0200
Subject: [PATCH] spi: Fix runtime PM imbalance on pump transfer message error
Cc: kernel@collabora.com
The current SPI message pumping code may drop the runtime PM twice when
an SPI message cannot be send:
spi_master spi2: noqueue transfer failed
rockchip-spi feb20000.spi: Runtime PM usage count underflow!
Fix the problem by always keeping the runtime PM count increased when
exiting __spi_pump_transfer_message(), as the caller handles decreasing
it.
Note, that the function already keeps the RPM usage counter increased
for the error paths following after the prepare_transfer_hardware step.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/spi/spi.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 40cda0037ea5..9cd1cabfa0b3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1951,7 +1951,6 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
if (!was_busy && ctlr->auto_runtime_pm) {
ret = pm_runtime_get_sync(ctlr->dev.parent);
if (ret < 0) {
- pm_runtime_put_noidle(ctlr->dev.parent);
dev_err(&ctlr->dev, "Failed to power device: %d\n",
ret);
@@ -1972,9 +1971,6 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
"failed to prepare transfer hardware: %d\n",
ret);
- if (ctlr->auto_runtime_pm)
- pm_runtime_put(ctlr->dev.parent);
-
msg->status = ret;
spi_finalize_current_message(ctlr);
--
2.53.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths
2026-11-07 2:35 ` Sebastian Reichel
@ 2026-11-07 12:33 ` Mark Brown
0 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2026-11-07 12:33 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Alexander Shiyan, linux-spi, linux-rockchip, Heiko Stuebner
[-- Attachment #1: Type: text/plain, Size: 434 bytes --]
On Sat, Nov 07, 2026 at 03:35:51AM +0100, Sebastian Reichel wrote:
> I haven't found the time to investigate more closely, check for a
> proper Fixes references e.t.c., hence it has not yet been send. So
> take this with a grain of salt, but it seems to be not Rockchip
> specific:
That looks entirely plausible - could you post it as a regular patch
please? It's probably more important to fix the bug than to work out
the Fixes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-07 12:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06 19:18 [PATCH] spi: rockchip: Fix runtime PM underflow on CS error paths Alexander Shiyan
2026-11-06 14:58 ` Mark Brown
2026-11-07 2:35 ` Sebastian Reichel
2026-11-07 12:33 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox