From 7a874e8b54ea21094f7fd2d428b164394c6cb316 Mon Sep 17 00:00:00 2001 From: Luis de Arquer Date: Fri, 21 Mar 2025 13:57:53 +0100 Subject: [PATCH 1/7] spi-rockchip: Fix register out of bounds access Do not write native chip select stuff for GPIO chip selects. GPIOs can be numbered much higher than native CS. Also, it makes no sense. Signed-off-by: Luis de Arquer Link: https://patch.msgid.link/365ccddfba110549202b3520f4401a6a936e82a8.camel@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 1bc012fce7cb8..1a6381de6f33d 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -547,7 +547,7 @@ static int rockchip_spi_config(struct rockchip_spi *rs, cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET; if (spi->mode & SPI_LSB_FIRST) cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET; - if (spi->mode & SPI_CS_HIGH) + if ((spi->mode & SPI_CS_HIGH) && !(spi_get_csgpiod(spi, 0))) cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET; if (xfer->rx_buf && xfer->tx_buf) From d32c4e58545f17caaa854415f854691e32d42075 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 26 Mar 2025 15:22:19 +0100 Subject: [PATCH 2/7] spi: SPI_QPIC_SNAND should be tristate and depend on MTD SPI_QPIC_SNAND is the only driver that selects MTD instead of depending on it, which could lead to circular dependencies. Moreover, as SPI_QPIC_SNAND is bool, this forces MTD (and various related symbols) to be built-in, as can be seen in an allmodconfig kernel. Except for a missing semicolon, there is no reason why SPI_QPIC_SNAND cannot be tristate; all MODULE_*() boilerplate is already present. Hence make SPI_QPIC_SNAND tristate, let it depend on MTD, and add the missing semicolon. Fixes: 7304d1909080ef0c ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") Signed-off-by: Geert Uytterhoeven Link: https://patch.msgid.link/b63db431cbf35223a4400e44c296293d32c4543c.1742998909.git.geert+renesas@glider.be Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 4 ++-- drivers/spi/spi-qpic-snand.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f40c282d4d633..ed38f6d41f470 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -937,9 +937,9 @@ config SPI_QCOM_QSPI QSPI(Quad SPI) driver for Qualcomm QSPI controller. config SPI_QPIC_SNAND - bool "QPIC SNAND controller" + tristate "QPIC SNAND controller" depends on ARCH_QCOM || COMPILE_TEST - select MTD + depends on MTD help QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller. QPIC controller supports both parallel nand and serial nand. diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index fbba7741a9bf3..17eb67e191326 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c @@ -1614,7 +1614,7 @@ static const struct of_device_id qcom_snandc_of_match[] = { .data = &ipq9574_snandc_props, }, {} -} +}; MODULE_DEVICE_TABLE(of, qcom_snandc_of_match); static struct platform_driver qcom_spi_driver = { From 40369bfe717e96e26650eeecfa5a6363563df6e4 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Wed, 26 Mar 2025 17:41:51 -0500 Subject: [PATCH 3/7] spi: fsl-qspi: use devm function instead of driver remove Driver use devm APIs to manage clk/irq/resources and register the spi controller, but the legacy remove function will be called first during device detach and trigger kernel panic. Drop the remove function and use devm_add_action_or_reset() for driver cleanup to ensure the release sequence. Trigger kernel panic on i.MX8MQ by echo 30bb0000.spi >/sys/bus/platform/drivers/fsl-quadspi/unbind Cc: stable@vger.kernel.org Fixes: 8fcb830a00f0 ("spi: spi-fsl-qspi: use devm_spi_register_controller") Reported-by: Kevin Hao Signed-off-by: Han Xu Reviewed-by: Frank Li Link: https://patch.msgid.link/20250326224152.2147099-1-han.xu@nxp.com Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-qspi.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index 355e6a39fb418..5c59fddb32c1b 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -844,6 +844,19 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = { .per_op_freq = true, }; +static void fsl_qspi_cleanup(void *data) +{ + struct fsl_qspi *q = data; + + /* disable the hardware */ + qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); + qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER); + + fsl_qspi_clk_disable_unprep(q); + + mutex_destroy(&q->lock); +} + static int fsl_qspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -934,6 +947,10 @@ static int fsl_qspi_probe(struct platform_device *pdev) ctlr->dev.of_node = np; + ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q); + if (ret) + goto err_destroy_mutex; + ret = devm_spi_register_controller(dev, ctlr); if (ret) goto err_destroy_mutex; @@ -953,19 +970,6 @@ static int fsl_qspi_probe(struct platform_device *pdev) return ret; } -static void fsl_qspi_remove(struct platform_device *pdev) -{ - struct fsl_qspi *q = platform_get_drvdata(pdev); - - /* disable the hardware */ - qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); - qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER); - - fsl_qspi_clk_disable_unprep(q); - - mutex_destroy(&q->lock); -} - static int fsl_qspi_suspend(struct device *dev) { return 0; @@ -1003,7 +1007,6 @@ static struct platform_driver fsl_qspi_driver = { .pm = &fsl_qspi_pm_ops, }, .probe = fsl_qspi_probe, - .remove = fsl_qspi_remove, }; module_platform_driver(fsl_qspi_driver); From 7ba0847fa1c22e7801cebfe5f7b75aee4fae317e Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 31 Mar 2025 08:33:32 -0700 Subject: [PATCH 4/7] spi: cadence: Fix out-of-bounds array access in cdns_mrvl_xspi_setup_clock() If requested_clk > 128, cdns_mrvl_xspi_setup_clock() iterates over the entire cdns_mrvl_xspi_clk_div_list array without breaking out early, causing 'i' to go beyond the array bounds. Fix that by stopping the loop when it gets to the last entry, clamping the clock to the minimum 6.25 MHz. Fixes the following warning with an UBSAN kernel: vmlinux.o: warning: objtool: cdns_mrvl_xspi_setup_clock: unexpected end of section .text.cdns_mrvl_xspi_setup_clock Fixes: 26d34fdc4971 ("spi: cadence: Add clock configuration for Marvell xSPI overlay") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503282236.UhfRsF3B-lkp@intel.com/ Link: https://lore.kernel.org/r/gs2ooxfkblnee6cc5yfcxh7nu4wvoqnuv4lrllkhccxgcac2jg@7snmwd73jkhs Signed-off-by: Josh Poimboeuf Link: https://patch.msgid.link/h6bef6wof6zpjfp3jbhrkigqsnykdfy6j4qmmvb6gsabhianhj@k57a7hwpa3bj Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-xspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index aed98ab143346..6dcba0e0ddaa3 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -432,7 +432,7 @@ static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi, u32 clk_reg; bool update_clk = false; - while (i < ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list)) { + while (i < (ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list) - 1)) { clk_val = MRVL_XSPI_CLOCK_DIVIDED( cdns_mrvl_xspi_clk_div_list[i]); if (clk_val <= requested_clk) From 3cb2a2f7eebbb0752a834708e720a914e61841a1 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 1 Apr 2025 15:47:47 +0200 Subject: [PATCH 5/7] spi: cadence-qspi: revert "Improve spi memory performance" During the v6.14-rc cycles, there has been an issue with syscons which prevented TI chipid controller to probe, itself preventing the only DMA engine on AM62A with the memcpy capability to probe, which is needed for the SPI controller to work in its most efficient configuration. The SPI controller on AM62A can be used in DAC and INDAC mode, which are some kind of direct mapping vs. CPU-controlled SPI operations, respectively. However, because of hardware constraints (some kind of request line not being driven), INDAC mode cannot leverage DMA without risking to underflow the SPI FIFO. This mode costs a lot of CPU cycles. On the other side however, DAC mode can be used with and without DMA support, but in practice, DMA transfers are way more efficient because of the burst capabilities that the CPU does not have. As a result, in terms of read throughput, using a Winbond chip in 1-8-8 SDR mode, we get: - 3.5MiB/s in DAC mode without DMA - 9.0MiB/s in INDAC mode (CPU more busy) - a fluctuating 9 to 12MiB/s in DAC mode with DMA (a constant 14.5MiB/s without CPUfreq) The reason for the patch that is being reverted is that because of the syscon issue, we were using a very un-efficient DAC configuration (no DMA), but since: commit 5728c92ae112 ("mfd: syscon: Restore device_node_to_regmap() for non-syscon nodes") the probing of the DMA controller has been fixed, and the performances are back to normal, so we can safely revert this commit. This is a revert of: commit cce2200dacd6 ("spi: cadence-qspi: Improve spi memory performance") Suggested-by: Vignesh Raghavendra Signed-off-by: Miquel Raynal Link: https://patch.msgid.link/20250401134748.242846-1-miquel.raynal@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 559fbdfbd9f73..c90462783b3f9 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -2073,7 +2073,7 @@ static const struct cqspi_driver_platdata k2g_qspi = { static const struct cqspi_driver_platdata am654_ospi = { .hwcaps_mask = CQSPI_SUPPORTS_OCTAL | CQSPI_SUPPORTS_QUAD, - .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NEEDS_WR_DELAY, + .quirks = CQSPI_NEEDS_WR_DELAY, }; static const struct cqspi_driver_platdata intel_lgm_qspi = { From d6691010523fe1016f482a1e1defcc6289eeea48 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 1 Apr 2025 15:42:38 -0700 Subject: [PATCH 6/7] spi: bcm2835: Do not call gpiod_put() on invalid descriptor If we are unable to lookup the chip-select GPIO, the error path will call bcm2835_spi_cleanup() which unconditionally calls gpiod_put() on the cs->gpio variable which we just determined was invalid. Fixes: 21f252cd29f0 ("spi: bcm2835: reduce the abuse of the GPIO API") Signed-off-by: Florian Fainelli Link: https://patch.msgid.link/20250401224238.2854256-1-florian.fainelli@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm2835.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 0d1aa65924846..06a81727d74dd 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -1162,7 +1162,8 @@ static void bcm2835_spi_cleanup(struct spi_device *spi) sizeof(u32), DMA_TO_DEVICE); - gpiod_put(bs->cs_gpio); + if (!IS_ERR(bs->cs_gpio)) + gpiod_put(bs->cs_gpio); spi_set_csgpiod(spi, 0, NULL); kfree(target); From e19c1272c80a5ecce387c1b0c3b995f4edf9c525 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 1 Apr 2025 16:36:03 -0700 Subject: [PATCH 7/7] spi: bcm2835: Restore native CS probing when pinctrl-bcm2835 is absent The lookup table forces the use of the "pinctrl-bcm2835" GPIO chip provider and essentially assumes that there is going to be such a provider, and if not, we will fail to set-up the SPI device. While this is true on Raspberry Pi based systems (2835/36/37, 2711, 2712), this is not true on 7712/77122 Broadcom STB systems which use the SPI driver, but not the GPIO driver. There used to be an early check: chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); if (!chip) return 0; which would accomplish that nicely, bring something similar back by checking for the compatible strings matched by the pinctrl-bcm2835.c driver, if there is no Device Tree node matching those compatible strings, then we won't find any GPIO provider registered by the "pinctrl-bcm2835" driver. Fixes: 21f252cd29f0 ("spi: bcm2835: reduce the abuse of the GPIO API") Signed-off-by: Florian Fainelli Link: https://patch.msgid.link/20250401233603.2938955-1-florian.fainelli@broadcom.com Acked-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- drivers/spi/spi-bcm2835.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 06a81727d74dd..77de5a07639af 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -1226,7 +1226,12 @@ static int bcm2835_spi_setup(struct spi_device *spi) struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct bcm2835_spidev *target = spi_get_ctldata(spi); struct gpiod_lookup_table *lookup __free(kfree) = NULL; - int ret; + const char *pinctrl_compats[] = { + "brcm,bcm2835-gpio", + "brcm,bcm2711-gpio", + "brcm,bcm7211-gpio", + }; + int ret, i; u32 cs; if (!target) { @@ -1291,6 +1296,14 @@ static int bcm2835_spi_setup(struct spi_device *spi) goto err_cleanup; } + for (i = 0; i < ARRAY_SIZE(pinctrl_compats); i++) { + if (of_find_compatible_node(NULL, NULL, pinctrl_compats[i])) + break; + } + + if (i == ARRAY_SIZE(pinctrl_compats)) + return 0; + /* * TODO: The code below is a slightly better alternative to the utter * abuse of the GPIO API that I found here before. It creates a