Skip to content

Commit a1d8128

Browse files
committed
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
2 parents df46426 + 04a8ff1 commit a1d8128

File tree

6 files changed

+61
-11
lines changed

6 files changed

+61
-11
lines changed

drivers/mtd/nand/qpic_common.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@ qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
5757
bam_txn_buf += sizeof(*bam_txn);
5858

5959
bam_txn->bam_ce = bam_txn_buf;
60-
bam_txn_buf +=
61-
sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
60+
bam_txn->bam_ce_nitems = QPIC_PER_CW_CMD_ELEMENTS * num_cw;
61+
bam_txn_buf += sizeof(*bam_txn->bam_ce) * bam_txn->bam_ce_nitems;
6262

6363
bam_txn->cmd_sgl = bam_txn_buf;
64-
bam_txn_buf +=
65-
sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
64+
bam_txn->cmd_sgl_nitems = QPIC_PER_CW_CMD_SGL * num_cw;
65+
bam_txn_buf += sizeof(*bam_txn->cmd_sgl) * bam_txn->cmd_sgl_nitems;
6666

6767
bam_txn->data_sgl = bam_txn_buf;
68+
bam_txn->data_sgl_nitems = QPIC_PER_CW_DATA_SGL * num_cw;
6869

6970
init_completion(&bam_txn->txn_done);
7071

@@ -238,6 +239,11 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
238239
struct bam_transaction *bam_txn = nandc->bam_txn;
239240
u32 offset;
240241

242+
if (bam_txn->bam_ce_pos + size > bam_txn->bam_ce_nitems) {
243+
dev_err(nandc->dev, "BAM %s array is full\n", "CE");
244+
return -EINVAL;
245+
}
246+
241247
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
242248

243249
/* fill the command desc */
@@ -258,6 +264,12 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
258264

259265
/* use the separate sgl after this command */
260266
if (flags & NAND_BAM_NEXT_SGL) {
267+
if (bam_txn->cmd_sgl_pos >= bam_txn->cmd_sgl_nitems) {
268+
dev_err(nandc->dev, "BAM %s array is full\n",
269+
"CMD sgl");
270+
return -EINVAL;
271+
}
272+
261273
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
262274
bam_ce_size = (bam_txn->bam_ce_pos -
263275
bam_txn->bam_ce_start) *
@@ -297,10 +309,20 @@ int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
297309
struct bam_transaction *bam_txn = nandc->bam_txn;
298310

299311
if (read) {
312+
if (bam_txn->rx_sgl_pos >= bam_txn->data_sgl_nitems) {
313+
dev_err(nandc->dev, "BAM %s array is full\n", "RX sgl");
314+
return -EINVAL;
315+
}
316+
300317
sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
301318
vaddr, size);
302319
bam_txn->rx_sgl_pos++;
303320
} else {
321+
if (bam_txn->tx_sgl_pos >= bam_txn->data_sgl_nitems) {
322+
dev_err(nandc->dev, "BAM %s array is full\n", "TX sgl");
323+
return -EINVAL;
324+
}
325+
304326
sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
305327
vaddr, size);
306328
bam_txn->tx_sgl_pos++;

drivers/spi/spi-cadence-quadspi.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,11 +1960,6 @@ static int cqspi_probe(struct platform_device *pdev)
19601960

19611961
pm_runtime_enable(dev);
19621962

1963-
if (cqspi->rx_chan) {
1964-
dma_release_channel(cqspi->rx_chan);
1965-
goto probe_setup_failed;
1966-
}
1967-
19681963
pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
19691964
pm_runtime_use_autosuspend(dev);
19701965
pm_runtime_get_noresume(dev);

drivers/spi/spi-fsl-dspi.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,11 +983,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
983983
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
984984
status = dspi_dma_xfer(dspi);
985985
} else {
986+
/*
987+
* Reinitialize the completion before transferring data
988+
* to avoid the case where it might remain in the done
989+
* state due to a spurious interrupt from a previous
990+
* transfer. This could falsely signal that the current
991+
* transfer has completed.
992+
*/
993+
if (dspi->irq)
994+
reinit_completion(&dspi->xfer_done);
995+
986996
dspi_fifo_write(dspi);
987997

988998
if (dspi->irq) {
989999
wait_for_completion(&dspi->xfer_done);
990-
reinit_completion(&dspi->xfer_done);
9911000
} else {
9921001
do {
9931002
status = dspi_poll(dspi);

drivers/spi/spi-qpic-snand.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
315315

316316
mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
317317

318+
/*
319+
* Free the temporary BAM transaction allocated initially by
320+
* qcom_nandc_alloc(), and allocate a new one based on the
321+
* updated max_cwperpage value.
322+
*/
323+
qcom_free_bam_transaction(snandc);
324+
325+
snandc->max_cwperpage = cwperpage;
326+
327+
snandc->bam_txn = qcom_alloc_bam_transaction(snandc);
328+
if (!snandc->bam_txn) {
329+
dev_err(snandc->dev, "failed to allocate BAM transaction\n");
330+
ret = -ENOMEM;
331+
goto err_free_ecc_cfg;
332+
}
333+
318334
ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
319335
FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
320336
FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |

include/linux/mtd/nand-qpic-common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@
237237
* @last_data_desc - last DMA desc in data channel (tx/rx).
238238
* @last_cmd_desc - last DMA desc in command channel.
239239
* @txn_done - completion for NAND transfer.
240+
* @bam_ce_nitems - the number of elements in the @bam_ce array
241+
* @cmd_sgl_nitems - the number of elements in the @cmd_sgl array
242+
* @data_sgl_nitems - the number of elements in the @data_sgl array
240243
* @bam_ce_pos - the index in bam_ce which is available for next sgl
241244
* @bam_ce_start - the index in bam_ce which marks the start position ce
242245
* for current sgl. It will be used for size calculation
@@ -255,6 +258,11 @@ struct bam_transaction {
255258
struct dma_async_tx_descriptor *last_data_desc;
256259
struct dma_async_tx_descriptor *last_cmd_desc;
257260
struct completion txn_done;
261+
262+
unsigned int bam_ce_nitems;
263+
unsigned int cmd_sgl_nitems;
264+
unsigned int data_sgl_nitems;
265+
258266
struct_group(bam_positions,
259267
u32 bam_ce_pos;
260268
u32 bam_ce_start;

include/linux/spi/spi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <uapi/linux/spi/spi.h>
2222

2323
/* Max no. of CS supported per spi device */
24-
#define SPI_CS_CNT_MAX 16
24+
#define SPI_CS_CNT_MAX 24
2525

2626
struct dma_chan;
2727
struct software_node;

0 commit comments

Comments
 (0)