diff options
author | 2025-04-28 15:58:56 -0500 | |
---|---|---|
committer | 2025-04-30 09:38:37 +0900 | |
commit | 1d0ee0c9df31c9fd1e4f8d7e2464e36fbf6e3f75 (patch) | |
tree | ae98bec4720c38a66f63988035f59572e65605b5 | |
parent | Linux 6.15-rc4 (diff) | |
download | wireguard-linux-1d0ee0c9df31c9fd1e4f8d7e2464e36fbf6e3f75.tar.xz wireguard-linux-1d0ee0c9df31c9fd1e4f8d7e2464e36fbf6e3f75.zip |
spi: axi-spi-engine: wait for completion in setup
Add a polling wait for SPI instruction execution to complete in the
spi_engine_setup() function. In practice, these instructions complete
in a few 10s of nanoseconds, so we never ran into any race conditions,
but it is good practice to wait for the completion of the SPI engine
instructions before returning from the setup function.
Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250428-adi-main-v1-1-4b8a1b88a212@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-axi-spi-engine.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index da9840957778..d040deffa9bb 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -14,6 +14,7 @@ #include <linux/fpga/adi-axi-common.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/of.h> #include <linux/module.h> #include <linux/overflow.h> @@ -739,12 +740,16 @@ static int spi_engine_setup(struct spi_device *device) { struct spi_controller *host = device->controller; struct spi_engine *spi_engine = spi_controller_get_devdata(host); + unsigned int reg; if (device->mode & SPI_CS_HIGH) spi_engine->cs_inv |= BIT(spi_get_chipselect(device, 0)); else spi_engine->cs_inv &= ~BIT(spi_get_chipselect(device, 0)); + writel_relaxed(SPI_ENGINE_CMD_SYNC(0), + spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); + writel_relaxed(SPI_ENGINE_CMD_CS_INV(spi_engine->cs_inv), spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); @@ -755,7 +760,11 @@ static int spi_engine_setup(struct spi_device *device) writel_relaxed(SPI_ENGINE_CMD_ASSERT(0, 0xff), spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); - return 0; + writel_relaxed(SPI_ENGINE_CMD_SYNC(1), + spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); + + return readl_relaxed_poll_timeout(spi_engine->base + SPI_ENGINE_REG_SYNC_ID, + reg, reg == 1, 1, 1000); } static int spi_engine_transfer_one_message(struct spi_controller *host, |