[PATCH v2 26/28] spi: s3c64xx: add iowrite{8,16}_32_rep accessors

From: Tudor Ambarus
Date: Thu Jan 25 2024 - 09:58:04 EST


There are SoCs that allow just 32 bit register accesses otherwise they
throw a SError interrupt if accessing the bus with 8 or 16 bits widths.
Such an SoC is the google gs101. Allow such SoCs to use the
iowrite{8,16}_32_rep accessors.

Signed-off-by: Tudor Ambarus <tudor.ambarus@xxxxxxxxxx>
---
drivers/spi/spi-s3c64xx.c | 46 +++++++++++++++++++++++++++------------
1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index fa70c6aab7c2..35a2d5554dfd 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -139,6 +139,7 @@ struct s3c64xx_spi_dma_data {
* prescaler unit.
* @clk_ioclk: True if clock is present on this device
* @has_loopback: True if loopback mode can be supported
+ * @use_32bit_io: True if the SoC allows just 32-bit register accesses.
*
* The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
* differ in some aspects such as the size of the fifo and spi bus clock
@@ -156,6 +157,7 @@ struct s3c64xx_spi_port_config {
bool clk_from_cmu;
bool clk_ioclk;
bool has_loopback;
+ bool use_32bit_io;
};

/**
@@ -412,6 +414,35 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
return false;
}

+static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
+ struct spi_transfer *xfer)
+{
+ void __iomem *regs = sdd->regs;
+
+ switch (sdd->cur_bpw) {
+ case 32:
+ iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 4);
+ break;
+ case 16:
+ if (sdd->port_conf->use_32bit_io)
+ iowrite16_32_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 2);
+ else
+ iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 2);
+ break;
+ default:
+ if (sdd->port_conf->use_32bit_io)
+ iowrite8_32_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len);
+ else
+ iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len);
+ break;
+ }
+}
+
static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
struct spi_transfer *xfer, int dma_mode)
{
@@ -445,20 +476,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
} else {
- switch (sdd->cur_bpw) {
- case 32:
- iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
- xfer->tx_buf, xfer->len / 4);
- break;
- case 16:
- iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
- xfer->tx_buf, xfer->len / 2);
- break;
- default:
- iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
- xfer->tx_buf, xfer->len);
- break;
- }
+ s3c64xx_iowrite_rep(sdd, xfer);
}
}

--
2.43.0.429.g432eaa2c6b-goog