* [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization
@ 2026-11-08 22:42 James Hilliard
2026-11-08 22:42 ` [PATCH v2 1/4] mtd: rawnand: qcom: parse boot partitions before registering MTD James Hilliard
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: James Hilliard @ 2026-11-08 22:42 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Manivannan Sadhasivam, Christian Marangi, Sricharan R,
Md Sadre Alam, Boris Brezillon
Cc: linux-mtd, linux-arm-msm, linux-kernel, James Hilliard, stable
Keep the shared BAM transaction usable when resizing it fails, validate
the boot-partition layout before publishing a chip, and propagate child
probe failures after unregistering any previously published chips.
The first three patches fix layout validation, allocation failure and
controller-wide probe unwind. The fourth scans every chip before
publishing any MTD devices, so initialization cannot race with I/O
on an earlier chip using the shared controller state.
Assisted-by: Codex:gpt-6-astra
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
Changes in v2:
- Add a patch separating initialization of all chips from MTD
registration, addressing the concurrent BAM replacement report.
- Track which scanned chips are registered for probe-error cleanup.
- Link to v1: https://patch.msgid.link/20261108-submit-qcom-nand-child-probe-errors-v1-v1-0-509f30a9e14d@gmail.com
To: Manivannan Sadhasivam <mani@kernel.org>
To: Miquel Raynal <miquel.raynal@bootlin.com>
To: Richard Weinberger <richard@nod.at>
To: Vignesh Raghavendra <vigneshr@ti.com>
To: Christian Marangi <ansuelsmth@gmail.com>
To: Sricharan R <quic_srichara@quicinc.com>
To: Md Sadre Alam <quic_mdalam@quicinc.com>
To: Boris Brezillon <bbrezillon@kernel.org>
Cc: linux-mtd@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
James Hilliard (4):
mtd: rawnand: qcom: parse boot partitions before registering MTD
mtd: rawnand: qcom: retain the BAM transaction if replacement fails
mtd: rawnand: qcom: unwind registered chips on child probe failure
mtd: rawnand: qcom: scan all chips before registering MTD devices
drivers/mtd/nand/raw/qcom_nandc.c | 72 ++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 28 deletions(-)
---
base-commit: 30daaf3e7897b4a8d9b72e5b0c86dd6e2a4d7d85
change-id: 20261107-submit-qcom-nand-child-probe-errors-v1-f5e2703a17a5
Best regards,
--
James Hilliard <james.hilliard1@gmail.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/4] mtd: rawnand: qcom: parse boot partitions before registering MTD
2026-11-08 22:42 [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization James Hilliard
@ 2026-11-08 22:42 ` James Hilliard
2026-11-08 22:42 ` [PATCH v2 2/4] mtd: rawnand: qcom: retain the BAM transaction if replacement fails James Hilliard
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: James Hilliard @ 2026-11-08 22:42 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Manivannan Sadhasivam, Christian Marangi, Sricharan R,
Md Sadre Alam, Boris Brezillon
Cc: linux-mtd, linux-arm-msm, linux-kernel, James Hilliard, stable
A boot-partition parsing error currently calls nand_cleanup() after the
MTD device has already been registered, leaving a published device backed
by freed chip resources. Registration can also invoke consumers before
the boot-partition layout is available.
Parse that layout after nand_scan() supplies the geometry but before
publishing the device. All failures then reach cleanup without leaving a
registered MTD behind.
Fixes: 862bdedd7f4b ("mtd: nand: raw: qcom_nandc: add support for unprotected spare data pages")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 2d98f79b492d..f240d1effa04 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2052,16 +2052,16 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
if (ret)
return ret;
- ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
- if (ret)
- goto err;
-
if (nandc->props->use_codeword_fixup) {
ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn);
if (ret)
goto err;
}
+ ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
+ if (ret)
+ goto err;
+
return 0;
err:
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/4] mtd: rawnand: qcom: retain the BAM transaction if replacement fails
2026-11-08 22:42 [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization James Hilliard
2026-11-08 22:42 ` [PATCH v2 1/4] mtd: rawnand: qcom: parse boot partitions before registering MTD James Hilliard
@ 2026-11-08 22:42 ` James Hilliard
2026-11-08 22:42 ` [PATCH v2 3/4] mtd: rawnand: qcom: unwind registered chips on child probe failure James Hilliard
2026-11-08 22:42 ` [PATCH v2 4/4] mtd: rawnand: qcom: scan all chips before registering MTD devices James Hilliard
3 siblings, 0 replies; 5+ messages in thread
From: James Hilliard @ 2026-11-08 22:42 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Manivannan Sadhasivam, Christian Marangi, Sricharan R,
Md Sadre Alam, Boris Brezillon
Cc: linux-mtd, linux-arm-msm, linux-kernel, James Hilliard, stable
Attaching a chip frees the controller's BAM transaction before allocating
one sized for its page geometry. Allocation failure leaves bam_txn NULL,
although later chip scans and previously registered chips still use that
shared transaction.
Allocate the replacement before freeing the old transaction. Restore the
old capacity on failure so the controller retains a usable transaction
for already initialized chips, including I/O during probe cleanup.
Fixes: ba7542eb2dd5 ("mtd: rawnand: qcom: fix memory corruption that causes panic")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/mtd/nand/raw/qcom_nandc.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index f240d1effa04..062fba9eaecc 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1329,21 +1329,22 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
- /* Free the initially allocated BAM transaction for reading the ONFI params */
- if (nandc->props->supports_bam)
- qcom_free_bam_transaction(nandc);
-
- nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
- cwperpage);
-
/* Now allocate the BAM transaction based on updated max_cwperpage */
if (nandc->props->supports_bam) {
- nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
- if (!nandc->bam_txn) {
+ unsigned int old_max_cwperpage = nandc->max_cwperpage;
+ struct bam_transaction *bam_txn;
+
+ nandc->max_cwperpage = max_t(unsigned int, old_max_cwperpage,
+ cwperpage);
+ bam_txn = qcom_alloc_bam_transaction(nandc);
+ if (!bam_txn) {
+ nandc->max_cwperpage = old_max_cwperpage;
dev_err(nandc->dev,
"failed to allocate bam transaction\n");
return -ENOMEM;
}
+ qcom_free_bam_transaction(nandc);
+ nandc->bam_txn = bam_txn;
}
/*
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 3/4] mtd: rawnand: qcom: unwind registered chips on child probe failure
2026-11-08 22:42 [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization James Hilliard
2026-11-08 22:42 ` [PATCH v2 1/4] mtd: rawnand: qcom: parse boot partitions before registering MTD James Hilliard
2026-11-08 22:42 ` [PATCH v2 2/4] mtd: rawnand: qcom: retain the BAM transaction if replacement fails James Hilliard
@ 2026-11-08 22:42 ` James Hilliard
2026-11-08 22:42 ` [PATCH v2 4/4] mtd: rawnand: qcom: scan all chips before registering MTD devices James Hilliard
3 siblings, 0 replies; 5+ messages in thread
From: James Hilliard @ 2026-11-08 22:42 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Manivannan Sadhasivam, Christian Marangi, Sricharan R,
Md Sadre Alam, Boris Brezillon
Cc: linux-mtd, linux-arm-msm, linux-kernel, James Hilliard, stable
qcom_probe_nand_devices() continues after a child initialization error,
allowing a later successful child to hide failures such as -ENOMEM or
-EPROBE_DEFER. If the last child fails, or allocating a subsequent host
fails, probe releases controller resources without unregistering chips
that were already published.
Fail probe on the first error from an enabled NAND child and propagate
that error. Share chip cleanup with removal and run it before releasing
DMA resources or disabling the controller clocks.
Fixes: 89f5127c4b0d ("mtd: nand: qcom: reorganize nand devices probing")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/mtd/nand/raw/qcom_nandc.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 062fba9eaecc..14bb7f3d6c36 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2085,7 +2085,7 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
ret = qcom_nand_host_init_and_register(nandc, host, child);
if (ret) {
devm_kfree(dev, host);
- continue;
+ return ret;
}
list_add_tail(&host->node, &nandc->host_list);
@@ -2094,6 +2094,19 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
return ret;
}
+static void qcom_nandc_cleanup_chips(struct qcom_nand_controller *nandc)
+{
+ struct qcom_nand_host *host, *tmp;
+ int ret;
+
+ list_for_each_entry_safe(host, tmp, &nandc->host_list, node) {
+ ret = mtd_device_unregister(nand_to_mtd(&host->chip));
+ WARN_ON(ret);
+ nand_cleanup(&host->chip);
+ list_del(&host->node);
+ }
+}
+
/* parse custom DT properties here */
static int qcom_nandc_parse_dt(struct platform_device *pdev)
{
@@ -2184,10 +2197,12 @@ static int qcom_nandc_probe(struct platform_device *pdev)
ret = qcom_probe_nand_devices(nandc);
if (ret)
- goto err_setup;
+ goto err_cleanup_chips;
return 0;
+err_cleanup_chips:
+ qcom_nandc_cleanup_chips(nandc);
err_setup:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
@@ -2204,16 +2219,8 @@ static void qcom_nandc_remove(struct platform_device *pdev)
{
struct qcom_nand_controller *nandc = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct qcom_nand_host *host;
- struct nand_chip *chip;
- int ret;
- list_for_each_entry(host, &nandc->host_list, node) {
- chip = &host->chip;
- ret = mtd_device_unregister(nand_to_mtd(chip));
- WARN_ON(ret);
- nand_cleanup(chip);
- }
+ qcom_nandc_cleanup_chips(nandc);
qcom_nandc_unalloc(nandc);
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 4/4] mtd: rawnand: qcom: scan all chips before registering MTD devices
2026-11-08 22:42 [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization James Hilliard
` (2 preceding siblings ...)
2026-11-08 22:42 ` [PATCH v2 3/4] mtd: rawnand: qcom: unwind registered chips on child probe failure James Hilliard
@ 2026-11-08 22:42 ` James Hilliard
3 siblings, 0 replies; 5+ messages in thread
From: James Hilliard @ 2026-11-08 22:42 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Manivannan Sadhasivam, Christian Marangi, Sricharan R,
Md Sadre Alam, Boris Brezillon
Cc: linux-mtd, linux-arm-msm, linux-kernel, James Hilliard, stable
Each NAND child is registered before the next child is scanned. Once a
chip is published, its MTD operations can run concurrently with the next
nand_scan(), which does not hold the controller lock. Both paths use
controller-wide command buffers, and attaching another chip can replace
the BAM transaction underneath an active transfer.
Initialize and scan every child before registering any MTD devices. Track
which chips have been registered so probe failure unregisters only those
devices while cleaning up every successfully scanned chip.
Fixes: 6a3cec64f18c ("mtd: rawnand: qcom: convert driver to nand_scan()")
Cc: stable@vger.kernel.org
Closes: https://lore.kernel.org/r/sashiko-outbox-204074@kernel.org/
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/mtd/nand/raw/qcom_nandc.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 14bb7f3d6c36..978fa84f051d 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -89,6 +89,7 @@ struct qcom_op {
* @use_ecc: request the controller to use ECC for the
* upcoming read/write
* @bch_enabled: flag to tell whether BCH ECC mode is used
+ * @registered: whether the MTD device has been registered
*/
struct qcom_nand_host {
struct qcom_nand_boot_partition *boot_partitions;
@@ -118,6 +119,7 @@ struct qcom_nand_host {
bool codeword_fixup;
bool use_ecc;
bool bch_enabled;
+ bool registered;
};
static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
@@ -2008,9 +2010,9 @@ static int qcom_nand_host_parse_boot_partitions(struct qcom_nand_controller *nan
return 0;
}
-static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
- struct qcom_nand_host *host,
- struct device_node *dn)
+static int qcom_nand_host_init(struct qcom_nand_controller *nandc,
+ struct qcom_nand_host *host,
+ struct device_node *dn)
{
struct nand_chip *chip = &host->chip;
struct mtd_info *mtd = nand_to_mtd(chip);
@@ -2059,10 +2061,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
goto err;
}
- ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
- if (ret)
- goto err;
-
return 0;
err:
@@ -2082,7 +2080,7 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
if (!host)
return -ENOMEM;
- ret = qcom_nand_host_init_and_register(nandc, host, child);
+ ret = qcom_nand_host_init(nandc, host, child);
if (ret) {
devm_kfree(dev, host);
return ret;
@@ -2091,6 +2089,14 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
list_add_tail(&host->node, &nandc->host_list);
}
+ list_for_each_entry(host, &nandc->host_list, node) {
+ ret = mtd_device_parse_register(nand_to_mtd(&host->chip),
+ probes, NULL, NULL, 0);
+ if (ret)
+ return ret;
+ host->registered = true;
+ }
+
return ret;
}
@@ -2100,8 +2106,10 @@ static void qcom_nandc_cleanup_chips(struct qcom_nand_controller *nandc)
int ret;
list_for_each_entry_safe(host, tmp, &nandc->host_list, node) {
- ret = mtd_device_unregister(nand_to_mtd(&host->chip));
- WARN_ON(ret);
+ if (host->registered) {
+ ret = mtd_device_unregister(nand_to_mtd(&host->chip));
+ WARN_ON(ret);
+ }
nand_cleanup(&host->chip);
list_del(&host->node);
}
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-08 22:42 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-08 22:42 [PATCH v2 0/4] mtd: rawnand: qcom: unwind failed child initialization James Hilliard
2026-11-08 22:42 ` [PATCH v2 1/4] mtd: rawnand: qcom: parse boot partitions before registering MTD James Hilliard
2026-11-08 22:42 ` [PATCH v2 2/4] mtd: rawnand: qcom: retain the BAM transaction if replacement fails James Hilliard
2026-11-08 22:42 ` [PATCH v2 3/4] mtd: rawnand: qcom: unwind registered chips on child probe failure James Hilliard
2026-11-08 22:42 ` [PATCH v2 4/4] mtd: rawnand: qcom: scan all chips before registering MTD devices James Hilliard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®