diff options
| author | Mark Brown <broonie@kernel.org> | 2026-09-17 16:24:31 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-09-17 16:24:31 +0100 |
| commit | ca01ebd9e2ed0ea7ed4a068bcd666b0f394581ac (patch) | |
| tree | 4e01c4d37fda32cec54c2e30f734feeb0ad41068 | |
| parent | 333c6f61629bff9921813208f1a92f9ba845abdd (diff) | |
| parent | 8d691164547832f43289a7d5f3450738ead98c2d (diff) | |
| download | linux-next-ca01ebd9e2ed0ea7ed4a068bcd666b0f394581ac.tar.gz linux-next-ca01ebd9e2ed0ea7ed4a068bcd666b0f394581ac.zip | |
spi: spi-qpic-snand: fix the stale ECC context pointer
Johan Alvarado <contact@c127.dev> says:
qcom_spi_ecc_init_ctx_pipelined() installs the ooblayout but never
publishes the ECC context it allocates, so qcom_spi_ooblayout_ecc() and
qcom_spi_ooblayout_free() run against a pointer that describes something
else - a zeroed struct on a first probe, the previous attempt's freed
context on a retry. On IPQ5018 the qcom,smem-part parser makes that retry
routine, and like half the boots on a Mercusys MR80X failed to mount the
rootfs.
Patch 1 is the fix and is unchanged from v1. Patch 2 removes what becomes
redundant once the context is published. It is a cleanup with no
functional change, so it carries no Fixes: tag and is not marked for
stable.
Patch 1 was applied to mtd/fixes as 93bc7c4d2f41 on 2026-09-04 and
dropped the same day, so nothing from this series is queued.
Link: https://patch.msgid.link/20260911184416.109790-1-contact@c127.dev
| -rw-r--r-- | drivers/spi/spi-qpic-snand.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index abb1015073ec..9e626ffbe63a 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c @@ -411,6 +411,8 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) dev_dbg(snandc->dev, "ECC strength: %u bits per %u bytes\n", ecc_cfg->strength, ecc_cfg->step_size); + snandc->qspi->ecc = ecc_cfg; + return 0; err_free_ecc_cfg: @@ -427,6 +429,7 @@ static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand) kfree(snandc->qspi->oob_buf); snandc->qspi->oob_buf = NULL; + snandc->qspi->ecc = NULL; kfree(ecc_cfg); } @@ -434,9 +437,7 @@ static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *nand, struct nand_page_io_req *req) { struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); - struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand); - snandc->qspi->ecc = ecc_cfg; snandc->qspi->raw_rw = false; snandc->qspi->oob_rw = false; snandc->qspi->page_rw = false; @@ -1579,14 +1580,9 @@ static int qcom_spi_probe(struct platform_device *pdev) struct spi_controller *ctlr; struct qcom_nand_controller *snandc; struct qpic_spi_nand *qspi; - struct qpic_ecc *ecc; struct resource *res; int ret; - ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); - if (!ecc) - return -ENOMEM; - qspi = devm_kzalloc(dev, sizeof(*qspi), GFP_KERNEL); if (!qspi) return -ENOMEM; @@ -1606,7 +1602,6 @@ static int qcom_spi_probe(struct platform_device *pdev) snandc->dev = dev; snandc->qspi = qspi; snandc->qspi->ctlr = ctlr; - snandc->qspi->ecc = ecc; snandc->props = of_device_get_match_data(dev); if (!snandc->props) { |
