From 2469e191079671e3ad0bdcb417ce97f5959cec28 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Sun, 21 Jul 2024 14:02:36 +0800 Subject: [PATCH] spi: rockchip: Support failed retry poll SPI transmission exception is often caused by an abnormality in the IRQ subsystem in the environment, so an attempt is made to switch to the poll transmission scheme in order to expect the SPI module to continue working. Change-Id: I1fc0451efef501a5a462931515a25e48c4fd1765 Signed-off-by: Jon Lin --- drivers/spi/spi-rockchip.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index e80f7379100f..8e7b566b1c8a 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -216,6 +216,8 @@ struct rockchip_spi { u8 rsd; u8 csm; bool poll; /* only support transfer data by cpu polling */ + bool retry_poll; /* SPI adjustment when the system irq abnormally */ + bool retry_poll_active; bool cs_asserted[ROCKCHIP_SPI_MAX_CS_NUM]; @@ -314,6 +316,8 @@ static void rockchip_spi_handle_err(struct spi_controller *ctlr, { struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); + if (rs->retry_poll) + dev_err(rs->dev, "poll=%d-%d\n", rs->poll, rs->retry_poll_active); dev_err(rs->dev, "state=%x\n", atomic_read(&rs->state)); dev_err(rs->dev, "tx_left=%x\n", rs->tx_left); dev_err(rs->dev, "rx_left=%x\n", rs->rx_left); @@ -334,6 +338,8 @@ static void rockchip_spi_handle_err(struct spi_controller *ctlr, if (atomic_read(&rs->state) & RXDMA) dmaengine_terminate_async(ctlr->dma_rx); atomic_set(&rs->state, 0); + if (rs->retry_poll) + rs->retry_poll_active = true; } static void rockchip_spi_pio_writer(struct rockchip_spi *rs) @@ -832,7 +838,7 @@ static int rockchip_spi_transfer_one( rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2; rs->xfer = xfer; - if (rs->poll) { + if (rs->poll || rs->retry_poll_active) { xfer_mode = ROCKCHIP_SPI_POLL; } else { use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false; @@ -1179,8 +1185,9 @@ static int rockchip_spi_probe(struct platform_device *pdev) } rs->poll = device_property_read_bool(&pdev->dev, "rockchip,poll-only"); + rs->retry_poll = device_property_read_bool(&pdev->dev, "rockchip,failed-retry-poll"); init_completion(&rs->xfer_done); - if (rs->poll && slave_mode) { + if ((rs->poll || rs->retry_poll) && slave_mode) { dev_err(rs->dev, "only support rockchip,poll-only property in master mode\n"); ret = -EINVAL; goto err_free_dma_rx; @@ -1319,6 +1326,9 @@ static int rockchip_spi_runtime_resume(struct device *dev) if (ret < 0) clk_disable_unprepare(rs->apb_pclk); + if (rs->retry_poll) + rs->retry_poll_active = false; + return 0; } #endif /* CONFIG_PM */