From 9e264f3f85a56cc109cc2d6010a48aa89d5c1ff1 Mon Sep 17 00:00:00 2001 From: Amit Kumar Mahapatra via Alsa-devel Date: Fri, 10 Mar 2023 23:02:03 +0530 Subject: spi: Replace all spi->chip_select and spi->cs_gpiod references with function call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod members of struct spi_device to be an array. But changing the type of these members to array would break the spi driver functionality. To make the transition smoother introduced four new APIs to get/set the spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and spi->cs_gpiod references with get or set API calls. While adding multi-cs support in further patches the chip_select & cs_gpiod members of the spi_device structure would be converted to arrays & the "idx" parameter of the APIs would be used as array index i.e., spi->chip_select[idx] & spi->cs_gpiod[idx] respectively. Signed-off-by: Amit Kumar Mahapatra Acked-by: Heiko Stuebner # Rockchip drivers Reviewed-by: Michal Simek Reviewed-by: Cédric Le Goater # Aspeed driver Reviewed-by: Dhruva Gole # SPI Cadence QSPI Reviewed-by: Patrice Chotard # spi-stm32-qspi Acked-by: William Zhang # bcm63xx-hsspi driver Reviewed-by: Serge Semin # DW SSI part Link: https://lore.kernel.org/r/167847070432.26.15076794204368669839@mailman-core.alsa-project.org Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/spi/spi-imx.c') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e4ccd0c329d0..620bce96b1f9 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -528,7 +528,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl); /* set chip select to use */ - ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); + ctrl |= MX51_ECSPI_CTRL_CS(spi_get_chipselect(spi, 0)); /* * The ctrl register must be written first, with the EN bit set other @@ -549,22 +549,22 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, * BURST_LENGTH + 1 bits are received */ if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx)) - cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); + cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0)); else - cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); + cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0)); if (spi->mode & SPI_CPOL) { - cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); - cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); + cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0)); } else { - cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); - cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); + cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0)); } if (spi->mode & SPI_CS_HIGH) - cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); + cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0)); else - cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); + cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0)); if (cfg == current_cfg) return 0; @@ -614,9 +614,9 @@ static void mx51_configure_cpha(struct spi_imx_data *spi_imx, cpha ^= flip_cpha; if (cpha) - cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); + cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0)); else - cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); + cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0)); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); } @@ -768,8 +768,8 @@ static int mx31_prepare_transfer(struct spi_imx_data *spi_imx, reg |= MX31_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX31_CSPICTRL_SSPOL; - if (!spi->cs_gpiod) - reg |= (spi->chip_select) << + if (!spi_get_csgpiod(spi, 0)) + reg |= (spi_get_chipselect(spi, 0)) << (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : MX31_CSPICTRL_CS_SHIFT); @@ -868,8 +868,8 @@ static int mx21_prepare_transfer(struct spi_imx_data *spi_imx, reg |= MX21_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX21_CSPICTRL_SSPOL; - if (!spi->cs_gpiod) - reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; + if (!spi_get_csgpiod(spi, 0)) + reg |= spi_get_chipselect(spi, 0) << MX21_CSPICTRL_CS_SHIFT; writel(reg, spi_imx->base + MXC_CSPICTRL); -- cgit From 11951c9e3f364d7ae3b568a0e52c8335d43066b5 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 6 Mar 2023 07:57:32 +0100 Subject: spi: imx: Don't skip cleanup in remove's error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning early in a platform driver's remove callback is wrong. In this case the dma resources are not released in the error path. this is never retried later and so this is a permanent leak. To fix this, only skip hardware disabling if waking the device fails. Fixes: d593574aff0a ("spi: imx: do not access registers while clocks disabled") Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230306065733.2170662-2-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/spi/spi-imx.c') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 620bce96b1f9..81221594dd97 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1856,13 +1856,11 @@ static int spi_imx_remove(struct platform_device *pdev) spi_unregister_controller(controller); - ret = pm_runtime_resume_and_get(spi_imx->dev); - if (ret < 0) { - dev_err(spi_imx->dev, "failed to enable clock\n"); - return ret; - } - - writel(0, spi_imx->base + MXC_CSPICTRL); + ret = pm_runtime_get_sync(spi_imx->dev); + if (ret >= 0) + writel(0, spi_imx->base + MXC_CSPICTRL); + else + dev_warn(spi_imx->dev, "failed to enable clock, skip hw disable\n"); pm_runtime_dont_use_autosuspend(spi_imx->dev); pm_runtime_put_sync(spi_imx->dev); -- cgit From 423e548127223d597bb65a149ebcb3c50ea08846 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 6 Mar 2023 07:57:33 +0100 Subject: spi: imx: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is (mostly) ignored and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230306065733.2170662-3-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/spi/spi-imx.c') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 81221594dd97..1f2c7ad65ec8 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1848,7 +1848,7 @@ out_controller_put: return ret; } -static int spi_imx_remove(struct platform_device *pdev) +static void spi_imx_remove(struct platform_device *pdev) { struct spi_controller *controller = platform_get_drvdata(pdev); struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller); @@ -1867,8 +1867,6 @@ static int spi_imx_remove(struct platform_device *pdev) pm_runtime_disable(spi_imx->dev); spi_imx_sdma_exit(spi_imx); - - return 0; } static int __maybe_unused spi_imx_runtime_resume(struct device *dev) @@ -1930,7 +1928,7 @@ static struct platform_driver spi_imx_driver = { .pm = &imx_spi_pm, }, .probe = spi_imx_probe, - .remove = spi_imx_remove, + .remove_new = spi_imx_remove, }; module_platform_driver(spi_imx_driver); -- cgit From 87c614175bbf28d3fd076dc2d166bac759e41427 Mon Sep 17 00:00:00 2001 From: Kevin Groeneveld Date: Sat, 18 Mar 2023 18:21:32 -0400 Subject: spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using gpio based chip select the cs value can go outside the range 0 – 3. The various MX51_ECSPI_* macros did not take this into consideration resulting in possible corruption of the configuration. For example for any cs value over 3 the SCLKPHA bits would not be set and other values in the register possibly corrupted. One way to fix this is to just mask the cs bits to 2 bits. This still allows all 4 native chip selects to work as well as gpio chip selects (which can use any of the 4 chip select configurations). Signed-off-by: Kevin Groeneveld Link: https://lore.kernel.org/r/20230318222132.3373-1-kgroeneveld@lenbrook.com Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers/spi/spi-imx.c') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 1f2c7ad65ec8..24390c702c60 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -252,6 +252,18 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device return true; } +/* + * Note the number of natively supported chip selects for MX51 is 4. Some + * devices may have less actual SS pins but the register map supports 4. When + * using gpio chip selects the cs values passed into the macros below can go + * outside the range 0 - 3. We therefore need to limit the cs value to avoid + * corrupting bits outside the allocated locations. + * + * The simplest way to do this is to just mask the cs bits to 2 bits. This + * still allows all 4 native chip selects to work as well as gpio chip selects + * (which can use any of the 4 chip select configurations). + */ + #define MX51_ECSPI_CTRL 0x08 #define MX51_ECSPI_CTRL_ENABLE (1 << 0) #define MX51_ECSPI_CTRL_XCH (1 << 2) @@ -260,16 +272,16 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device #define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16) #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 -#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) +#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c -#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) -#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) -#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) -#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) -#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20)) +#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0)) +#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4)) +#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8)) +#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12)) +#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20)) #define MX51_ECSPI_INT 0x10 #define MX51_ECSPI_INT_TEEN (1 << 0) -- cgit From d909451ce1db59ba0281fc65ee03d8933d623574 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 28 Mar 2023 14:26:00 +0800 Subject: spi: imx: Use devm_platform_get_and_ioremap_resource() According to commit 890cc39a8799 ("drivers: provide devm_platform_get_and_ioremap_resource()"), convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yang Li Link: https://lore.kernel.org/r/20230328062600.93160-1-yang.lee@linux.alibaba.com Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/spi/spi-imx.c') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 24390c702c60..34e5f81ec431 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1765,8 +1765,7 @@ static int spi_imx_probe(struct platform_device *pdev) init_completion(&spi_imx->xfer_done); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - spi_imx->base = devm_ioremap_resource(&pdev->dev, res); + spi_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(spi_imx->base)) { ret = PTR_ERR(spi_imx->base); goto out_controller_put; -- cgit