[PATCH 09/27] mtd: nand: nand_mrvl_nfc: support the nand-controller bindings
Sascha Hauer <[email protected]>
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
The driver only knows the deprecated "marvell,pxa3xx-nand" and "marvell,armada370-nand" compatibles, where the chip properties are in the controller node. The upstream device trees use the newer "...-nand-controller" bindings, where the chip lives in a child node along with its partitions. Add the new compatibles and read the chip properties from the child node. Handing that node to the NAND core via nand_set_flash_node() is what makes the generic properties and the partitions below it work at all: mtd_get_of_node() otherwise falls back to the parent, which is the controller node. Assisted-by: Claude Opus 5 Signed-off-by: Sascha Hauer <[email protected]> --- drivers/mtd/nand/raw/nand_mrvl_nfc.c | 69 ++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_mrvl_nfc.c b/drivers/mtd/nand/raw/nand_mrvl_nfc.c index 6f3fb57062..ebb1fd81fb 100644 --- a/drivers/mtd/nand/raw/nand_mrvl_nfc.c +++ b/drivers/mtd/nand/raw/nand_mrvl_nfc.c @@ -132,6 +132,12 @@ struct mrvl_nand_variant { unsigned int hwflags; + /* + * True for the "nand-controller" bindings, where the chip properties + * live in per chip select child nodes instead of in the controller + * node itself. + */ + bool chip_subnodes; }; struct mrvl_nand_host { @@ -288,7 +294,26 @@ static const struct mrvl_nand_variant armada370_variant = { .hwflags = HWFLAGS_ECC_BCH | HWFLAGS_HAS_NDCB3, }; +static const struct mrvl_nand_variant pxa3xx_controller_variant = { + .hwflags = 0, + .chip_subnodes = true, +}; + +static const struct mrvl_nand_variant armada370_controller_variant = { + .hwflags = HWFLAGS_ECC_BCH | HWFLAGS_HAS_NDCB3, + .chip_subnodes = true, +}; + static struct of_device_id mrvl_nand_dt_ids[] = { + { + .compatible = "marvell,pxa3xx-nand-controller", + .data = &pxa3xx_controller_variant, + }, + { + .compatible = "marvell,armada370-nand-controller", + .data = &armada370_controller_variant, + }, + /* Deprecated bindings, the chip properties are in the controller node */ { .compatible = "marvell,pxa3xx-nand", .data = &pxa3xx_variant, @@ -1199,33 +1224,55 @@ static struct mrvl_nand_host *alloc_nand_resource(struct device *dev) static int mrvl_nand_probe_dt(struct mrvl_nand_host *host) { struct device_node *np = host->dev->of_node; - const struct of_device_id *match; const struct mrvl_nand_variant *variant; + struct device_node *chip_np; if (!IS_ENABLED(CONFIG_OFTREE) || host->dev->platform_data) return 0; - match = of_match_node(mrvl_nand_dt_ids, np); - if (!match) + variant = device_get_match_data(host->dev); + if (!variant) return -EINVAL; - variant = match->data; - if (of_get_property(np, "marvell,nand-keep-config", NULL)) - host->keep_config = 1; + host->hwflags = variant->hwflags; + of_property_read_u32(np, "num-cs", &host->num_cs); - if (of_get_nand_on_flash_bbt(np)) + + /* + * With the "nand-controller" bindings the chip lives in a child node + * of the controller. Only a single chip is supported, so take the + * first one. The deprecated bindings have the chip properties in the + * controller node itself. + */ + if (variant->chip_subnodes) { + chip_np = of_get_next_available_child(np, NULL); + if (!chip_np) { + dev_err(host->dev, "no chip node found\n"); + return -ENODEV; + } + } else { + chip_np = np; + } + + /* + * Hand the chip node to the NAND core so that the generic properties + * and the partitions below it are evaluated. + */ + nand_set_flash_node(&host->chip, chip_np); + + if (of_get_property(chip_np, "marvell,nand-keep-config", NULL)) + host->keep_config = 1; + if (of_get_nand_on_flash_bbt(chip_np)) host->flash_bbt = 1; - host->ecc_strength = of_get_nand_ecc_strength(np); + host->ecc_strength = of_get_nand_ecc_strength(chip_np); if (host->ecc_strength < 0) host->ecc_strength = 0; - host->ecc_step = of_get_nand_ecc_step_size(np); + host->ecc_step = of_get_nand_ecc_step_size(chip_np); if (host->ecc_step < 0) host->ecc_step = 0; - host->hwflags = variant->hwflags; - return 0; } -- 2.47.3