spi: Fixes for v6.18

A disappointingly large set of device specific fixes that have built up
 since I've been a bit tardy with sending a pull requests as people kept
 sending me new new fixes.  The bcm63xx and lpspi issues could lead to
 corruption so the fixes are fairly important for the affected parts, the
 other issues should all be relatively minor.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmkqFaIACgkQJNaLcl1U
 h9Cx4Af+N+WonkDRzn5iOEzu4dOFz4idB0mV2LkFwWgKaTXZ2G0YKwJqvWE9Yw1Z
 bxOYOmJYaZAms4qOPJJVbPm38NrkjEnRdca9+zBsyu3nuvo8QLCefgLbzgwfUFcF
 cy/9JPVdcOaI9yQsw0nfVa59NiddlnxWZM8iEbiUWkdG+Y6e6vkvs/iS0GutP39e
 XDrCLLyfzK70Pl7PwjNtSvVAQSxIuIB6Y08Q5/ck3tdQYW48Nvf48e5NIhKp/dO1
 ulIrtEYp9//pec/VRUAyNBT2JE/suDjHs+C3xeT9BLpzUlJEUq6e0yec8vtkrTiu
 S2a9nMpexxTPlu9kH31PecS/seRyHg==
 =8IkW
 -----END PGP SIGNATURE-----

Merge tag 'spi-fix-v6.18-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A disappointingly large set of device specific fixes that have built
  up since I've been a bit tardy with sending a pull requests as people
  kept sending me new new fixes.

  The bcm63xx and lpspi issues could lead to corruption so the fixes are
  fairly important for the affected parts, the other issues should all
  be relatively minor"

* tag 'spi-fix-v6.18-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: nxp-fspi: Propagate fwnode in ACPI case as well
  spi: tegra114: remove Kconfig dependency on TEGRA20_APB_DMA
  spi: amlogic-spifc-a1: Handle devm_pm_runtime_enable() errors
  spi: spi-fsl-lpspi: fix watermark truncation caused by type cast
  spi: cadence-quadspi: Fix cqspi_probe() error handling for runtime pm
  spi: bcm63xx: fix premature CS deassertion on RX-only transactions
  spi: spi-cadence-quadspi: Remove duplicate pm_runtime_put_autosuspend() call
  spi: spi-cadence-quadspi: Enable pm runtime earlier to avoid imbalance
This commit is contained in:
Linus Torvalds 2025-11-28 14:08:09 -08:00
commit e664048784
6 changed files with 39 additions and 19 deletions

View File

@ -1181,10 +1181,10 @@ config SPI_TEGRA210_QUAD
config SPI_TEGRA114
tristate "NVIDIA Tegra114 SPI Controller"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
depends on ARCH_TEGRA || COMPILE_TEST
depends on RESET_CONTROLLER
help
SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller
SPI controller driver for NVIDIA Tegra114 and later SoCs. This controller
is different than the older SoCs SPI controller and also register interface
get changed with this controller.

View File

@ -353,7 +353,9 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(spifc->dev, 500);
pm_runtime_use_autosuspend(spifc->dev);
devm_pm_runtime_enable(spifc->dev);
ret = devm_pm_runtime_enable(spifc->dev);
if (ret)
return ret;
ctrl->num_chipselect = 1;
ctrl->dev.of_node = pdev->dev.of_node;

View File

@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
if (t->rx_buf) {
do_rx = true;
/*
* In certain hardware implementations, there appears to be a
* hidden accumulator that tracks the number of bytes written into
* the hardware FIFO, and this accumulator overrides the length in
* the SPI_MSG_CTL register.
*
* Therefore, for read-only transfers, we need to write some dummy
* value into the FIFO to keep the accumulator tracking the correct
* length.
*/
if (!t->tx_buf)
memset_io(bs->tx_io + len, 0xFF, t->len);
/* prepend is half-duplex write only */
if (t == first)
prepend_len = 0;

View File

@ -1981,6 +1981,13 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->current_cs = -1;
cqspi->sclk = 0;
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
pm_runtime_get_noresume(dev);
}
ret = cqspi_setup_flash(cqspi);
if (ret) {
dev_err(dev, "failed to setup flash parameters %d\n", ret);
@ -1995,14 +2002,7 @@ static int cqspi_probe(struct platform_device *pdev)
if (cqspi->use_direct_mode) {
ret = cqspi_request_mmap_dma(cqspi);
if (ret == -EPROBE_DEFER)
goto probe_dma_failed;
}
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
pm_runtime_get_noresume(dev);
goto probe_setup_failed;
}
ret = spi_register_controller(host);
@ -2012,7 +2012,6 @@ static int cqspi_probe(struct platform_device *pdev)
}
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
pm_runtime_put_autosuspend(dev);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
}
@ -2021,7 +2020,6 @@ static int cqspi_probe(struct platform_device *pdev)
probe_setup_failed:
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
pm_runtime_disable(dev);
probe_dma_failed:
cqspi_controller_enable(cqspi, 0);
probe_reset_failed:
if (cqspi->is_jh7110)

View File

@ -486,7 +486,13 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
fsl_lpspi->tx = fsl_lpspi_buf_tx_u32;
}
fsl_lpspi->watermark = min_t(typeof(fsl_lpspi->watermark),
/*
* t->len is 'unsigned' and txfifosize and watermrk is 'u8', force
* type cast is inevitable. When len > 255, len will be truncated in min_t(),
* it caused wrong watermark set. 'unsigned int' is as the designated type
* for min_t() to avoid truncation.
*/
fsl_lpspi->watermark = min_t(unsigned int,
fsl_lpspi->txfifosize,
t->len);

View File

@ -1287,7 +1287,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
{
struct spi_controller *ctlr;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct resource *res;
struct nxp_fspi *f;
int ret, irq;
@ -1309,7 +1309,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, f);
/* find the resources - configuration register address space */
if (is_acpi_node(dev_fwnode(f->dev)))
if (is_acpi_node(fwnode))
f->iobase = devm_platform_ioremap_resource(pdev, 0);
else
f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base");
@ -1317,7 +1317,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
return PTR_ERR(f->iobase);
/* find the resources - controller memory mapped space */
if (is_acpi_node(dev_fwnode(f->dev)))
if (is_acpi_node(fwnode))
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
else
res = platform_get_resource_byname(pdev,
@ -1330,7 +1330,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
f->memmap_phy_size = resource_size(res);
/* find the clocks */
if (dev_of_node(&pdev->dev)) {
if (is_of_node(fwnode)) {
f->clk_en = devm_clk_get(dev, "fspi_en");
if (IS_ERR(f->clk_en))
return PTR_ERR(f->clk_en);
@ -1383,7 +1383,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
else
ctlr->mem_caps = &nxp_fspi_mem_caps;
ctlr->dev.of_node = np;
device_set_node(&ctlr->dev, fwnode);
ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f);
if (ret)