Message ID | 20240125145007.748295-1-tudor.ambarus@linaro.org |
---|---|
Headers | show |
Series | spi: s3c64xx: winter cleanup and gs101 support | expand |
On Thu, Jan 25, 2024 at 02:49:59PM +0000, Tudor Ambarus wrote: > Infer the FIFO size from the compatible, where all the instances of the > SPI IP have the same FIFO size. This way we no longer depend on the SPI > alias from the device tree to select the FIFO size, thus we remove the > dependency of the driver on the SPI alias. > static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = { > - .fifo_lvl_mask = { 0x7f }, > + .fifosize = 64, > .rx_lvl_offset = 13, > .tx_st_done = 21, > .clk_div = 2, I'm having real trouble associating the changelog with the change here. This appears to be changing from specifying the mask for the FIFO level register to specifying the size of the FIFO and unrelated to anything to do with looking things up from the compatible?
On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote: > Allow SoCs that have multiple instances of the SPI IP with different > FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize" > device tree property. With this we can break the dependency between the > SPI alias, the fifo_lvl_mask and the FIFO size. OK, so we do actually have SoCs with multiple instances of the IP with different FIFO depths (and who knows what else other differences)?
On Thu, Jan 25, 2024 at 02:50:03PM +0000, Tudor Ambarus wrote: > This will allow devices 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. A > typical use case is SPI, where the clients can request transfers in words > of 8 bits. Might be good to CC this one to linux-arch if reposting.
On 1/25/24 17:18, Mark Brown wrote: > On Thu, Jan 25, 2024 at 02:49:59PM +0000, Tudor Ambarus wrote: > >> Infer the FIFO size from the compatible, where all the instances of the >> SPI IP have the same FIFO size. This way we no longer depend on the SPI >> alias from the device tree to select the FIFO size, thus we remove the >> dependency of the driver on the SPI alias. > >> static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = { >> - .fifo_lvl_mask = { 0x7f }, >> + .fifosize = 64, >> .rx_lvl_offset = 13, >> .tx_st_done = 21, >> .clk_div = 2, > > I'm having real trouble associating the changelog with the change here. > This appears to be changing from specifying the mask for the FIFO level > register to specifying the size of the FIFO and unrelated to anything to > do with looking things up from the compatible? Let me try to explain everything. In the driver there is a weird dependency between the SPI of_alias ID, s3c64xx_spi_port_config.fifo_lvl_mask and the IP's FIFO depth. s3c64xx_spi_port_config.fifo_lvl_mask is not a 1:1 match with the SPI_STATUSn.{RX, TX}_FIFO_LVL register field. Those fields are defined in the datasheet as: +#define S3C64XX_SPI_ST_RX_FIFO_LVL GENMASK(23, 15) +#define S3C64XX_SPI_ST_TX_FIFO_LVL GENMASK(14, 6) Thus the register mask is on 9 bits, but the driver used either 0x1ff or 0x7f, which was not reflecting the real register mask. Patch 10/28 updates the driver to use the full register mask regardless of the FIFO depth configuration. Another problem with s3c64xx_spi_port_config.fifo_lvl_mask is that it was used as a way to determine the FIFO depth. The SPI of_alias ID was used as an index in this array to determine the FIFO depth with something like fifo_depth = (fifo_lvl_mask[alias_id] >> 1) + 1 For example, if one wanted to specify a 64 FIFO length (0x40), it would have configured the FIFO level to 127 (0x7f). The patch set breaks this weird dependencies. Obviously the FIFO depth must be tightly tied by the compatible and not by an alias. I tied the FIFO depth to the compatible in 2 ways: 1/ For SoCs that have all the SPI nodes with the same FIFO depth, I chose to deduce the FIFO depth from the compatible. Instead of specifying "samsung,spi-fifosize" for all the gs101 SPI nodes in the device tree, I chose to infer it from the compatible. I know for sure that all the gs101 SPI nodes have 64 bytes FIFO depths, thus don't pollute the device tree with superfluous info. (patches 20/28 and 21/28) 2/ For SoCs that have instances of the SPI IP with different FIFO depths, specify the node's FIFO depth via the "samsung,spi-fifosize" dt property. (patch 23/28) Hope this helps. Please tell if you want me to elaborate on something.
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > The platform id is used as an index into the fifo_lvl_mask array. > Platforms can come with a negative device ID, PLATFORM_DEVID_NONE (-1), > thus we risked a negative array index. Catch such cases and fail to > probe. > > Fixes: 2b90807549e5 ("spi: s3c64xx: add device tree support") > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 2b5bb7604526..c3176a510643 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1189,6 +1189,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) > "Failed to get alias id\n"); > sdd->port_id = ret; > } else { > + if (pdev->id < 0) I'd add { } braces around this block, but that's a matter of taste. Also, I'm not sure why do we still want to handle !of_node case for drivers like these at all: there is no mfd case for this driver, and board files are long gone; it seems to be OF only driver in a sense, from its users POV. Anyways, LGTM: Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > + return dev_err_probe(&pdev->dev, -EINVAL, > + "Negative platform ID is not allowed\n"); > sdd->port_id = pdev->id; > } > > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > The driver uses readl() but does not include <linux/io.h>. > > It is good practice to directly include all headers used, it avoids > implicit dependencies and spurious breakage if someone rearranges > headers and causes the implicit include to vanish. > > Include the missing header. > > Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver") Not sure the "Fixes" tag is needed here. AFAIU, this patch doesn't fix any actual bugs, seems more like a style fix to me. In other words, I'm not convinced it has to be necessarily backported to stable kernels. The same goes for another similar patch from this series. > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 7f7eb8f742e4..c1cbc4780a3b 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -10,6 +10,7 @@ > #include <linux/clk.h> > #include <linux/dma-mapping.h> > #include <linux/dmaengine.h> > +#include <linux/io.h> > #include <linux/platform_device.h> > #include <linux/pm_runtime.h> > #include <linux/spi/spi.h> > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > of_device_id::data is an opaque pointer. No explicit cast is needed. > Remove unneeded (void *) casts in of_match_table. While here align the > compatible and data members. > > Reviewed-by: Andi Shyti <andi.shyti@kernel.org> > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 45 +++++++++++++++++++++++---------------- > 1 file changed, 27 insertions(+), 18 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 230fda2b3417..137faf9f2697 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1511,32 +1511,41 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = { > }; > > static const struct of_device_id s3c64xx_spi_dt_match[] = { > - { .compatible = "samsung,s3c2443-spi", > - .data = (void *)&s3c2443_spi_port_config, I support removing (void *) cast. But this new braces style: }, { seems to bloat the code a bit. For my taste, having something like }, { on the same line would be more compact, and more canonical so to speak. Or even preserving the existing style would be ok too, for that matter. Assuming the braces style is fixed, you can add: Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > + { > + .compatible = "samsung,s3c2443-spi", > + .data = &s3c2443_spi_port_config, > }, > - { .compatible = "samsung,s3c6410-spi", > - .data = (void *)&s3c6410_spi_port_config, > + { > + .compatible = "samsung,s3c6410-spi", > + .data = &s3c6410_spi_port_config, > }, > - { .compatible = "samsung,s5pv210-spi", > - .data = (void *)&s5pv210_spi_port_config, > + { > + .compatible = "samsung,s5pv210-spi", > + .data = &s5pv210_spi_port_config, > }, > - { .compatible = "samsung,exynos4210-spi", > - .data = (void *)&exynos4_spi_port_config, > + { > + .compatible = "samsung,exynos4210-spi", > + .data = &exynos4_spi_port_config, > }, > - { .compatible = "samsung,exynos7-spi", > - .data = (void *)&exynos7_spi_port_config, > + { > + .compatible = "samsung,exynos7-spi", > + .data = &exynos7_spi_port_config, > }, > - { .compatible = "samsung,exynos5433-spi", > - .data = (void *)&exynos5433_spi_port_config, > + { > + .compatible = "samsung,exynos5433-spi", > + .data = &exynos5433_spi_port_config, > }, > - { .compatible = "samsung,exynos850-spi", > - .data = (void *)&exynos850_spi_port_config, > + { > + .compatible = "samsung,exynos850-spi", > + .data = &exynos850_spi_port_config, > }, > - { .compatible = "samsung,exynosautov9-spi", > - .data = (void *)&exynosautov9_spi_port_config, > + { > + .compatible = "samsung,exynosautov9-spi", > + .data = &exynosautov9_spi_port_config, > }, > - { .compatible = "tesla,fsd-spi", > - .data = (void *)&fsd_spi_port_config, > + { > + .compatible = "tesla,fsd-spi", > + .data = &fsd_spi_port_config, > }, > { }, > }; > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Use the bitfield access macros in order to clean and to make the driver > easier to read. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 196 +++++++++++++++++++------------------- > 1 file changed, 99 insertions(+), 97 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 1e44b24f6401..d046810da51f 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -4,6 +4,7 @@ > // Jaswinder Singh <jassi.brar@samsung.com> > > #include <linux/bits.h> > +#include <linux/bitfield.h> > #include <linux/clk.h> > #include <linux/delay.h> > #include <linux/dma-mapping.h> > @@ -18,91 +19,91 @@ > #include <linux/pm_runtime.h> > #include <linux/spi/spi.h> > > -#define MAX_SPI_PORTS 12 > -#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1) > -#define AUTOSUSPEND_TIMEOUT 2000 > +#define MAX_SPI_PORTS 12 > +#define S3C64XX_SPI_QUIRK_CS_AUTO BIT(1) > +#define AUTOSUSPEND_TIMEOUT 2000 > > /* Registers and bit-fields */ > > -#define S3C64XX_SPI_CH_CFG 0x00 > -#define S3C64XX_SPI_CLK_CFG 0x04 > -#define S3C64XX_SPI_MODE_CFG 0x08 > -#define S3C64XX_SPI_CS_REG 0x0C > -#define S3C64XX_SPI_INT_EN 0x10 > -#define S3C64XX_SPI_STATUS 0x14 > -#define S3C64XX_SPI_TX_DATA 0x18 > -#define S3C64XX_SPI_RX_DATA 0x1C > -#define S3C64XX_SPI_PACKET_CNT 0x20 > -#define S3C64XX_SPI_PENDING_CLR 0x24 > -#define S3C64XX_SPI_SWAP_CFG 0x28 > -#define S3C64XX_SPI_FB_CLK 0x2C > - > -#define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */ > -#define S3C64XX_SPI_CH_SW_RST (1<<5) > -#define S3C64XX_SPI_CH_SLAVE (1<<4) > -#define S3C64XX_SPI_CPOL_L (1<<3) > -#define S3C64XX_SPI_CPHA_B (1<<2) > -#define S3C64XX_SPI_CH_RXCH_ON (1<<1) > -#define S3C64XX_SPI_CH_TXCH_ON (1<<0) > - > -#define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9) > -#define S3C64XX_SPI_CLKSEL_SRCSHFT 9 > -#define S3C64XX_SPI_ENCLK_ENABLE (1<<8) > -#define S3C64XX_SPI_PSR_MASK 0xff > - > -#define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29) > -#define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29) > -#define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29) > -#define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29) > -#define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17) > -#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17) > -#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17) > -#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17) > +#define S3C64XX_SPI_CH_CFG 0x00 > +#define S3C64XX_SPI_CLK_CFG 0x04 > +#define S3C64XX_SPI_MODE_CFG 0x08 > +#define S3C64XX_SPI_CS_REG 0x0C > +#define S3C64XX_SPI_INT_EN 0x10 > +#define S3C64XX_SPI_STATUS 0x14 > +#define S3C64XX_SPI_TX_DATA 0x18 > +#define S3C64XX_SPI_RX_DATA 0x1C > +#define S3C64XX_SPI_PACKET_CNT 0x20 > +#define S3C64XX_SPI_PENDING_CLR 0x24 > +#define S3C64XX_SPI_SWAP_CFG 0x28 > +#define S3C64XX_SPI_FB_CLK 0x2C > + > +#define S3C64XX_SPI_CH_HS_EN BIT(6) /* High Speed Enable */ > +#define S3C64XX_SPI_CH_SW_RST BIT(5) > +#define S3C64XX_SPI_CH_SLAVE BIT(4) > +#define S3C64XX_SPI_CPOL_L BIT(3) > +#define S3C64XX_SPI_CPHA_B BIT(2) > +#define S3C64XX_SPI_CH_RXCH_ON BIT(1) > +#define S3C64XX_SPI_CH_TXCH_ON BIT(0) > + > +#define S3C64XX_SPI_CLKSEL_SRCMSK GENMASK(10, 9) > +#define S3C64XX_SPI_ENCLK_ENABLE BIT(8) > +#define S3C64XX_SPI_PSR_MASK GENMASK(15, 0) But it was 0xff (7:0) originally, and here you extend it up to 15:0. Was it intentional? If so, I'd advice to keep non-functional changes as a separate patch, and pull all functional changes like these into another one, probably with an explanation why it's needed. > + > +#define S3C64XX_SPI_MODE_CH_TSZ_MASK GENMASK(30, 29) > +#define S3C64XX_SPI_MODE_CH_TSZ_BYTE 0 > +#define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD 1 > +#define S3C64XX_SPI_MODE_CH_TSZ_WORD 2 > +#define S3C64XX_SPI_MAX_TRAILCNT_MASK GENMASK(28, 19) > +#define S3C64XX_SPI_MODE_BUS_TSZ_MASK GENMASK(18, 17) > +#define S3C64XX_SPI_MODE_BUS_TSZ_BYTE 0 > +#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD 1 > +#define S3C64XX_SPI_MODE_BUS_TSZ_WORD 2 > #define S3C64XX_SPI_MODE_RX_RDY_LVL GENMASK(16, 11) > -#define S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT 11 > -#define S3C64XX_SPI_MODE_SELF_LOOPBACK (1<<3) > -#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2) > -#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1) > -#define S3C64XX_SPI_MODE_4BURST (1<<0) > - > -#define S3C64XX_SPI_CS_NSC_CNT_2 (2<<4) > -#define S3C64XX_SPI_CS_AUTO (1<<1) > -#define S3C64XX_SPI_CS_SIG_INACT (1<<0) > - > -#define S3C64XX_SPI_INT_TRAILING_EN (1<<6) > -#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) > -#define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4) > -#define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3) > -#define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2) > -#define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1) > -#define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0) > - > -#define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5) > -#define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4) > -#define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3) > -#define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2) > -#define S3C64XX_SPI_ST_RX_FIFORDY (1<<1) > -#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) > - > -#define S3C64XX_SPI_PACKET_CNT_EN (1<<16) > +#define S3C64XX_SPI_MODE_SELF_LOOPBACK BIT(3) > +#define S3C64XX_SPI_MODE_RXDMA_ON BIT(2) > +#define S3C64XX_SPI_MODE_TXDMA_ON BIT(1) > +#define S3C64XX_SPI_MODE_4BURST BIT(0) > + > +#define S3C64XX_SPI_CS_NSC_CNT_MASK GENMASK(9, 4) > +#define S3C64XX_SPI_CS_NSC_CNT_2 2 > +#define S3C64XX_SPI_CS_AUTO BIT(1) > +#define S3C64XX_SPI_CS_SIG_INACT BIT(0) > + > +#define S3C64XX_SPI_INT_TRAILING_EN BIT(6) > +#define S3C64XX_SPI_INT_RX_OVERRUN_EN BIT(5) > +#define S3C64XX_SPI_INT_RX_UNDERRUN_EN BIT(4) > +#define S3C64XX_SPI_INT_TX_OVERRUN_EN BIT(3) > +#define S3C64XX_SPI_INT_TX_UNDERRUN_EN BIT(2) > +#define S3C64XX_SPI_INT_RX_FIFORDY_EN BIT(1) > +#define S3C64XX_SPI_INT_TX_FIFORDY_EN BIT(0) > + > +#define S3C64XX_SPI_ST_RX_OVERRUN_ERR BIT(5) > +#define S3C64XX_SPI_ST_RX_UNDERRUN_ERR BIT(4) > +#define S3C64XX_SPI_ST_TX_OVERRUN_ERR BIT(3) > +#define S3C64XX_SPI_ST_TX_UNDERRUN_ERR BIT(2) > +#define S3C64XX_SPI_ST_RX_FIFORDY BIT(1) > +#define S3C64XX_SPI_ST_TX_FIFORDY BIT(0) > + > +#define S3C64XX_SPI_PACKET_CNT_EN BIT(16) > #define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0) > > -#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) > -#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) > -#define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2) > -#define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1) > -#define S3C64XX_SPI_PND_TRAILING_CLR (1<<0) > +#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR BIT(4) > +#define S3C64XX_SPI_PND_TX_OVERRUN_CLR BIT(3) > +#define S3C64XX_SPI_PND_RX_UNDERRUN_CLR BIT(2) > +#define S3C64XX_SPI_PND_RX_OVERRUN_CLR BIT(1) > +#define S3C64XX_SPI_PND_TRAILING_CLR BIT(0) > > -#define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7) > -#define S3C64XX_SPI_SWAP_RX_BYTE (1<<6) > -#define S3C64XX_SPI_SWAP_RX_BIT (1<<5) > -#define S3C64XX_SPI_SWAP_RX_EN (1<<4) > -#define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3) > -#define S3C64XX_SPI_SWAP_TX_BYTE (1<<2) > -#define S3C64XX_SPI_SWAP_TX_BIT (1<<1) > -#define S3C64XX_SPI_SWAP_TX_EN (1<<0) > +#define S3C64XX_SPI_SWAP_RX_HALF_WORD BIT(7) > +#define S3C64XX_SPI_SWAP_RX_BYTE BIT(6) > +#define S3C64XX_SPI_SWAP_RX_BIT BIT(5) > +#define S3C64XX_SPI_SWAP_RX_EN BIT(4) > +#define S3C64XX_SPI_SWAP_TX_HALF_WORD BIT(3) > +#define S3C64XX_SPI_SWAP_TX_BYTE BIT(2) > +#define S3C64XX_SPI_SWAP_TX_BIT BIT(1) > +#define S3C64XX_SPI_SWAP_TX_EN BIT(0) > > -#define S3C64XX_SPI_FBCLK_MSK (3<<0) > +#define S3C64XX_SPI_FBCLK_MASK GENMASK(1, 0) > > #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id]) > #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \ > @@ -112,18 +113,13 @@ > FIFO_LVL_MASK(i)) > #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1) > > -#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff > -#define S3C64XX_SPI_TRAILCNT_OFF 19 > - > -#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT > - > #define S3C64XX_SPI_POLLING_SIZE 32 > > #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) > #define is_polling(x) (x->cntrlr_info->polling) > > -#define RXBUSY (1<<2) > -#define TXBUSY (1<<3) > +#define RXBUSY BIT(2) > +#define TXBUSY BIT(3) > > struct s3c64xx_spi_dma_data { > struct dma_chan *ch; > @@ -342,8 +338,9 @@ static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) > } else { > u32 ssel = readl(sdd->regs + S3C64XX_SPI_CS_REG); > > - ssel |= (S3C64XX_SPI_CS_AUTO | > - S3C64XX_SPI_CS_NSC_CNT_2); > + ssel |= S3C64XX_SPI_CS_AUTO | > + FIELD_PREP(S3C64XX_SPI_CS_NSC_CNT_MASK, > + S3C64XX_SPI_CS_NSC_CNT_2); > writel(ssel, sdd->regs + S3C64XX_SPI_CS_REG); > } > } else { > @@ -666,16 +663,22 @@ static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) > > switch (sdd->cur_bpw) { > case 32: > - val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD; > - val |= S3C64XX_SPI_MODE_CH_TSZ_WORD; > + val |= FIELD_PREP(S3C64XX_SPI_MODE_BUS_TSZ_MASK, > + S3C64XX_SPI_MODE_BUS_TSZ_WORD) | > + FIELD_PREP(S3C64XX_SPI_MODE_CH_TSZ_MASK, > + S3C64XX_SPI_MODE_CH_TSZ_WORD); > break; > case 16: > - val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD; > - val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD; > + val |= FIELD_PREP(S3C64XX_SPI_MODE_BUS_TSZ_MASK, > + S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD) | > + FIELD_PREP(S3C64XX_SPI_MODE_CH_TSZ_MASK, > + S3C64XX_SPI_MODE_CH_TSZ_HALFWORD); > break; > default: > - val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; > - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; > + val |= FIELD_PREP(S3C64XX_SPI_MODE_BUS_TSZ_MASK, > + S3C64XX_SPI_MODE_BUS_TSZ_BYTE) | > + FIELD_PREP(S3C64XX_SPI_MODE_CH_TSZ_MASK, > + S3C64XX_SPI_MODE_CH_TSZ_BYTE); I don't know. Maybe it's me, but using this FIELD_PREP() macro seems to only making the code harder to read. At least in cases like this. I would vote against its usage, to keep the code compact and easy to read. > break; > } > > @@ -801,7 +804,7 @@ static int s3c64xx_spi_transfer_one(struct spi_controller *host, > > val = readl(sdd->regs + S3C64XX_SPI_MODE_CFG); > val &= ~S3C64XX_SPI_MODE_RX_RDY_LVL; > - val |= (rdy_lv << S3C64XX_SPI_MODE_RX_RDY_LVL_SHIFT); > + val |= FIELD_PREP(S3C64XX_SPI_MODE_RX_RDY_LVL, rdy_lv); > writel(val, sdd->regs + S3C64XX_SPI_MODE_CFG); > > /* Enable FIFO_RDY_EN IRQ */ > @@ -1074,8 +1077,8 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd) > writel(0, regs + S3C64XX_SPI_INT_EN); > > if (!sdd->port_conf->clk_from_cmu) > - writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, > - regs + S3C64XX_SPI_CLK_CFG); > + writel(FIELD_PREP(S3C64XX_SPI_CLKSEL_SRCMSK, sci->src_clk_nr), > + regs + S3C64XX_SPI_CLK_CFG); > writel(0, regs + S3C64XX_SPI_MODE_CFG); > writel(0, regs + S3C64XX_SPI_PACKET_CNT); > > @@ -1091,8 +1094,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd) > > val = readl(regs + S3C64XX_SPI_MODE_CFG); > val &= ~S3C64XX_SPI_MODE_4BURST; > - val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); Doesn't it change the behavior? > - val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); > + val |= S3C64XX_SPI_MAX_TRAILCNT_MASK; > writel(val, regs + S3C64XX_SPI_MODE_CFG); > > s3c64xx_flush_fifo(sdd); > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > SPI_STATUSn.{RX, TX}_FIFO_LVL fields show the data level in the RX and > TX FIFOs. The IP supports FIFOs from 8 to 256 bytes, but apart from the > MODE_CFG.{RX, TX}_RDY_LVL fields that configure the {RX, TX} FIFO > trigger level in the interrupt mode, there's nothing in the registers > that configure the FIFOs depth. Is the responsibility of the SoC that > integrates the IP to dictate the FIFO depth and of the SPI driver to > make sure it doesn't bypass the FIFO length. > > {RX, TX}_FIFO_LVL was used to pass the FIFO length information based on > the IP configuration in the SoC. Its value was defined so that it > includes the entire FIFO length. For example, if one wanted to specify a > 64 FIFO length (0x40), it wold configure the FIFO level to 127 (0x7f). s/wodl/would/ > This is not only wrong, because it doesn't respect the IP's register > fields, it's also misleading. Use the full mask for the > SPI_STATUSn.{RX, TX}_FIFO_LVL fields. No change in functionality is > expected. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 21 +++++++++++---------- > 1 file changed, 11 insertions(+), 10 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index d046810da51f..b048e81e6207 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -78,6 +78,8 @@ > #define S3C64XX_SPI_INT_RX_FIFORDY_EN BIT(1) > #define S3C64XX_SPI_INT_TX_FIFORDY_EN BIT(0) > > +#define S3C64XX_SPI_ST_RX_FIFO_LVL GENMASK(23, 15) What about s3c* architectures, where RX_LVL starts with bit #13, as can be seen from .rx_lvl_offset values in corresponding port_configs? Wouldn't this change break those? More generally, I don't understand why this patch is needed. Looks like it just changes the naming of the FIFO level accessing macros, making the code more bloated too. > +#define S3C64XX_SPI_ST_TX_FIFO_LVL GENMASK(14, 6) > #define S3C64XX_SPI_ST_RX_OVERRUN_ERR BIT(5) > #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR BIT(4) > #define S3C64XX_SPI_ST_TX_OVERRUN_ERR BIT(3) > @@ -108,9 +110,6 @@ > #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id]) > #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \ > (1 << (i)->port_conf->tx_st_done)) ? 1 : 0) > -#define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i)) > -#define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \ > - FIFO_LVL_MASK(i)) > #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1) > > #define S3C64XX_SPI_POLLING_SIZE 32 > @@ -219,7 +218,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) > loops = msecs_to_loops(1); > do { > val = readl(regs + S3C64XX_SPI_STATUS); > - } while (TX_FIFO_LVL(val, sdd) && loops--); > + } while (FIELD_GET(S3C64XX_SPI_ST_TX_FIFO_LVL, val) && loops--); > > if (loops == 0) > dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); > @@ -228,7 +227,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) > loops = msecs_to_loops(1); > do { > val = readl(regs + S3C64XX_SPI_STATUS); > - if (RX_FIFO_LVL(val, sdd)) > + if (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, val)) > readl(regs + S3C64XX_SPI_RX_DATA); > else > break; > @@ -499,10 +498,11 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, > > do { > status = readl(regs + S3C64XX_SPI_STATUS); > - } while (RX_FIFO_LVL(status, sdd) < max_fifo && --val); > + } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < max_fifo && > + --val); > > /* return the actual received data length */ > - return RX_FIFO_LVL(status, sdd); > + return FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); > } > > static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, > @@ -533,7 +533,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, > if (val && !xfer->rx_buf) { > val = msecs_to_loops(10); > status = readl(regs + S3C64XX_SPI_STATUS); > - while ((TX_FIFO_LVL(status, sdd) > + while ((FIELD_GET(S3C64XX_SPI_ST_TX_FIFO_LVL, status) > || !S3C64XX_SPI_ST_TX_DONE(status, sdd)) > && --val) { > cpu_relax(); > @@ -568,7 +568,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, > > /* sleep during signal transfer time */ > status = readl(regs + S3C64XX_SPI_STATUS); > - if (RX_FIFO_LVL(status, sdd) < xfer->len) > + if (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < xfer->len) > usleep_range(time_us / 2, time_us); > > if (use_irq) { > @@ -580,7 +580,8 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, > val = msecs_to_loops(ms); > do { > status = readl(regs + S3C64XX_SPI_STATUS); > - } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); > + } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < xfer->len && > + --val); > > if (!val) > return -EIO; > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Move common code outside if else to avoid code duplication. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 6 ++---- > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index b048e81e6207..107b4200ab00 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -286,20 +286,18 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, > if (dma->direction == DMA_DEV_TO_MEM) { > sdd = container_of((void *)dma, > struct s3c64xx_spi_driver_data, rx_dma); > - config.direction = dma->direction; > config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; > config.src_addr_width = sdd->cur_bpw / 8; > config.src_maxburst = 1; > - dmaengine_slave_config(dma->ch, &config); > } else { > sdd = container_of((void *)dma, > struct s3c64xx_spi_driver_data, tx_dma); > - config.direction = dma->direction; > config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; > config.dst_addr_width = sdd->cur_bpw / 8; > config.dst_maxburst = 1; > - dmaengine_slave_config(dma->ch, &config); > } > + config.direction = dma->direction; > + dmaengine_slave_config(dma->ch, &config); > > desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, > dma->direction, DMA_PREP_INTERRUPT); > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Check the return code of dmaengine_slave_config(). > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 107b4200ab00..48b87c5e2dd2 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -297,7 +297,9 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, > config.dst_maxburst = 1; > } > config.direction = dma->direction; > - dmaengine_slave_config(dma->ch, &config); > + ret = dmaengine_slave_config(dma->ch, &config); > + if (ret) > + return ret; > > desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, > dma->direction, DMA_PREP_INTERRUPT); > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Propagate the dma_submit_error() error code, don't overwrite it. But why? What would be the benefit over -EIO? > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 48b87c5e2dd2..25d642f99278 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -316,7 +316,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, > ret = dma_submit_error(dma->cookie); > if (ret) { > dev_err(&sdd->pdev->dev, "DMA submission failed"); > - return -EIO; > + return ret; > } > > dma_async_issue_pending(dma->ch); > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Don't monopolize the name. Prepend the driver prefix to the function > name. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 25d642f99278..447320788697 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -273,8 +273,8 @@ static void s3c64xx_spi_dmacb(void *data) > spin_unlock_irqrestore(&sdd->lock, flags); > } > > -static int prepare_dma(struct s3c64xx_spi_dma_data *dma, > - struct sg_table *sgt) > +static int s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma, > + struct sg_table *sgt) > { > struct s3c64xx_spi_driver_data *sdd; > struct dma_slave_config config; > @@ -440,7 +440,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, > chcfg |= S3C64XX_SPI_CH_TXCH_ON; > if (dma_mode) { > modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; > - ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg); > + ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg); > } else { > switch (sdd->cur_bpw) { > case 32: > @@ -472,7 +472,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, > writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) > | S3C64XX_SPI_PACKET_CNT_EN, > regs + S3C64XX_SPI_PACKET_CNT); > - ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg); > + ret = s3c64xx_prepare_dma(&sdd->rx_dma, &xfer->rx_sg); > } > } > > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > ETIMEDOUT is more specific than EIO, use it for > wait_for_completion_timeout(). > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 447320788697..d2dd28ff00c6 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -523,7 +523,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, > > /* > * If the previous xfer was completed within timeout, then > - * proceed further else return -EIO. > + * proceed further else return -ETIMEDOUT. > * DmaTx returns after simply writing data in the FIFO, > * w/o waiting for real transmission on the bus to finish. > * DmaRx returns only after Dma read data from FIFO which > @@ -544,7 +544,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, > > /* If timed out while checking rx/tx status return error */ > if (!val) > - return -EIO; > + return -ETIMEDOUT; > > return 0; > } > @@ -574,7 +574,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, > if (use_irq) { > val = msecs_to_jiffies(ms); > if (!wait_for_completion_timeout(&sdd->xfer_completion, val)) > - return -EIO; > + return -ETIMEDOUT; > } > > val = msecs_to_loops(ms); > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Drop the blank line and move the logical operation in the body of the > function rather than in initialization list. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 00a0878aeb80..bb6d9bf390a8 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1282,8 +1282,9 @@ static int s3c64xx_spi_suspend(struct device *dev) > { > struct spi_controller *host = dev_get_drvdata(dev); > struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); > + int ret; > > - int ret = spi_controller_suspend(host); > + ret = spi_controller_suspend(host); > if (ret) > return ret; > > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Fix typo, s/configuartion/configuration. > > Fixes: 6b8d1e4739f4 ("spi: spi-s3c64xx: Add missing entries for structs 's3c64xx_spi_dma_data' and 's3c64xx_spi_dma_data'") > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index bb6d9bf390a8..692ccb7828f8 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -174,7 +174,7 @@ struct s3c64xx_spi_port_config { > * @cur_speed: Current clock speed > * @rx_dma: Local receive DMA data (e.g. chan and direction) > * @tx_dma: Local transmit DMA data (e.g. chan and direction) > - * @port_conf: Local SPI port configuartion data > + * @port_conf: Local SPI port configuration data > * @port_id: Port identification number > */ > struct s3c64xx_spi_driver_data { > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > "samsung,spi-src-clk" and "num-cs" are optional dt properties. Downgrade > the message from warning to debug message. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > drivers/spi/spi-s3c64xx.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 692ccb7828f8..fc5fffc019e0 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1071,14 +1071,14 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev) > return ERR_PTR(-ENOMEM); > > if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) { > - dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); > + dev_dbg(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); > sci->src_clk_nr = 0; > } else { > sci->src_clk_nr = temp; > } > > if (of_property_read_u32(dev->of_node, "num-cs", &temp)) { > - dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n"); > + dev_dbg(dev, "number of chip select lines not specified, assuming 1 chip select line\n"); > sci->num_cs = 1; > } else { > sci->num_cs = temp; > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > s3c64xx_spi_transfer_one() makes sure that for PIO the xfer->len is > always smaller than the fifo size. Since we can't receive more that the > FIFO size, droop the loop handling, the code becomes less misleading. Drop (spelling)? For the patch: how exactly it was tested to make sure there is no regression? > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 75 +++++++++------------------------------ > 1 file changed, 17 insertions(+), 58 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index d2dd28ff00c6..00a0878aeb80 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -485,26 +485,6 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, > return 0; > } > > -static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, > - int timeout_ms) > -{ > - void __iomem *regs = sdd->regs; > - unsigned long val = 1; > - u32 status; > - u32 max_fifo = FIFO_DEPTH(sdd); > - > - if (timeout_ms) > - val = msecs_to_loops(timeout_ms); > - > - do { > - status = readl(regs + S3C64XX_SPI_STATUS); > - } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < max_fifo && > - --val); > - > - /* return the actual received data length */ > - return FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); > -} > - > static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, > struct spi_transfer *xfer) > { > @@ -553,13 +533,11 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, > struct spi_transfer *xfer, bool use_irq) > { > void __iomem *regs = sdd->regs; > + u8 *buf = xfer->rx_buf; > + unsigned long time_us; > unsigned long val; > - u32 status; > - int loops; > - u32 cpy_len; > - u8 *buf; > + u32 status, len; > int ms; > - unsigned long time_us; > > /* microsecs to xfer 'len' bytes @ 'cur_speed' */ > time_us = (xfer->len * 8 * 1000 * 1000) / sdd->cur_speed; > @@ -582,48 +560,29 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, > status = readl(regs + S3C64XX_SPI_STATUS); > } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < xfer->len && > --val); > - > if (!val) > return -EIO; > > /* If it was only Tx */ > - if (!xfer->rx_buf) { > + if (!buf) { > sdd->state &= ~TXBUSY; > return 0; > } > > - /* > - * If the receive length is bigger than the controller fifo > - * size, calculate the loops and read the fifo as many times. > - * loops = length / max fifo size (calculated by using the > - * fifo mask). > - * For any size less than the fifo size the below code is > - * executed atleast once. > - */ > - loops = xfer->len / FIFO_DEPTH(sdd); > - buf = xfer->rx_buf; > - do { > - /* wait for data to be received in the fifo */ > - cpy_len = s3c64xx_spi_wait_for_timeout(sdd, > - (loops ? ms : 0)); > - > - switch (sdd->cur_bpw) { > - case 32: > - ioread32_rep(regs + S3C64XX_SPI_RX_DATA, > - buf, cpy_len / 4); > - break; > - case 16: > - ioread16_rep(regs + S3C64XX_SPI_RX_DATA, > - buf, cpy_len / 2); > - break; > - default: > - ioread8_rep(regs + S3C64XX_SPI_RX_DATA, > - buf, cpy_len); > - break; > - } > + len = FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); > + > + switch (sdd->cur_bpw) { > + case 32: > + ioread32_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 4); > + break; > + case 16: > + ioread16_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 2); > + break; > + default: > + ioread8_rep(regs + S3C64XX_SPI_RX_DATA, buf, len); > + break; > + } > > - buf = buf + cpy_len; > - } while (loops--); > sdd->state &= ~RXBUSY; > > return 0; > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Add support for GS101 SPI. All the SPI nodes on GS101 have 64 bytes > FIFOs, infer the FIFO size from the compatible. GS101 allows just 32bit > register accesses, otherwise a Serror Interrupt is raised. Do the write > reg accesses in 32 bits. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 35a2d5554dfd..e887be6955a0 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1501,6 +1501,18 @@ static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = { > .quirks = S3C64XX_SPI_QUIRK_CS_AUTO, > }; > > +static const struct s3c64xx_spi_port_config gs101_spi_port_config = { > + .fifosize = 64, > + .rx_lvl_offset = 15, > + .tx_st_done = 25, > + .clk_div = 4, > + .high_speed = true, > + .clk_from_cmu = true, > + .has_loopback = true, > + .use_32bit_io = true, > + .quirks = S3C64XX_SPI_QUIRK_CS_AUTO, > +}; > + > static const struct s3c64xx_spi_port_config fsd_spi_port_config = { > .fifosize = 64, > .rx_lvl_offset = 15, > @@ -1556,6 +1568,10 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = { > .compatible = "samsung,exynosautov9-spi", > .data = &exynosautov9_spi_port_config, > }, > + { As I mentioned before, this braces style looks too bloated to me. Other than that: Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > + .compatible = "google,gs101-spi", > + .data = &gs101_spi_port_config, > + }, > { > .compatible = "tesla,fsd-spi", > .data = &fsd_spi_port_config, > -- > 2.43.0.429.g432eaa2c6b-goog >
On Thu, Jan 25, 2024, at 15:50, Tudor Ambarus wrote: > This will allow devices 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. A > typical use case is SPI, where the clients can request transfers in words > of 8 bits. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> My feeling is that this operation is rare enough that I'd prefer it to be open-coded in the driver than made generic here. Making it work for all corner cases is possible but probably not worth it. > +#ifndef writesb_l > +#define writesb_l writesb_l > +static inline void writesb_l(volatile void __iomem *addr, const void > *buffer, > + unsigned int count) > +{ > + if (count) { > + const u8 *buf = buffer; > + > + do { > + __raw_writel(*buf++, addr); > + } while (--count); > + } > +} > +#endif There are architectures where writesb() requires an extra barrier before and/or after the loop. I think there are others that get the endianess wrong in the generic version you have here. > +#ifndef iowrite8_32_rep > +#define iowrite8_32_rep iowrite8_32_rep > +static inline void iowrite8_32_rep(volatile void __iomem *addr, > + const void *buffer, > + unsigned int count) > +{ > + writesb_l(addr, buffer, count); > +} > +#endif This one is wrong for architectures that have a custom inl() helper and need to multiplex between inl() and writel() in iowrite32(), notably x86. For completeness you would need to add the out-of-line version in lib/iomap.c for those, plus the corresponding insb_32() and possibly the respective big-endian versions of those. If you keep the helper in a driver that is only used on regular architectures like arm64, it will work reliably. Arnd
On Thu, Jan 25, 2024 at 02:03:15PM -0600, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > +#define S3C64XX_SPI_ST_RX_FIFO_LVL GENMASK(23, 15) > What about s3c* architectures, where RX_LVL starts with bit #13, as > can be seen from .rx_lvl_offset values in corresponding port_configs? > Wouldn't this change break those? I should point out that I have a s3c6410 board I care about.
On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Infer the FIFO size from the compatible, where all the instances of the > SPI IP have the same FIFO size. This way we no longer depend on the SPI > alias from the device tree to select the FIFO size, thus we remove the > dependency of the driver on the SPI alias. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > --- > drivers/spi/spi-s3c64xx.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > index 5a93ed4125b0..b86eb0a77b60 100644 > --- a/drivers/spi/spi-s3c64xx.c > +++ b/drivers/spi/spi-s3c64xx.c > @@ -1381,7 +1381,7 @@ static const struct dev_pm_ops s3c64xx_spi_pm = { > }; > > static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = { > - .fifo_lvl_mask = { 0x7f }, How will it work with already existing out-of-tree dts's, if only kernel image gets updated? I wonder if it's considered ok to break that compatibility like this. > + .fifosize = 64, > .rx_lvl_offset = 13, > .tx_st_done = 21, > .clk_div = 2, > @@ -1389,7 +1389,7 @@ static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = { > }; > > static const struct s3c64xx_spi_port_config s3c6410_spi_port_config = { > - .fifo_lvl_mask = { 0x7f, 0x7F }, > + .fifosize = 64, > .rx_lvl_offset = 13, > .tx_st_done = 21, > .clk_div = 2, > @@ -1435,7 +1435,7 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = { > }; > > static const struct s3c64xx_spi_port_config exynos850_spi_port_config = { > - .fifo_lvl_mask = { 0x7f, 0x7f, 0x7f }, > + .fifosize = 64, > .rx_lvl_offset = 15, > .tx_st_done = 25, > .clk_div = 4, > @@ -1459,7 +1459,7 @@ static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = { > }; > > static const struct s3c64xx_spi_port_config fsd_spi_port_config = { > - .fifo_lvl_mask = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, > + .fifosize = 64, > .rx_lvl_offset = 15, > .tx_st_done = 25, > .clk_div = 2, > -- > 2.43.0.429.g432eaa2c6b-goog >
On 1/25/24 21:23, Arnd Bergmann wrote: > My feeling is that this operation is rare enough that I'd prefer > it to be open-coded in the driver than made generic here. Making > it work for all corner cases is possible but probably not worth > it. Thanks for all the explanations, Arnd. I'll open-code the op in the SPI driver for now. Cheers, ta
On 1/25/24 22:28, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> Infer the FIFO size from the compatible, where all the instances of the >> SPI IP have the same FIFO size. This way we no longer depend on the SPI >> alias from the device tree to select the FIFO size, thus we remove the >> dependency of the driver on the SPI alias. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 8 ++++---- >> 1 file changed, 4 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 5a93ed4125b0..b86eb0a77b60 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -1381,7 +1381,7 @@ static const struct dev_pm_ops s3c64xx_spi_pm = { >> }; >> >> static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = { >> - .fifo_lvl_mask = { 0x7f }, > How will it work with already existing out-of-tree dts's, if only > kernel image gets updated? I wonder if it's considered ok to break > that compatibility like this. > ah, good catch, Sam! I prepared everything to not break older device trees and then I removed this :). >> + .fifosize = 64, Adding .fifosize and keeping fifo_lvl_mask will not break backward compatibility. In s3c64xx_spi_get_fifosize() I first check if .fifosize is set and use that, and if not set, use the .fifo_lvl_mask.
On 1/25/24 20:23, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> Propagate the dma_submit_error() error code, don't overwrite it. > > But why? What would be the benefit over -EIO I'd like to see why dma submit fail rather than "oh, it's an EIO". DMA submit should just add the dma descriptor to a queue, without firing it, thus EIO looks very wrong here, and it's misleading. > >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 48b87c5e2dd2..25d642f99278 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -316,7 +316,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma, >> ret = dma_submit_error(dma->cookie); >> if (ret) { >> dev_err(&sdd->pdev->dev, "DMA submission failed"); >> - return -EIO; >> + return ret; >> } >> >> dma_async_issue_pending(dma->ch); >> -- >> 2.43.0.429.g432eaa2c6b-goog >>
On 1/25/24 20:43, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> s3c64xx_spi_transfer_one() makes sure that for PIO the xfer->len is >> always smaller than the fifo size. Since we can't receive more that the >> FIFO size, droop the loop handling, the code becomes less misleading. > > Drop (spelling)? oh yeah, thanks. > > For the patch: how exactly it was tested to make sure there is no regression? no regression testing for the entire patch set, I have just a gs101 on my hands. However, we shouldn't refrain ourselves on improving things when we think they're straight forward and they worth it. In this particular case, for PIO, s3c64xx_spi_transfer_one() does: xfer->len = fifo_len - 1; then in s3c64xx_enable_datapath() we write xfer->len and then in s3c64xx_wait_for_pio() we code did the following: loops = xfer->len / FIFO_DEPTH(sdd); loops is always zero, this is bogus and we shall remove it. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 75 +++++++++------------------------------ >> 1 file changed, 17 insertions(+), 58 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index d2dd28ff00c6..00a0878aeb80 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -485,26 +485,6 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, >> return 0; >> } >> >> -static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, >> - int timeout_ms) >> -{ >> - void __iomem *regs = sdd->regs; >> - unsigned long val = 1; >> - u32 status; >> - u32 max_fifo = FIFO_DEPTH(sdd); >> - >> - if (timeout_ms) >> - val = msecs_to_loops(timeout_ms); >> - >> - do { >> - status = readl(regs + S3C64XX_SPI_STATUS); >> - } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < max_fifo && >> - --val); >> - >> - /* return the actual received data length */ >> - return FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); >> -} >> - >> static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, >> struct spi_transfer *xfer) >> { >> @@ -553,13 +533,11 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, >> struct spi_transfer *xfer, bool use_irq) >> { >> void __iomem *regs = sdd->regs; >> + u8 *buf = xfer->rx_buf; >> + unsigned long time_us; >> unsigned long val; >> - u32 status; >> - int loops; >> - u32 cpy_len; >> - u8 *buf; >> + u32 status, len; >> int ms; >> - unsigned long time_us; >> >> /* microsecs to xfer 'len' bytes @ 'cur_speed' */ >> time_us = (xfer->len * 8 * 1000 * 1000) / sdd->cur_speed; >> @@ -582,48 +560,29 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, >> status = readl(regs + S3C64XX_SPI_STATUS); >> } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < xfer->len && >> --val); >> - >> if (!val) >> return -EIO; >> >> /* If it was only Tx */ >> - if (!xfer->rx_buf) { >> + if (!buf) { >> sdd->state &= ~TXBUSY; >> return 0; >> } >> >> - /* >> - * If the receive length is bigger than the controller fifo >> - * size, calculate the loops and read the fifo as many times. >> - * loops = length / max fifo size (calculated by using the >> - * fifo mask). >> - * For any size less than the fifo size the below code is >> - * executed atleast once. >> - */ >> - loops = xfer->len / FIFO_DEPTH(sdd); >> - buf = xfer->rx_buf; >> - do { >> - /* wait for data to be received in the fifo */ >> - cpy_len = s3c64xx_spi_wait_for_timeout(sdd, >> - (loops ? ms : 0)); >> - >> - switch (sdd->cur_bpw) { >> - case 32: >> - ioread32_rep(regs + S3C64XX_SPI_RX_DATA, >> - buf, cpy_len / 4); >> - break; >> - case 16: >> - ioread16_rep(regs + S3C64XX_SPI_RX_DATA, >> - buf, cpy_len / 2); >> - break; >> - default: >> - ioread8_rep(regs + S3C64XX_SPI_RX_DATA, >> - buf, cpy_len); >> - break; >> - } >> + len = FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); >> + >> + switch (sdd->cur_bpw) { >> + case 32: >> + ioread32_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 4); >> + break; >> + case 16: >> + ioread16_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 2); >> + break; >> + default: >> + ioread8_rep(regs + S3C64XX_SPI_RX_DATA, buf, len); >> + break; >> + } >> >> - buf = buf + cpy_len; >> - } while (loops--); >> sdd->state &= ~RXBUSY; >> >> return 0; >> -- >> 2.43.0.429.g432eaa2c6b-goog >>
On 1/25/24 20:03, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> SPI_STATUSn.{RX, TX}_FIFO_LVL fields show the data level in the RX and >> TX FIFOs. The IP supports FIFOs from 8 to 256 bytes, but apart from the >> MODE_CFG.{RX, TX}_RDY_LVL fields that configure the {RX, TX} FIFO >> trigger level in the interrupt mode, there's nothing in the registers >> that configure the FIFOs depth. Is the responsibility of the SoC that >> integrates the IP to dictate the FIFO depth and of the SPI driver to >> make sure it doesn't bypass the FIFO length. >> >> {RX, TX}_FIFO_LVL was used to pass the FIFO length information based on >> the IP configuration in the SoC. Its value was defined so that it >> includes the entire FIFO length. For example, if one wanted to specify a >> 64 FIFO length (0x40), it wold configure the FIFO level to 127 (0x7f). > > s/wodl/would/ oh, yes, thanks > >> This is not only wrong, because it doesn't respect the IP's register >> fields, it's also misleading. Use the full mask for the >> SPI_STATUSn.{RX, TX}_FIFO_LVL fields. No change in functionality is >> expected. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 21 +++++++++++---------- >> 1 file changed, 11 insertions(+), 10 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index d046810da51f..b048e81e6207 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -78,6 +78,8 @@ >> #define S3C64XX_SPI_INT_RX_FIFORDY_EN BIT(1) >> #define S3C64XX_SPI_INT_TX_FIFORDY_EN BIT(0) >> >> +#define S3C64XX_SPI_ST_RX_FIFO_LVL GENMASK(23, 15) > > What about s3c* architectures, where RX_LVL starts with bit #13, as > can be seen from .rx_lvl_offset values in corresponding port_configs? > Wouldn't this change break those? ah, wonderful catch, Sam. I break those indeed. > > More generally, I don't understand why this patch is needed. Looks I said in the commit message and subject that I'd like to use the full FIFO level mask rather than just a partial mask. On gs101 at least, that register field is on 9 bits, but as the code is now, we consider that register on 7 bits. For gs101 the FIFO size is always 64 bytes, thus indirectly the fifo_lvl_mask is always 0x7f. Unfortunately I'll drop this patch because I don't have access to all the SoC datasheets, thus I can't tell for sure if that register is always 9 bits wide. s3c2443 and s3c6410, which have the rx-lvl-offset set to 13, use just 0x7f masks. That's a pitty.
Thanks for the review feedback, Sam, great catches so far! On 1/25/24 19:04, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> of_device_id::data is an opaque pointer. No explicit cast is needed. >> Remove unneeded (void *) casts in of_match_table. While here align the >> compatible and data members. >> >> Reviewed-by: Andi Shyti <andi.shyti@kernel.org> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 45 +++++++++++++++++++++++---------------- >> 1 file changed, 27 insertions(+), 18 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 230fda2b3417..137faf9f2697 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -1511,32 +1511,41 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = { >> }; >> >> static const struct of_device_id s3c64xx_spi_dt_match[] = { >> - { .compatible = "samsung,s3c2443-spi", >> - .data = (void *)&s3c2443_spi_port_config, > > I support removing (void *) cast. But this new braces style: > > }, > { this style was there before my patch. > > seems to bloat the code a bit. For my taste, having something like }, > { on the same line would be more compact, and more canonical so to I don't lean towards neither of the styles, I'm ok with both > speak. Or even preserving the existing style would be ok too, for that > matter. > seeing .compatible and .data unaligned hurt my eyes and I think that aligning them while dropping the cast is fine. I don't really want to do the style change unless you, Andi or Mark insist. Would you please come with a patch on top if you really want them changed? > Assuming the braces style is fixed, you can add: > > Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > >> + { >> + .compatible = "samsung,s3c2443-spi", >> + .data = &s3c2443_spi_port_config, >> }, >> - { .compatible = "samsung,s3c6410-spi", >> - .data = (void *)&s3c6410_spi_port_config, >> + { >> + .compatible = "samsung,s3c6410-spi", >> + .data = &s3c6410_spi_port_config, >> }, >> - { .compatible = "samsung,s5pv210-spi", >> - .data = (void *)&s5pv210_spi_port_config, >> + { >> + .compatible = "samsung,s5pv210-spi", >> + .data = &s5pv210_spi_port_config, >> }, >> - { .compatible = "samsung,exynos4210-spi", >> - .data = (void *)&exynos4_spi_port_config, >> + { >> + .compatible = "samsung,exynos4210-spi", >> + .data = &exynos4_spi_port_config, >> }, >> - { .compatible = "samsung,exynos7-spi", >> - .data = (void *)&exynos7_spi_port_config, >> + { >> + .compatible = "samsung,exynos7-spi", >> + .data = &exynos7_spi_port_config, >> }, >> - { .compatible = "samsung,exynos5433-spi", >> - .data = (void *)&exynos5433_spi_port_config, >> + { >> + .compatible = "samsung,exynos5433-spi", >> + .data = &exynos5433_spi_port_config, >> }, >> - { .compatible = "samsung,exynos850-spi", >> - .data = (void *)&exynos850_spi_port_config, >> + { >> + .compatible = "samsung,exynos850-spi", >> + .data = &exynos850_spi_port_config, >> }, >> - { .compatible = "samsung,exynosautov9-spi", >> - .data = (void *)&exynosautov9_spi_port_config, >> + { >> + .compatible = "samsung,exynosautov9-spi", >> + .data = &exynosautov9_spi_port_config, >> }, >> - { .compatible = "tesla,fsd-spi", >> - .data = (void *)&fsd_spi_port_config, >> + { >> + .compatible = "tesla,fsd-spi", >> + .data = &fsd_spi_port_config, >> }, >> { }, >> }; >> -- >> 2.43.0.429.g432eaa2c6b-goog >>
On 1/25/24 19:50, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> Use the bitfield access macros in order to clean and to make the driver >> easier to read. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 196 +++++++++++++++++++------------------- >> 1 file changed, 99 insertions(+), 97 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 1e44b24f6401..d046810da51f 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -4,6 +4,7 @@ cut >> +#define S3C64XX_SPI_PSR_MASK GENMASK(15, 0) > > But it was 0xff (7:0) originally, and here you extend it up to 15:0. this is a bug from my side, I'll fix it, thanks! cut >> default: >> - val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; >> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; >> + val |= FIELD_PREP(S3C64XX_SPI_MODE_BUS_TSZ_MASK, >> + S3C64XX_SPI_MODE_BUS_TSZ_BYTE) | >> + FIELD_PREP(S3C64XX_SPI_MODE_CH_TSZ_MASK, >> + S3C64XX_SPI_MODE_CH_TSZ_BYTE); > > I don't know. Maybe it's me, but using this FIELD_PREP() macro seems > to only making the code harder to read. At least in cases like this. I > would vote against its usage, to keep the code compact and easy to > read. I saw Andi complained about this too, maybe Mark can chime in. To me this is not a matter of taste, it's how it should be done. In this particular case you have more lines when using FIELD_PREP because the mask starts from bit 0. If the mask ever changes for new IPs then you'd have to hack the code, whereas if using FIELD_PREP you just have to update the mask field, something like: FIELD_PREP(drv_prv_data->whatever_reg.field_mask, S3C64XX_SPI_MODE_CH_TSZ_BYTE); Thus it makes the code generic and more friendly for new IP additions. And I have to admit I like it better too. I know from the start that we're dealing with register fields and not some internal driver mask.
On 1/25/24 21:48, Mark Brown wrote: > On Thu, Jan 25, 2024 at 02:03:15PM -0600, Sam Protsenko wrote: >> On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > >>> +#define S3C64XX_SPI_ST_RX_FIFO_LVL GENMASK(23, 15) > >> What about s3c* architectures, where RX_LVL starts with bit #13, as >> can be seen from .rx_lvl_offset values in corresponding port_configs? >> Wouldn't this change break those? > > I should point out that I have a s3c6410 board I care about. Obviously, I don't want to break things, but it may happen as Sam pointed out. I'll be around to fix whatever I break. It's good that you have a s3c6410 board, maybe you can run a test on it after I send v3? Thanks!
On 1/25/24 18:58, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> The driver uses readl() but does not include <linux/io.h>. >> >> It is good practice to directly include all headers used, it avoids >> implicit dependencies and spurious breakage if someone rearranges >> headers and causes the implicit include to vanish. >> >> Include the missing header. >> >> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver") > > Not sure the "Fixes" tag is needed here. AFAIU, this patch doesn't fix fixes tag indicates which commit failed to include the necessary header > any actual bugs, seems more like a style fix to me. In other words, not yet, but we can't estimate what header get rearranged and whether it will cause the implicit include to vanish. > I'm not convinced it has to be necessarily backported to stable > kernels. The same goes for another similar patch from this series. It would be good to have this in the stable kernels for the reasons described in the commit message. > >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 7f7eb8f742e4..c1cbc4780a3b 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -10,6 +10,7 @@ >> #include <linux/clk.h> >> #include <linux/dma-mapping.h> >> #include <linux/dmaengine.h> >> +#include <linux/io.h> >> #include <linux/platform_device.h> >> #include <linux/pm_runtime.h> >> #include <linux/spi/spi.h> >> -- >> 2.43.0.429.g432eaa2c6b-goog >>
Hi, Sam, I just noticed that I haven't responded to a question you had. On 1/25/24 19:50, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: >> >> Use the bitfield access macros in order to clean and to make the driver >> easier to read. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> >> --- >> drivers/spi/spi-s3c64xx.c | 196 +++++++++++++++++++------------------- >> 1 file changed, 99 insertions(+), 97 deletions(-) >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> index 1e44b24f6401..d046810da51f 100644 >> --- a/drivers/spi/spi-s3c64xx.c >> +++ b/drivers/spi/spi-s3c64xx.c >> @@ -4,6 +4,7 @@ cut >> +#define S3C64XX_SPI_MAX_TRAILCNT_MASK GENMASK(28, 19) cut >> +#define S3C64XX_SPI_CS_NSC_CNT_MASK GENMASK(9, 4) I was wrong introducing this mask because I can't tell if it applies to all the versions of the IP. Thus I'll keep S3C64XX_SPI_CS_NSC_CNT_2 defined as (2 << 4) and add the following comment on top of it: /* * S3C64XX_SPI_CS_NSC_CNT_2 is a value into the NCS_TIME_COUNT field. In newer * datasheets this field is defined as GENMASK(9, 4). We don't know if this mask * applies to all the versions of the IP, thus we can't yet define * S3C64XX_SPI_CS_NSC_CNT_2 as a value and the register field as a mask. */ #define S3C64XX_SPI_CS_NSC_CNT_2 (2 << 4) cut >> -#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff >> -#define S3C64XX_SPI_TRAILCNT_OFF 19 >> - >> -#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT >> - cut >> @@ -1091,8 +1094,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd) >> >> val = readl(regs + S3C64XX_SPI_MODE_CFG); >> val &= ~S3C64XX_SPI_MODE_4BURST; >> - val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); > > Doesn't it change the behavior? No, I don't think it does. so above we wipe the mask, it's equivalent to: val &= ~(GENMASK(28, 19)) > >> - val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); and above we set the entire mask: val |= GENMASK(28, 19) the wipe is not necessary. This can be done in a separate patch of course, but I considered that if I removed the shift, the value and replaced them with the mask, I get the liberty of using the mask directly. I'll split this op in a separate patch (it starts to feel tiring). I verified the entire patch again, apart of the problem with the wrong mask for S3C64XX_SPI_PSR_MASK and the problem that I specified with S3C64XX_SPI_CS_NSC_CNT_MASK everything shall be fine. All the bits handling shall be equivalent.
On Thu, Jan 25, 2024 at 11:33 AM Mark Brown <broonie@kernel.org> wrote: > > On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote: > > > Allow SoCs that have multiple instances of the SPI IP with different > > FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize" > > device tree property. With this we can break the dependency between the > > SPI alias, the fifo_lvl_mask and the FIFO size. > > OK, so we do actually have SoCs with multiple instances of the IP with > different FIFO depths (and who knows what else other differences)? I think that's why we can see .fifo_lvl_mask[] with different values for different IP instances. For example, ExynosAutoV9 has this (in upstream driver, yes): .fifo_lvl_mask = { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, And I'm pretty sure the comment (in struct s3c64xx_spi_port_config) for .fifo_lvl_mask field is not correct anymore: * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register. Maybe it used to indicate the bit number in SPI_STATUS register for {TX|RX}_FIFO_LVL fields, but not anymore. Nowadays it looks like .fifo_lvl_mask just specifies FIFO depth for each IP instance.
On Fri, Jan 26, 2024 at 1:56 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > On 1/25/24 20:43, Sam Protsenko wrote: > > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > >> > >> s3c64xx_spi_transfer_one() makes sure that for PIO the xfer->len is > >> always smaller than the fifo size. Since we can't receive more that the > >> FIFO size, droop the loop handling, the code becomes less misleading. > > > > Drop (spelling)? > > oh yeah, thanks. > > > > > For the patch: how exactly it was tested to make sure there is no regression? > > no regression testing for the entire patch set, I have just a gs101 on > my hands. > > However, we shouldn't refrain ourselves on improving things when we > think they're straight forward and they worth it. In this particular This patch clearly brings a functional change. The way I see things, the risk of having a regression outweighs the benefits of this refactoring. I don't think it's even methodologically right to apply such changes without thoroughly testing it first. It might be ok for super-easy one-line cleanups, but that's not one of those. > case, for PIO, s3c64xx_spi_transfer_one() does: > xfer->len = fifo_len - 1; > then in s3c64xx_enable_datapath() we write xfer->len and then in > s3c64xx_wait_for_pio() we code did the following: > loops = xfer->len / FIFO_DEPTH(sdd); > loops is always zero, this is bogus and we shall remove it. > [snip]
On Fri, Jan 26, 2024 at 2:24 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > Thanks for the review feedback, Sam, great catches so far! > > On 1/25/24 19:04, Sam Protsenko wrote: > > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > >> > >> of_device_id::data is an opaque pointer. No explicit cast is needed. > >> Remove unneeded (void *) casts in of_match_table. While here align the > >> compatible and data members. > >> > >> Reviewed-by: Andi Shyti <andi.shyti@kernel.org> > >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > >> --- > >> drivers/spi/spi-s3c64xx.c | 45 +++++++++++++++++++++++---------------- > >> 1 file changed, 27 insertions(+), 18 deletions(-) > >> > >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > >> index 230fda2b3417..137faf9f2697 100644 > >> --- a/drivers/spi/spi-s3c64xx.c > >> +++ b/drivers/spi/spi-s3c64xx.c > >> @@ -1511,32 +1511,41 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = { > >> }; > >> > >> static const struct of_device_id s3c64xx_spi_dt_match[] = { > >> - { .compatible = "samsung,s3c2443-spi", > >> - .data = (void *)&s3c2443_spi_port_config, > > > > I support removing (void *) cast. But this new braces style: > > > > }, > > { > > this style was there before my patch. > > > > seems to bloat the code a bit. For my taste, having something like }, > > { on the same line would be more compact, and more canonical so to > > I don't lean towards neither of the styles, I'm ok with both > > > speak. Or even preserving the existing style would be ok too, for that > > matter. > > > > seeing .compatible and .data unaligned hurt my eyes and I think that > aligning them while dropping the cast is fine. I don't really want to do > the style change unless you, Andi or Mark insist. Would you please come > with a patch on top if you really want them changed? > But that would completely undermine the whole point of the review? I'd prefer this style: ... = { { .compatible = .data = }, { .compatible = .data = }, { /* sentinel */ }, }; That seems more canonical to me, and more compact too, with no contradictions to your preference about alignment too. But that's only my opinion, as a reviewer. > > Assuming the braces style is fixed, you can add: > > > > Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> > > > >> + { > >> + .compatible = "samsung,s3c2443-spi", > >> + .data = &s3c2443_spi_port_config, > >> }, > >> - { .compatible = "samsung,s3c6410-spi", > >> - .data = (void *)&s3c6410_spi_port_config, > >> + { > >> + .compatible = "samsung,s3c6410-spi", > >> + .data = &s3c6410_spi_port_config, > >> }, > >> - { .compatible = "samsung,s5pv210-spi", > >> - .data = (void *)&s5pv210_spi_port_config, > >> + { > >> + .compatible = "samsung,s5pv210-spi", > >> + .data = &s5pv210_spi_port_config, > >> }, > >> - { .compatible = "samsung,exynos4210-spi", > >> - .data = (void *)&exynos4_spi_port_config, > >> + { > >> + .compatible = "samsung,exynos4210-spi", > >> + .data = &exynos4_spi_port_config, > >> }, > >> - { .compatible = "samsung,exynos7-spi", > >> - .data = (void *)&exynos7_spi_port_config, > >> + { > >> + .compatible = "samsung,exynos7-spi", > >> + .data = &exynos7_spi_port_config, > >> }, > >> - { .compatible = "samsung,exynos5433-spi", > >> - .data = (void *)&exynos5433_spi_port_config, > >> + { > >> + .compatible = "samsung,exynos5433-spi", > >> + .data = &exynos5433_spi_port_config, > >> }, > >> - { .compatible = "samsung,exynos850-spi", > >> - .data = (void *)&exynos850_spi_port_config, > >> + { > >> + .compatible = "samsung,exynos850-spi", > >> + .data = &exynos850_spi_port_config, > >> }, > >> - { .compatible = "samsung,exynosautov9-spi", > >> - .data = (void *)&exynosautov9_spi_port_config, > >> + { > >> + .compatible = "samsung,exynosautov9-spi", > >> + .data = &exynosautov9_spi_port_config, > >> }, > >> - { .compatible = "tesla,fsd-spi", > >> - .data = (void *)&fsd_spi_port_config, > >> + { > >> + .compatible = "tesla,fsd-spi", > >> + .data = &fsd_spi_port_config, > >> }, > >> { }, > >> }; > >> -- > >> 2.43.0.429.g432eaa2c6b-goog > >>
On Fri, Jan 26, 2024 at 2:49 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > > > > On 1/25/24 19:50, Sam Protsenko wrote: > > On Thu, Jan 25, 2024 at 8:50 AM Tudor Ambarus <tudor.ambarus@linaro.org> wrote: > >> > >> Use the bitfield access macros in order to clean and to make the driver > >> easier to read. > >> > >> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > >> --- > >> drivers/spi/spi-s3c64xx.c | 196 +++++++++++++++++++------------------- > >> 1 file changed, 99 insertions(+), 97 deletions(-) > >> > >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > >> index 1e44b24f6401..d046810da51f 100644 > >> --- a/drivers/spi/spi-s3c64xx.c > >> +++ b/drivers/spi/spi-s3c64xx.c > >> @@ -4,6 +4,7 @@ > > cut > > >> +#define S3C64XX_SPI_PSR_MASK GENMASK(15, 0) > > > > But it was 0xff (7:0) originally, and here you extend it up to 15:0. > > this is a bug from my side, I'll fix it, thanks! > > cut > > >> default: > >> - val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; > >> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; > >> + val |= FIELD_PREP(S3C64XX_SPI_MODE_BUS_TSZ_MASK, > >> + S3C64XX_SPI_MODE_BUS_TSZ_BYTE) | > >> + FIELD_PREP(S3C64XX_SPI_MODE_CH_TSZ_MASK, > >> + S3C64XX_SPI_MODE_CH_TSZ_BYTE); > > > > I don't know. Maybe it's me, but using this FIELD_PREP() macro seems > > to only making the code harder to read. At least in cases like this. I > > would vote against its usage, to keep the code compact and easy to > > read. > > I saw Andi complained about this too, maybe Mark can chime in. > > To me this is not a matter of taste, it's how it should be done. In this Sure. But if you think it has to be done, I suggest it's done taking next things into the account: 1. It shouldn't make code harder to read 2. Preferably stick to canonical ways of doing things 3. IMHO patches like this *must* be tested thoroughly on different boards with different test-cases, to make sure there are no regressions. Because the benefits of cleanups are not that great, as I see it, but we are risking to break some hardware/software combination unintentionally while doing those cleanups. It's a good idea to describe how it was tested in commit message or PATCH #0. Just my $.02. For (1) and (2): I noticed a lot of drivers are carrying additional helper functions for read/write operations, to keep things tidy and functional at the same time. Another mechanism that comes into mind is regmap, though I'm not sure if it's needed for such low-level entities as bus drivers. Also I think Andi has a point about FIELD_PREP and how that can be handled. > particular case you have more lines when using FIELD_PREP because the > mask starts from bit 0. If the mask ever changes for new IPs then you'd > have to hack the code, whereas if using FIELD_PREP you just have to > update the mask field, something like: > > FIELD_PREP(drv_prv_data->whatever_reg.field_mask, > S3C64XX_SPI_MODE_CH_TSZ_BYTE); > > Thus it makes the code generic and more friendly for new IP additions. > And I have to admit I like it better too. I know from the start that > we're dealing with register fields and not some internal driver mask.
On Fri, Jan 26, 2024, at 20:23, Sam Protsenko wrote: > On Thu, Jan 25, 2024 at 11:33 AM Mark Brown <broonie@kernel.org> wrote: >> >> On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote: >> >> > Allow SoCs that have multiple instances of the SPI IP with different >> > FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize" >> > device tree property. With this we can break the dependency between the >> > SPI alias, the fifo_lvl_mask and the FIFO size. >> >> OK, so we do actually have SoCs with multiple instances of the IP with >> different FIFO depths (and who knows what else other differences)? > > I think that's why we can see .fifo_lvl_mask[] with different values > for different IP instances. For example, ExynosAutoV9 has this (in > upstream driver, yes): > > .fifo_lvl_mask = { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, > 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, > That sounds like the same bug as in the serial port driver, by assuming that the alias values in the devicetree have a particular meaning in identifying instances. This immediately breaks when there is a dtb file that does not use the same alias values, e.g. because it only needs some of the SPI ports. Arnd
On Fri, Jan 26, 2024 at 2:17 PM Arnd Bergmann <arnd@arndb.de> wrote: > > On Fri, Jan 26, 2024, at 20:23, Sam Protsenko wrote: > > On Thu, Jan 25, 2024 at 11:33 AM Mark Brown <broonie@kernel.org> wrote: > >> > >> On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote: > >> > >> > Allow SoCs that have multiple instances of the SPI IP with different > >> > FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize" > >> > device tree property. With this we can break the dependency between the > >> > SPI alias, the fifo_lvl_mask and the FIFO size. > >> > >> OK, so we do actually have SoCs with multiple instances of the IP with > >> different FIFO depths (and who knows what else other differences)? > > > > I think that's why we can see .fifo_lvl_mask[] with different values > > for different IP instances. For example, ExynosAutoV9 has this (in > > upstream driver, yes): > > > > .fifo_lvl_mask = { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, > > 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, > > > > That sounds like the same bug as in the serial port driver, > by assuming that the alias values in the devicetree have > a particular meaning in identifying instances. This immediately > breaks when there is a dtb file that does not use the same > alias values, e.g. because it only needs some of the SPI > ports. > Exactly. I guess that's exactly what Tudor mentioned in his commit message, and he's trying to fix that very problem by relying on corresponding dts property (in his patch series) rather than on .fifo_lvl_mask. > Arnd
On Fri, Jan 26, 2024 at 09:16:53PM +0100, Arnd Bergmann wrote: > That sounds like the same bug as in the serial port driver, > by assuming that the alias values in the devicetree have > a particular meaning in identifying instances. This immediately > breaks when there is a dtb file that does not use the same > alias values, e.g. because it only needs some of the SPI > ports. It'll be the result of a conversion from board files where that was a normal way of doing things.
On 26.01.2024 22:20, Sam Protsenko wrote: > On Fri, Jan 26, 2024 at 2:17 PM Arnd Bergmann <arnd@arndb.de> wrote: >> >> On Fri, Jan 26, 2024, at 20:23, Sam Protsenko wrote: >>> On Thu, Jan 25, 2024 at 11:33 AM Mark Brown <broonie@kernel.org> wrote: >>>> >>>> On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote: >>>> >>>>> Allow SoCs that have multiple instances of the SPI IP with different >>>>> FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize" >>>>> device tree property. With this we can break the dependency between the >>>>> SPI alias, the fifo_lvl_mask and the FIFO size. >>>> >>>> OK, so we do actually have SoCs with multiple instances of the IP with >>>> different FIFO depths (and who knows what else other differences)? >>> >>> I think that's why we can see .fifo_lvl_mask[] with different values >>> for different IP instances. For example, ExynosAutoV9 has this (in >>> upstream driver, yes): >>> >>> .fifo_lvl_mask = { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, >>> 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, >>> >> >> That sounds like the same bug as in the serial port driver, >> by assuming that the alias values in the devicetree have >> a particular meaning in identifying instances. This immediately >> breaks when there is a dtb file that does not use the same >> alias values, e.g. because it only needs some of the SPI >> ports. >> > > Exactly. I guess that's exactly what Tudor mentioned in his commit > message, and he's trying to fix that very problem by relying on > corresponding dts property (in his patch series) rather than on > .fifo_lvl_mask. > Yes, all from above are correct. I'll split the FIFO size patches into a smaller series to be easier to review. Cheers, ta