mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali
@ 2020-11-25  5:20 Sascha Hauer
  2020-11-25  5:20 ` [PATCH 1/4] mtd: Remove set but not used of_path Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-11-25  5:20 UTC (permalink / raw)
  To: Barebox List

In the Denali NAND driver the partitions device node to fixup
for the kernel changed over time. This used to be a direct subnode
of the controller node, but Kernel v5.2 introduced an additional
subnode between the controller node and the partitions node.
Until then the binding complies with the current generic NAND
binding which has subnodes for each NAND chip under the controller
node.
We'll likely see that more often in the future. For now solve this
at driver level, but we might want to solve that in mtd code some
day.

Sascha

Sascha Hauer (4):
  mtd: Remove set but not used of_path
  of: partitions: export of_fixup_partitions
  mtd: Add hook to fix up kernel partitions
  mtd: nand: denali: cope with kernel device trees without chip subnodes

 drivers/mtd/core.c                | 31 +++++++++++++++--
 drivers/mtd/nand/nand_denali_dt.c | 57 +++++++++++++++++++++++++++++++
 drivers/of/partition.c            | 37 +++++++++++---------
 include/linux/mtd/mtd.h           |  3 +-
 include/of.h                      |  6 ++++
 5 files changed, 115 insertions(+), 19 deletions(-)

-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] mtd: Remove set but not used of_path
  2020-11-25  5:20 [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali Sascha Hauer
@ 2020-11-25  5:20 ` Sascha Hauer
  2020-11-25  5:20 ` [PATCH 2/4] of: partitions: export of_fixup_partitions Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-11-25  5:20 UTC (permalink / raw)
  To: Barebox List

struct mtd_info member of_path is set but not used, remove it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c      | 1 -
 include/linux/mtd/mtd.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 1b1ed53a61..e21c71b816 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -706,7 +706,6 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
 		dev_add_param_string(&mtd->dev, "partitions", mtd_partition_set, mtd_partition_get, &mtd->partition_string, mtd);
 		if (IS_ENABLED(CONFIG_OFDEVICE) && np) {
 			of_parse_partitions(&mtd->cdev, np);
-			mtd->of_path = xstrdup(np->full_name);
 			ret = of_partitions_register_fixup(&mtd->cdev);
 			if (ret)
 				goto err1;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index ee37dfd5cb..0e2ff4526d 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -248,7 +248,6 @@ struct mtd_info {
 	struct list_head partitions_entry;
 	char *partition_string;
 
-	char *of_path;
 	unsigned int of_binding;
 };
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/4] of: partitions: export of_fixup_partitions
  2020-11-25  5:20 [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali Sascha Hauer
  2020-11-25  5:20 ` [PATCH 1/4] mtd: Remove set but not used of_path Sascha Hauer
@ 2020-11-25  5:20 ` Sascha Hauer
  2020-11-25  5:20 ` [PATCH 3/4] mtd: Add hook to fix up kernel partitions Sascha Hauer
  2020-11-25  5:20 ` [PATCH 4/4] mtd: nand: denali: cope with kernel device trees without chip subnodes Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-11-25  5:20 UTC (permalink / raw)
  To: Barebox List

of_partitions_register_fixup() tries to automatically determine the
node to fixup. Sometimes this doesn't work, so add of_fixup_partitions()
that can called at fixup time with a device node determined by subsystem
or driver code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/partition.c | 37 +++++++++++++++++++++----------------
 include/of.h           |  6 ++++++
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 7367073c67..65c24c5426 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -123,20 +123,16 @@ static void delete_subnodes(struct device_node *np)
 	}
 }
 
-static int of_partition_fixup(struct device_node *root, void *ctx)
+int of_fixup_partitions(struct device_node *np, struct cdev *cdev)
 {
-	struct cdev *cdev = ctx, *partcdev;
-	struct device_node *np, *part, *partnode;
-	char *name;
+	struct cdev *partcdev;
+	struct device_node *part, *partnode;
 	int ret;
 	int n_cells, n_parts = 0;
 
 	if (of_partition_binding == MTD_OF_BINDING_DONTTOUCH)
 		return 0;
 
-	if (!cdev->device_node)
-		return -EINVAL;
-
 	list_for_each_entry(partcdev, &cdev->partitions, partition_entry) {
 		if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE)
 			continue;
@@ -151,15 +147,6 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 	else
 		n_cells = 1;
 
-	name = of_get_reproducible_name(cdev->device_node);
-	np = of_find_node_by_reproducible_name(root, name);
-	free(name);
-	if (!np) {
-		dev_err(cdev->dev, "Cannot find nodepath %s, cannot fixup\n",
-				cdev->device_node->full_name);
-		return -EINVAL;
-	}
-
 	partnode = of_get_child_by_name(np, "partitions");
 	if (partnode) {
 		if (of_partition_binding == MTD_OF_BINDING_LEGACY) {
@@ -242,6 +229,24 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 	return 0;
 }
 
+static int of_partition_fixup(struct device_node *root, void *ctx)
+{
+	struct cdev *cdev = ctx;
+	struct device_node *np;
+	char *name;
+
+	name = of_get_reproducible_name(cdev->device_node);
+	np = of_find_node_by_reproducible_name(root, name);
+	free(name);
+	if (!np) {
+		dev_err(cdev->dev, "Cannot find nodepath %s, cannot fixup\n",
+				cdev->device_node->full_name);
+		return -EINVAL;
+	}
+
+	return of_fixup_partitions(np, cdev);
+}
+
 int of_partitions_register_fixup(struct cdev *cdev)
 {
 	return of_register_fixup(of_partition_fixup, cdev);
diff --git a/include/of.h b/include/of.h
index 08a02e1105..aebd8384ad 100644
--- a/include/of.h
+++ b/include/of.h
@@ -275,6 +275,7 @@ extern struct device_d *of_device_enable_and_register_by_alias(
 
 struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node);
 int of_parse_partitions(struct cdev *cdev, struct device_node *node);
+int of_fixup_partitions(struct device_node *np, struct cdev *cdev);
 int of_partitions_register_fixup(struct cdev *cdev);
 int of_device_is_stdout_path(struct device_d *dev);
 const char *of_get_model(void);
@@ -303,6 +304,11 @@ static inline int of_parse_partitions(struct cdev *cdev,
 	return -EINVAL;
 }
 
+static inline int of_fixup_partitions(struct device_node *np, struct cdev *cdev)
+{
+	return -ENOSYS;
+}
+
 static inline int of_partitions_register_fixup(struct cdev *cdev)
 {
 	return -ENOSYS;
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/4] mtd: Add hook to fix up kernel partitions
  2020-11-25  5:20 [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali Sascha Hauer
  2020-11-25  5:20 ` [PATCH 1/4] mtd: Remove set but not used of_path Sascha Hauer
  2020-11-25  5:20 ` [PATCH 2/4] of: partitions: export of_fixup_partitions Sascha Hauer
@ 2020-11-25  5:20 ` Sascha Hauer
  2020-11-25  5:20 ` [PATCH 4/4] mtd: nand: denali: cope with kernel device trees without chip subnodes Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-11-25  5:20 UTC (permalink / raw)
  To: Barebox List

Some drivers have special requirements for fixing up the partition
nodes for the kernel. This adds a hook to struct mtd_info that can
be used by drivers to replace the generic fixup with a special one.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c      | 30 +++++++++++++++++++++++++++++-
 include/linux/mtd/mtd.h |  2 ++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index e21c71b816..af33ad665c 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -639,6 +639,34 @@ static int mtd_detect(struct device_d *dev)
 	return ret;
 }
 
+static int mtd_partition_fixup_generic(struct mtd_info *mtd, struct device_node *root)
+{
+	struct cdev *cdev = &mtd->cdev;
+	struct device_node *np, *mtdnp = mtd_get_of_node(mtd);
+	char *name;
+
+	name = of_get_reproducible_name(mtdnp);
+	np = of_find_node_by_reproducible_name(root, name);
+	free(name);
+	if (!np) {
+		dev_err(&mtd->dev, "Cannot find nodepath %s, cannot fixup\n",
+				mtdnp->full_name);
+		return -EINVAL;
+	}
+
+	return of_fixup_partitions(np, cdev);
+}
+
+static int mtd_partition_fixup(struct device_node *root, void *ctx)
+{
+	struct mtd_info *mtd = ctx;
+
+	if (mtd->of_fixup)
+		return mtd->of_fixup(mtd, root);
+
+	return mtd_partition_fixup_generic(mtd, root);
+}
+
 int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
 {
 	struct mtddev_hook *hook;
@@ -706,7 +734,7 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
 		dev_add_param_string(&mtd->dev, "partitions", mtd_partition_set, mtd_partition_get, &mtd->partition_string, mtd);
 		if (IS_ENABLED(CONFIG_OFDEVICE) && np) {
 			of_parse_partitions(&mtd->cdev, np);
-			ret = of_partitions_register_fixup(&mtd->cdev);
+			ret = of_register_fixup(mtd_partition_fixup, mtd);
 			if (ret)
 				goto err1;
 		}
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 0e2ff4526d..0d977fea25 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -206,6 +206,8 @@ struct mtd_info {
 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
 	int (*_block_markgood) (struct mtd_info *mtd, loff_t ofs);
 
+	int (*of_fixup)(struct mtd_info *mtd, struct device_node *root);
+
 	/* ECC status information */
 	struct mtd_ecc_stats ecc_stats;
 	/* Subpage shift (NAND) */
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/4] mtd: nand: denali: cope with kernel device trees without chip subnodes
  2020-11-25  5:20 [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali Sascha Hauer
                   ` (2 preceding siblings ...)
  2020-11-25  5:20 ` [PATCH 3/4] mtd: Add hook to fix up kernel partitions Sascha Hauer
@ 2020-11-25  5:20 ` Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-11-25  5:20 UTC (permalink / raw)
  To: Barebox List

