Skip to content

Commit 7bf0784

Browse files
john-madieugregkh
authored andcommitted
spi: rockchip: Read ISR, not IMR, to detect cs-inactive IRQ
[ Upstream commit b4683a2 ] rockchip_spi_isr() decides whether the current interrupt was the cs-inactive event by reading IMR: if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) ctlr->target_abort(ctlr); IMR is the interrupt mask register: it tells which sources are enabled, not which one fired. In the PIO path, rockchip_spi_prepare_irq() enables both INT_RF_FULL and INT_CS_INACTIVE in IMR when rs->cs_inactive is true: if (rs->cs_inactive) writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR); so the IMR check is always true once cs_inactive is enabled, and every PIO interrupt - including normal RF_FULL completions - is dispatched to ctlr->target_abort(), aborting the transfer. The bug is reachable on ROCKCHIP_SPI_VER2_TYPE2 in target mode with a DMA-capable controller when the transfer is short enough to fall back to PIO (rockchip_spi_can_dma() returns false below fifo_len). Read ISR (which is RISR masked by IMR) so the check actually reflects which interrupt fired, and parenthesise the expression for clarity while at it. Fixes: 869f2c9 ("spi: rockchip: Stop spi slave dma receiver when cs inactive") Signed-off-by: John Madieu <john.madieu@gmail.com> Link: https://patch.msgid.link/20260425092936.2590132-2-john.madieu@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c4632c6 commit 7bf0784

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

drivers/spi/spi-rockchip.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,8 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
357357
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
358358

359359
/* When int_cs_inactive comes, spi target abort */
360-
if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) {
360+
if (rs->cs_inactive &&
361+
(readl_relaxed(rs->regs + ROCKCHIP_SPI_ISR) & INT_CS_INACTIVE)) {
361362
ctlr->target_abort(ctlr);
362363
writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
363364
writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);

0 commit comments

Comments
 (0)