[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.