* [PATCH 1/2] spi: stm32-ospi: handle runtime resume failure in remove
2026-10-19 8:44 [PATCH 0/2] spi: handle runtime resume failures Jiale Yao
@ 2026-10-19 8:44 ` Jiale Yao
2026-10-30 14:47 ` Patrice CHOTARD
2026-10-19 8:44 ` [PATCH 2/2] spi: ti-qspi: handle setup clock runtime resume failure Jiale Yao
2026-11-02 22:39 ` [PATCH 0/2] spi: handle runtime resume failures Mark Brown
2 siblings, 1 reply; 6+ messages in thread
From: Jiale Yao @ 2026-10-19 8:44 UTC (permalink / raw)
To: Mark Brown, Maxime Coquelin, Alexandre Torgue, Patrice Chotard,
Felix Gu, linux-spi, linux-stm32, linux-arm-kernel, linux-kernel
Cc: Jiale Yao
stm32_ospi_remove() continues with the controller teardown when runtime
resume fails. The register write can then access an unavailable device,
and the final runtime PM put does not match an acquired reference.
Keep the resource cleanup, but skip the register access and matching
runtime PM put when the resume operation fails.
Fixes: 73cd1f97946a ("spi: stm32-ospi: Fix resource leak in remove() callback")
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
drivers/spi/spi-stm32-ospi.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
index fa0e8e83cb1b..1340e62ebe1b 100644
--- a/drivers/spi/spi-stm32-ospi.c
+++ b/drivers/spi/spi-stm32-ospi.c
@@ -986,12 +986,15 @@ static int stm32_ospi_probe(struct platform_device *pdev)
static void stm32_ospi_remove(struct platform_device *pdev)
{
struct stm32_ospi *ospi = platform_get_drvdata(pdev);
+ int ret;
- pm_runtime_resume_and_get(ospi->dev);
+ ret = pm_runtime_resume_and_get(ospi->dev);
spi_unregister_controller(ospi->ctrl);
- /* Disable ospi */
- writel_relaxed(0, ospi->regs_base + OSPI_CR);
+ if (ret >= 0) {
+ /* Disable ospi */
+ writel_relaxed(0, ospi->regs_base + OSPI_CR);
+ }
mutex_destroy(&ospi->lock);
if (ospi->dma_chtx)
@@ -1001,7 +1004,8 @@ static void stm32_ospi_remove(struct platform_device *pdev)
reset_control_release(ospi->rstc);
- pm_runtime_put_sync_suspend(ospi->dev);
+ if (ret >= 0)
+ pm_runtime_put_sync_suspend(ospi->dev);
pm_runtime_force_suspend(ospi->dev);
}
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 2/2] spi: ti-qspi: handle setup clock runtime resume failure
2026-10-19 8:44 [PATCH 0/2] spi: handle runtime resume failures Jiale Yao
2026-10-19 8:44 ` [PATCH 1/2] spi: stm32-ospi: handle runtime resume failure in remove Jiale Yao
@ 2026-10-19 8:44 ` Jiale Yao
2026-10-19 23:57 ` Atsushi Nemoto
2026-11-02 22:39 ` [PATCH 0/2] spi: handle runtime resume failures Mark Brown
2 siblings, 1 reply; 6+ messages in thread
From: Jiale Yao @ 2026-10-19 8:44 UTC (permalink / raw)
To: Mark Brown, Atsushi Nemoto, linux-spi, linux-kernel; +Cc: Jiale Yao
ti_qspi_setup_clk() writes controller registers after an unchecked
pm_runtime_resume_and_get() call. Runtime resume can fail, leaving the
controller unavailable while the helper continues with the register
access and later drops a reference that was not acquired.
Return the runtime resume error from the helper and propagate it through
the memory-map and transfer paths before any clock register access.
Fixes: 8d0b512844fd ("spi: spi-ti-qspi: Support per-transfer and per-slave speed_hz settings")
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
drivers/spi/spi-ti-qspi.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 34b154922ff2..5851574a4292 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -167,10 +167,10 @@ static int ti_qspi_setup(struct spi_device *spi)
return 0;
}
-static void ti_qspi_setup_clk(struct ti_qspi *qspi, u32 speed_hz)
+static int ti_qspi_setup_clk(struct ti_qspi *qspi, u32 speed_hz)
{
struct ti_qspi_regs *ctx_reg = &qspi->ctx_reg;
- int clk_div;
+ int clk_div, ret;
u32 clk_ctrl_reg, clk_rate, clk_ctrl_new;
clk_rate = clk_get_rate(qspi->fclk);
@@ -178,7 +178,9 @@ static void ti_qspi_setup_clk(struct ti_qspi *qspi, u32 speed_hz)
clk_div = clamp(clk_div, 0, QSPI_CLK_DIV_MAX);
dev_dbg(qspi->dev, "hz: %d, clock divider %d\n", speed_hz, clk_div);
- pm_runtime_resume_and_get(qspi->dev);
+ ret = pm_runtime_resume_and_get(qspi->dev);
+ if (ret < 0)
+ return ret;
clk_ctrl_new = QSPI_CLK_EN | clk_div;
if (ctx_reg->clkctrl != clk_ctrl_new) {
@@ -195,6 +197,8 @@ static void ti_qspi_setup_clk(struct ti_qspi *qspi, u32 speed_hz)
}
pm_runtime_put_autosuspend(qspi->dev);
+
+ return 0;
}
static void ti_qspi_restore_ctx(struct ti_qspi *qspi)
@@ -621,7 +625,9 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
mutex_lock(&qspi->list_lock);
if (!qspi->mmap_enabled || qspi->current_cs != spi_get_chipselect(mem->spi, 0)) {
- ti_qspi_setup_clk(qspi, op->max_freq);
+ ret = ti_qspi_setup_clk(qspi, op->max_freq);
+ if (ret)
+ goto unlock;
ti_qspi_enable_memory_map(mem->spi);
}
ti_qspi_setup_mmap_read(mem->spi, op->cmd.opcode, op->data.buswidth,
@@ -646,6 +652,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
op->data.nbytes);
}
+unlock:
mutex_unlock(&qspi->list_lock);
return ret;
@@ -704,7 +711,11 @@ static int ti_qspi_start_transfer_one(struct spi_controller *host,
wlen = t->bits_per_word >> 3;
transfer_len_words = min(t->len / wlen, frame_len_words);
- ti_qspi_setup_clk(qspi, t->speed_hz);
+ ret = ti_qspi_setup_clk(qspi, t->speed_hz);
+ if (ret) {
+ mutex_unlock(&qspi->list_lock);
+ return ret;
+ }
ret = qspi_transfer_msg(qspi, t, transfer_len_words * wlen);
if (ret) {
dev_dbg(qspi->dev, "transfer message failed\n");
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 0/2] spi: handle runtime resume failures
2026-10-19 8:44 [PATCH 0/2] spi: handle runtime resume failures Jiale Yao
2026-10-19 8:44 ` [PATCH 1/2] spi: stm32-ospi: handle runtime resume failure in remove Jiale Yao
2026-10-19 8:44 ` [PATCH 2/2] spi: ti-qspi: handle setup clock runtime resume failure Jiale Yao
@ 2026-11-02 22:39 ` Mark Brown
2 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-11-02 22:39 UTC (permalink / raw)
To: Maxime Coquelin, Alexandre Torgue, Patrice Chotard, Felix Gu,
Atsushi Nemoto, linux-spi, linux-stm32, linux-arm-kernel,
linux-kernel, Jiale Yao
On Mon, 19 Oct 2026 16:44:41 +0800, Jiale Yao wrote:
> spi: handle runtime resume failures
>
> The STM32 OSPI remove path and the TI QSPI clock setup helper ignore
> pm_runtime_resume_and_get() failures. A failed runtime resume leaves the
> controller unavailable, so following register accesses are unsafe and a
> later runtime PM put can be unmatched.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.5
Thanks!
[1/2] spi: stm32-ospi: handle runtime resume failure in remove
https://git.kernel.org/broonie/spi/c/e359991c180a
[2/2] spi: ti-qspi: handle setup clock runtime resume failure
https://git.kernel.org/broonie/spi/c/b21192833996
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread