diff options
author | Tudor Ambarus <tudor.ambarus@linaro.org> | 2024-02-07 11:15:15 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2024-02-08 16:33:46 +0000 |
commit | b7bafb9f54fc4609ff84ecd633f918f6f973f471 (patch) | |
tree | 0f35f5255dd5a6ceca9c1b5bb6c517a624ddca5e /drivers/spi | |
parent | 80d3204a3b1dbef570ed29d4d375e4d6922da82d (diff) |
spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
Allow SoCs that require 32 bits register accesses to write data in
chunks of 8 or 16 bits. One SoC that requires 32 bit register accesses
is the google gs101. The operation is rare, thus open code it in the
driver rather than making it generic (through asm-generic/io.h).
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Link: https://lore.kernel.org/r/20240207111516.2563218-4-tudor.ambarus@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index eb79c6e4f509..014fcc933c90 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -142,6 +142,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 only 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 @@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config { bool clk_from_cmu; bool clk_ioclk; bool has_loopback; + bool use_32bit_io; }; /** @@ -414,6 +416,30 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host, } +static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr, + const void *buffer, unsigned int count) +{ + if (count) { + const u8 *buf = buffer; + + do { + __raw_writel(*buf++, addr); + } while (--count); + } +} + +static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr, + const void *buffer, unsigned int count) +{ + if (count) { + const u16 *buf = buffer; + + do { + __raw_writel(*buf++, addr); + } while (--count); + } +} + static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd, struct spi_transfer *xfer) { @@ -426,10 +452,16 @@ static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd, iowrite32_rep(addr, buf, len / 4); break; case 16: - iowrite16_rep(addr, buf, len / 2); + if (sdd->port_conf->use_32bit_io) + s3c64xx_iowrite16_32_rep(addr, buf, len / 2); + else + iowrite16_rep(addr, buf, len / 2); break; default: - iowrite8_rep(addr, buf, len); + if (sdd->port_conf->use_32bit_io) + s3c64xx_iowrite8_32_rep(addr, buf, len); + else + iowrite8_rep(addr, buf, len); break; } } |