From 6dbaa4d288432c697cea47028480481b8b29bd6a Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Tue, 23 Jun 2026 21:58:34 +0800 Subject: [PATCH 1/2] spi: sh-msiof: abort transfers when reset times out sh_msiof_spi_reset_regs() asserts TX/RX reset and polls until the reset bits clear, but the poll result is ignored. sh_msiof_transfer_one() can therefore continue programming a transfer after the controller did not leave reset. Return the reset poll result from the helper and abort the transfer on timeout, matching the existing transfer path's error-return style. Fixes: fedd6940682a ("spi: sh-msiof: Add reset of registers before starting transfer") Signed-off-by: Pengpeng Hou Link: https://patch.msgid.link/20260623135834.55442-1-pengpeng@iscas.ac.cn Signed-off-by: Mark Brown --- drivers/spi/spi-sh-msiof.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index f23db85a1889..1aeab7ec0bc8 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -114,7 +114,7 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data) return IRQ_HANDLED; } -static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) +static int sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) { u32 mask = SICTR_TXRST | SICTR_RXRST; u32 data; @@ -123,8 +123,8 @@ static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) data |= mask; sh_msiof_write(p, SICTR, data); - readl_poll_timeout_atomic(p->mapbase + SICTR, data, !(data & mask), 1, - 100); + return readl_poll_timeout_atomic(p->mapbase + SICTR, data, + !(data & mask), 1, 100); } static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, @@ -834,7 +834,9 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr, int ret; /* reset registers */ - sh_msiof_spi_reset_regs(p); + ret = sh_msiof_spi_reset_regs(p); + if (ret) + return ret; /* setup clocks (clock already enabled in chipselect()) */ if (!spi_controller_is_target(p->ctlr)) From c1bab046d4786c5b17aab7c5225bf0d4a2a2d19b Mon Sep 17 00:00:00 2001 From: Praveen Talari Date: Thu, 25 Jun 2026 21:26:02 +0530 Subject: [PATCH 2/2] spi: core: Abort active target transfer on controller suspend When an SPI controller operating in target mode has a transfer in progress at the time of system suspend, the suspend path proceeds without aborting the ongoing transfer. This can leave the hardware in an inconsistent state, potentially causing the system to hang or fail to resume cleanly. Fix this by invoking the controller's target_abort callback from spi_controller_suspend() when the controller is in target mode and the callback is registered. This ensures any active target transfer is cleanly terminated before the controller is suspended. Signed-off-by: Praveen Talari Link: https://patch.msgid.link/20260625-abort_active_transfer_duirng_s2r-v2-1-1d6f724406b6@oss.qualcomm.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d7e584afa301..f35d288c64fe 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3671,6 +3671,9 @@ int spi_controller_suspend(struct spi_controller *ctlr) { int ret = 0; + if (ctlr->cur_msg && spi_controller_is_target(ctlr) && ctlr->target_abort) + ctlr->target_abort(ctlr); + /* Basically no-ops for non-queued controllers */ if (ctlr->queued) { ret = spi_stop_queue(ctlr);