spi: Fixes for v6.16

As well as a few driver specific fixes we've got a core change here
 which raises the hard coded limit on the number of devices we can
 support on one SPI bus since some FPGA based systems are running into
 the existing limit.  This is not a good solution but it's one suitable
 for this point in the release cycle, we should dynamically size the
 relevant data structures which I hope will happen in the next couple of
 merge windows.
 
 We also pull in a MTD fix for the Qualcomm SNAND driver, the two fixes
 cover the same issue and merging them together minimises bisection
 issues.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmhn61YACgkQJNaLcl1U
 h9DcLgf9EAb448AdwWrM7P8KJ+mK8C0GTu/k4h6pO2u2SfQC6IaOfLZ8hwnYx0vv
 ONzVLbbPIV2MFUPr/AZOjhIr16642qv0ddh3d11yX63BcapkiacL4RNvrMPHuCUT
 ir3waPdOIrW/HgbLkxSeZOEhcROjGWv/A0a6tunseQwpcOkQqKyh4VtNIHhiXVqQ
 KD/b6xXp0SG7IMQwEv+fWa/Bj5aVkkpEX/q/bKWDlXRd/YgsNhVLgSycsSt5eI4J
 6K3kxM58x9NtHd1B/jYtHwREDNoIu4QmjzuTC4AoaKGzG41ct7sH91IOABduAE4m
 k1KHWxyBh2bIVbWWGE7qrnzuDoHa5A==
 =hOXU
 -----END PGP SIGNATURE-----

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

Pull spi fixes from Mark Brown:
 "As well as a few driver specific fixes we've got a core change here
  which raises the hard coded limit on the number of devices we can
  support on one SPI bus since some FPGA based systems are running into
  the existing limit. This is not a good solution but it's one suitable
  for this point in the release cycle, we should dynamically size the
  relevant data structures which I hope will happen in the next couple
  of merge windows.

  We also pull in a MTD fix for the Qualcomm SNAND driver, the two fixes
  cover the same issue and merging them together minimises bisection
  issues"

* tag 'spi-fix-v6.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: cadence-quadspi: fix cleanup of rx_chan on failure paths
  spi: spi-fsl-dspi: Clear completion counter before initiating transfer
  spi: Raise limit on number of chip selects to 24
  mtd: nand: qpic_common: prevent out of bounds access of BAM arrays
  spi: spi-qpic-snand: reallocate BAM transactions
This commit is contained in:
Linus Torvalds 2025-07-04 10:10:49 -07:00
commit a1d8128f70
6 changed files with 61 additions and 11 deletions

View File

@ -57,14 +57,15 @@ qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
bam_txn_buf += sizeof(*bam_txn);
bam_txn->bam_ce = bam_txn_buf;
bam_txn_buf +=
sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
bam_txn->bam_ce_nitems = QPIC_PER_CW_CMD_ELEMENTS * num_cw;
bam_txn_buf += sizeof(*bam_txn->bam_ce) * bam_txn->bam_ce_nitems;
bam_txn->cmd_sgl = bam_txn_buf;
bam_txn_buf +=
sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
bam_txn->cmd_sgl_nitems = QPIC_PER_CW_CMD_SGL * num_cw;
bam_txn_buf += sizeof(*bam_txn->cmd_sgl) * bam_txn->cmd_sgl_nitems;
bam_txn->data_sgl = bam_txn_buf;
bam_txn->data_sgl_nitems = QPIC_PER_CW_DATA_SGL * num_cw;
init_completion(&bam_txn->txn_done);
@ -238,6 +239,11 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
struct bam_transaction *bam_txn = nandc->bam_txn;
u32 offset;
if (bam_txn->bam_ce_pos + size > bam_txn->bam_ce_nitems) {
dev_err(nandc->dev, "BAM %s array is full\n", "CE");
return -EINVAL;
}
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
/* fill the command desc */
@ -258,6 +264,12 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
/* use the separate sgl after this command */
if (flags & NAND_BAM_NEXT_SGL) {
if (bam_txn->cmd_sgl_pos >= bam_txn->cmd_sgl_nitems) {
dev_err(nandc->dev, "BAM %s array is full\n",
"CMD sgl");
return -EINVAL;
}
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
bam_ce_size = (bam_txn->bam_ce_pos -
bam_txn->bam_ce_start) *
@ -297,10 +309,20 @@ int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
struct bam_transaction *bam_txn = nandc->bam_txn;
if (read) {
if (bam_txn->rx_sgl_pos >= bam_txn->data_sgl_nitems) {
dev_err(nandc->dev, "BAM %s array is full\n", "RX sgl");
return -EINVAL;
}
sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
vaddr, size);
bam_txn->rx_sgl_pos++;
} else {
if (bam_txn->tx_sgl_pos >= bam_txn->data_sgl_nitems) {
dev_err(nandc->dev, "BAM %s array is full\n", "TX sgl");
return -EINVAL;
}
sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
vaddr, size);
bam_txn->tx_sgl_pos++;

View File

@ -1960,11 +1960,6 @@ static int cqspi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
if (cqspi->rx_chan) {
dma_release_channel(cqspi->rx_chan);
goto probe_setup_failed;
}
pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
pm_runtime_get_noresume(dev);

View File

@ -983,11 +983,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
status = dspi_dma_xfer(dspi);
} else {
/*
* Reinitialize the completion before transferring data
* to avoid the case where it might remain in the done
* state due to a spurious interrupt from a previous
* transfer. This could falsely signal that the current
* transfer has completed.
*/
if (dspi->irq)
reinit_completion(&dspi->xfer_done);
dspi_fifo_write(dspi);
if (dspi->irq) {
wait_for_completion(&dspi->xfer_done);
reinit_completion(&dspi->xfer_done);
} else {
do {
status = dspi_poll(dspi);

View File

@ -315,6 +315,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
/*
* Free the temporary BAM transaction allocated initially by
* qcom_nandc_alloc(), and allocate a new one based on the
* updated max_cwperpage value.
*/
qcom_free_bam_transaction(snandc);
snandc->max_cwperpage = cwperpage;
snandc->bam_txn = qcom_alloc_bam_transaction(snandc);
if (!snandc->bam_txn) {
dev_err(snandc->dev, "failed to allocate BAM transaction\n");
ret = -ENOMEM;
goto err_free_ecc_cfg;
}
ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |

View File

@ -237,6 +237,9 @@
* @last_data_desc - last DMA desc in data channel (tx/rx).
* @last_cmd_desc - last DMA desc in command channel.
* @txn_done - completion for NAND transfer.
* @bam_ce_nitems - the number of elements in the @bam_ce array
* @cmd_sgl_nitems - the number of elements in the @cmd_sgl array
* @data_sgl_nitems - the number of elements in the @data_sgl array
* @bam_ce_pos - the index in bam_ce which is available for next sgl
* @bam_ce_start - the index in bam_ce which marks the start position ce
* for current sgl. It will be used for size calculation
@ -255,6 +258,11 @@ struct bam_transaction {
struct dma_async_tx_descriptor *last_data_desc;
struct dma_async_tx_descriptor *last_cmd_desc;
struct completion txn_done;
unsigned int bam_ce_nitems;
unsigned int cmd_sgl_nitems;
unsigned int data_sgl_nitems;
struct_group(bam_positions,
u32 bam_ce_pos;
u32 bam_ce_start;

View File

@ -21,7 +21,7 @@
#include <uapi/linux/spi/spi.h>
/* Max no. of CS supported per spi device */
#define SPI_CS_CNT_MAX 16
#define SPI_CS_CNT_MAX 24
struct dma_chan;
struct software_node;