diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-01 19:09:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-01 19:09:04 -0700 |
commit | 2019295c9ea3137364682046bb6afc0eb364e591 (patch) | |
tree | 0f905528cd55cce6e1cd0db952f70f0531b06ff6 /drivers/spi/spi-amd.c | |
parent | 1260d242d94ae423c585050bbaabe9064741f419 (diff) | |
parent | 28b5eaf9712bbed90c2b5a5608d70a16b7950856 (diff) |
Merge tag 'spi-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"This is quite a quiet release for SPI, there's been a bit of cleanup
to the core from Uwe but nothing functionality wise.
We have added several new drivers, Cadence XSPI, Ingenic JZ47xx,
Qualcomm SC7280 and SC7180 and Xilinx Versal OSPI"
* tag 'spi-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (41 commits)
spi: Convert NXP flexspi to json schema
spi: spi-geni-qcom: Add support for GPI dma
spi: fsi: Fix contention in the FSI2SPI engine
spi: spi-rpc-if: Check return value of rpcif_sw_init()
spi: tegra210-quad: Put device into suspend on driver removal
spi: tegra20-slink: Put device into suspend on driver removal
spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in bcm_qspi_probe()
spi: at91-usart: replacing legacy gpio interface for gpiod
spi: replace snprintf in show functions with sysfs_emit
spi: cadence: Add of_node_put() before return
spi: orion: Add of_node_put() before goto
spi: cadence-quadspi: fix dma_unmap_single() call
spi: tegra20: fix build with CONFIG_PM_SLEEP=n
spi: bcm-qspi: add support for 3-wire mode for half duplex transfer
spi: bcm-qspi: Add mspi spcr3 32/64-bits xfer mode
spi: Make several public functions private to spi.c
spi: Reorder functions to simplify the next commit
spi: Remove unused function spi_busnum_to_master()
spi: Move comment about chipselect check to the right place
spi: fsi: Print status on error
...
Diffstat (limited to 'drivers/spi/spi-amd.c')
-rw-r--r-- | drivers/spi/spi-amd.c | 113 |
1 files changed, 43 insertions, 70 deletions
diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 3cf76096a76d..4b3ac7aceaf6 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -38,126 +38,102 @@ struct amd_spi { void __iomem *io_remap_addr; unsigned long io_base_addr; u32 rom_addr; - u8 chip_select; }; -static inline u8 amd_spi_readreg8(struct spi_master *master, int idx) +static inline u8 amd_spi_readreg8(struct amd_spi *amd_spi, int idx) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - return ioread8((u8 __iomem *)amd_spi->io_remap_addr + idx); } -static inline void amd_spi_writereg8(struct spi_master *master, int idx, - u8 val) +static inline void amd_spi_writereg8(struct amd_spi *amd_spi, int idx, u8 val) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - iowrite8(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx)); } -static inline void amd_spi_setclear_reg8(struct spi_master *master, int idx, - u8 set, u8 clear) +static void amd_spi_setclear_reg8(struct amd_spi *amd_spi, int idx, u8 set, u8 clear) { - u8 tmp = amd_spi_readreg8(master, idx); + u8 tmp = amd_spi_readreg8(amd_spi, idx); tmp = (tmp & ~clear) | set; - amd_spi_writereg8(master, idx, tmp); + amd_spi_writereg8(amd_spi, idx, tmp); } -static inline u32 amd_spi_readreg32(struct spi_master *master, int idx) +static inline u32 amd_spi_readreg32(struct amd_spi *amd_spi, int idx) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - return ioread32((u8 __iomem *)amd_spi->io_remap_addr + idx); } -static inline void amd_spi_writereg32(struct spi_master *master, int idx, - u32 val) +static inline void amd_spi_writereg32(struct amd_spi *amd_spi, int idx, u32 val) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - iowrite32(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx)); } -static inline void amd_spi_setclear_reg32(struct spi_master *master, int idx, - u32 set, u32 clear) +static inline void amd_spi_setclear_reg32(struct amd_spi *amd_spi, int idx, u32 set, u32 clear) { - u32 tmp = amd_spi_readreg32(master, idx); + u32 tmp = amd_spi_readreg32(amd_spi, idx); tmp = (tmp & ~clear) | set; - amd_spi_writereg32(master, idx, tmp); + amd_spi_writereg32(amd_spi, idx, tmp); } -static void amd_spi_select_chip(struct spi_master *master) +static void amd_spi_select_chip(struct amd_spi *amd_spi, u8 cs) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - u8 chip_select = amd_spi->chip_select; - - amd_spi_setclear_reg8(master, AMD_SPI_ALT_CS_REG, chip_select, - AMD_SPI_ALT_CS_MASK); + amd_spi_setclear_reg8(amd_spi, AMD_SPI_ALT_CS_REG, cs, AMD_SPI_ALT_CS_MASK); } -static void amd_spi_clear_fifo_ptr(struct spi_master *master) +static void amd_spi_clear_fifo_ptr(struct amd_spi *amd_spi) { - amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, - AMD_SPI_FIFO_CLEAR); + amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, AMD_SPI_FIFO_CLEAR); } -static void amd_spi_set_opcode(struct spi_master *master, u8 cmd_opcode) +static void amd_spi_set_opcode(struct amd_spi *amd_spi, u8 cmd_opcode) { - amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, cmd_opcode, - AMD_SPI_OPCODE_MASK); + amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, cmd_opcode, AMD_SPI_OPCODE_MASK); } -static inline void amd_spi_set_rx_count(struct spi_master *master, - u8 rx_count) +static inline void amd_spi_set_rx_count(struct amd_spi *amd_spi, u8 rx_count) { - amd_spi_setclear_reg8(master, AMD_SPI_RX_COUNT_REG, rx_count, 0xff); + amd_spi_setclear_reg8(amd_spi, AMD_SPI_RX_COUNT_REG, rx_count, 0xff); } -static inline void amd_spi_set_tx_count(struct spi_master *master, - u8 tx_count) +static inline void amd_spi_set_tx_count(struct amd_spi *amd_spi, u8 tx_count) { - amd_spi_setclear_reg8(master, AMD_SPI_TX_COUNT_REG, tx_count, 0xff); + amd_spi_setclear_reg8(amd_spi, AMD_SPI_TX_COUNT_REG, tx_count, 0xff); } -static inline int amd_spi_busy_wait(struct amd_spi *amd_spi) +static int amd_spi_busy_wait(struct amd_spi *amd_spi) { - bool spi_busy; int timeout = 100000; /* poll for SPI bus to become idle */ - spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr + - AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY; - while (spi_busy) { + while (amd_spi_readreg32(amd_spi, AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) { usleep_range(10, 20); if (timeout-- < 0) return -ETIMEDOUT; - - spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr + - AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY; } return 0; } -static void amd_spi_execute_opcode(struct spi_master *master) +static int amd_spi_execute_opcode(struct amd_spi *amd_spi) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); + int ret; + + ret = amd_spi_busy_wait(amd_spi); + if (ret) + return ret; /* Set ExecuteOpCode bit in the CTRL0 register */ - amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, - AMD_SPI_EXEC_CMD); + amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, AMD_SPI_EXEC_CMD); - amd_spi_busy_wait(amd_spi); + return 0; } static int amd_spi_master_setup(struct spi_device *spi) { - struct spi_master *master = spi->master; + struct amd_spi *amd_spi = spi_master_get_devdata(spi->master); - amd_spi_clear_fifo_ptr(master); + amd_spi_clear_fifo_ptr(amd_spi); return 0; } @@ -185,19 +161,18 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, tx_len = xfer->len - 1; cmd_opcode = *(u8 *)xfer->tx_buf; buf++; - amd_spi_set_opcode(master, cmd_opcode); + amd_spi_set_opcode(amd_spi, cmd_opcode); /* Write data into the FIFO. */ for (i = 0; i < tx_len; i++) { - iowrite8(buf[i], - ((u8 __iomem *)amd_spi->io_remap_addr + + iowrite8(buf[i], ((u8 __iomem *)amd_spi->io_remap_addr + AMD_SPI_FIFO_BASE + i)); } - amd_spi_set_tx_count(master, tx_len); - amd_spi_clear_fifo_ptr(master); + amd_spi_set_tx_count(amd_spi, tx_len); + amd_spi_clear_fifo_ptr(amd_spi); /* Execute command */ - amd_spi_execute_opcode(master); + amd_spi_execute_opcode(amd_spi); } if (m_cmd & AMD_SPI_XFER_RX) { /* @@ -206,15 +181,14 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, */ rx_len = xfer->len; buf = (u8 *)xfer->rx_buf; - amd_spi_set_rx_count(master, rx_len); - amd_spi_clear_fifo_ptr(master); + amd_spi_set_rx_count(amd_spi, rx_len); + amd_spi_clear_fifo_ptr(amd_spi); /* Execute command */ - amd_spi_execute_opcode(master); + amd_spi_execute_opcode(amd_spi); + amd_spi_busy_wait(amd_spi); /* Read data from FIFO to receive buffer */ for (i = 0; i < rx_len; i++) - buf[i] = amd_spi_readreg8(master, - AMD_SPI_FIFO_BASE + - tx_len + i); + buf[i] = amd_spi_readreg8(amd_spi, AMD_SPI_FIFO_BASE + tx_len + i); } } @@ -233,8 +207,7 @@ static int amd_spi_master_transfer(struct spi_master *master, struct amd_spi *amd_spi = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; - amd_spi->chip_select = spi->chip_select; - amd_spi_select_chip(master); + amd_spi_select_chip(amd_spi, spi->chip_select); /* * Extract spi_transfers from the spi message and |