]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
spi: sh-msiof: abort transfers when reset times out
authorPengpeng Hou <pengpeng@iscas.ac.cn>
Tue, 23 Jun 2026 13:58:34 +0000 (21:58 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 25 Jun 2026 12:49:00 +0000 (13:49 +0100)
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 <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260623135834.55442-1-pengpeng@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-sh-msiof.c

index f23db85a1889d509feae8f199968fc9d2457ab06..1aeab7ec0bc8d03d5db5a89702a05dfcda836c9b 100644 (file)
@@ -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))