The Denali binding for the Kernel has evolved over time. Recent Kernels
need NAND chip subnodes in the controller node which then hold the
partition nodes. Older Kernels need the partition nodes directly under
the controller node. Cope with both kernel types.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_denali_dt.c | 57 +++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/drivers/mtd/nand/nand_denali_dt.c b/drivers/mtd/nand/nand_denali_dt.c
index 877c40714a..8deea0292e 100644
--- a/drivers/mtd/nand/nand_denali_dt.c
+++ b/drivers/mtd/nand/nand_denali_dt.c
@@ -51,12 +51,65 @@ static const struct denali_dt_data denali_socfpga_data = {
 	.ecc_caps = &denali_socfpga_ecc_caps,
 };
 
+/*
+ * Older versions of the kernel driver require the partition nodes
+ * to be direct subnodes of the controller node. Starting with Kernel
+ * v5.2 (d8e8fd0ebf8b ("mtd: rawnand: denali: decouple controller and
+ * NAND chips")) the device node for the Denali controller is seen as a
+ * NAND controller node which has subnodes for each chip attached to that
+ * controller. The chip subnodes then hold the partitions. The barebox
+ * Denali driver also supports chip subnodes like the newer Kernel
+ * driver. To find the container node for the partitions we first try
+ * to find the chip subnodes in the Kernel device tree. Only if we
+ * can't find these we try the controller device node and put the
+ * partitions there.
+ * Note that we take the existence of the chip subnodes in the kernel
+ * device tree as a sign that we put the partitions there. When they
+ * don't exist we use the controller node. This means you have to make
+ * sure the chip subnodes exist when you start a Kernel that requires
+ * these. Beginning with Kernel v5.5 (f34a5072c465 ("mtd: rawnand: denali:
+ * remove the old unified controller/chip DT support")) the chip subnodes
+ * are mandatory for the Kernel.
+ */
+static int denali_partition_fixup(struct mtd_info *mtd, struct device_node *root)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct denali_controller *denali = container_of(chip->controller,
+							struct denali_controller,
+							controller);
+	struct device_node *np, *mtdnp = mtd_get_of_node(mtd);
+	char *name;
+
+	name = of_get_reproducible_name(mtdnp);
+	np = of_find_node_by_reproducible_name(root, name);
+	free(name);
+
+	if (np) {
+		dev_info(denali->dev, "Fixing up chip node %s\n",
+			 np->full_name);
+	} else {
+		name = of_get_reproducible_name(mtdnp->parent);
+		np = of_find_node_by_reproducible_name(root, name);
+		free(name);
+
+		if (np)
+			dev_info(denali->dev, "Fixing up controller node %s\n",
+				 np->full_name);
+	}
+
+	if (!np)
+		return -EINVAL;
+
+	return of_fixup_partitions(np, &mtd->cdev);
+}
+
 static int denali_dt_chip_init(struct denali_controller *denali,
 			       struct device_node *chip_np)
 {
 	struct denali_chip *dchip;
 	u32 bank;
 	int nsels, i, ret;
+	struct mtd_info *mtd;
 
 	nsels = of_property_count_elems_of_size(chip_np, "reg", sizeof(u32));
 	if (nsels < 0)
@@ -66,6 +119,10 @@ static int denali_dt_chip_init(struct denali_controller *denali,
 
 	dchip->nsels = nsels;
 
+	mtd = nand_to_mtd(&dchip->chip);
+
+	mtd->of_fixup = denali_partition_fixup;
+
 	for (i = 0; i < nsels; i++) {
 		ret = of_property_read_u32_index(chip_np, "reg", i, &bank);
 		if (ret)
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-25  5:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-25  5:20 [PATCH 0/4] mtd: nand: Add special fixup kernel partitions for Denali Sascha Hauer
2020-11-25  5:20 ` [PATCH 1/4] mtd: Remove set but not used of_path Sascha Hauer
2020-11-25  5:20 ` [PATCH 2/4] of: partitions: export of_fixup_partitions Sascha Hauer
2020-11-25  5:20 ` [PATCH 3/4] mtd: Add hook to fix up kernel partitions Sascha Hauer
2020-11-25  5:20 ` [PATCH 4/4] mtd: nand: denali: cope with kernel device trees without chip subnodes Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox