mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* OF partitions rework
@ 2017-03-31  5:33 Sascha Hauer
  2017-03-31  5:33 ` [PATCH 01/14] of: Add of_property_write_string() Sascha Hauer
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

This series reworks some aspects of device tree partitions.

- device tree partitions can be > 4GiB. So far we assumed
  #address-cells and #size-cells are both 1. Parse the
  cell size properly to support bigger partitions
- support the new device tree partition binding which collects
  the device tree partitions under a "partitions" node with
  compatible = "fixed-partitions"
- Add the counterpart of of_find_path(): of_find_node_by_devpath()
  converts a barebox device path back to a device node. This function
  will be used by the state framework in a later series.

----------------------------------------------------------------
Sascha Hauer (14):
      of: Add of_property_write_string()
      treewide: Use of_property_write_string() where appropriate
      of: partition: Move of_mtd_fixup to drivers/of/
      mtd: of: Make used partition binding configurable
      of: partition: support 64bit partition sizes
      mtd: partition: set cdev->offset to the actual offset
      cdev: Collect partitions on list
      of: partition: Make partition fixup independent from mtd devices
      fs: devfs-core: remove unused code
      fs: devfs-core: replace DEVFS_PARTITION_FIXED flag with pointer to the master cdev
      of: partition: only create partition node when partitions exist
      of: partitions: flag partitions from a partition table
      of: partition: Register the of partition fixup for of partition users
      of: of_path: add of_find_node_by_devpath()

 arch/arm/boards/highbank/init.c |   6 +-
 arch/arm/cpu/psci.c             |   6 +-
 arch/sandbox/board/hostfile.c   |   6 +-
 common/memory.c                 |   2 +-
 common/oftree.c                 |   2 +-
 common/partitions.c             |   2 +
 common/state/state.c            |   5 +-
 drivers/base/driver.c           |   2 +-
 drivers/eeprom/at24.c           |   1 +
 drivers/eeprom/at25.c           |   2 +
 drivers/mci/mci-core.c          |   4 +-
 drivers/mtd/core.c              |  65 +--------------
 drivers/mtd/partition.c         |   3 +
 drivers/of/base.c               |  24 +++++-
 drivers/of/of_path.c            | 107 +++++++++++++++++++++++++
 drivers/of/partition.c          | 170 +++++++++++++++++++++++++++++++++++++++-
 drivers/video/simplefb.c        |  12 +--
 fs/devfs-core.c                 |  82 +++----------------
 include/driver.h                |   4 +-
 include/linux/mtd/mtd.h         |   1 +
 include/of.h                    |  15 ++++
 21 files changed, 355 insertions(+), 166 deletions(-)

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

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

* [PATCH 01/14] of: Add of_property_write_string()
  2017-03-31  5:33 OF partitions rework Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 02/14] treewide: Use of_property_write_string() where appropriate Sascha Hauer
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Setting a property to a string is used many times. Create a convenience
function for it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 22 ++++++++++++++++++++++
 include/of.h      |  8 ++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index bef8f1de1a..01ab38907d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1217,6 +1217,28 @@ int of_property_write_u64_array(struct device_node *np,
 }
 
 /**
+ * of_property_write_string - Write a string to a property. If
+ * the property does not exist, it will be created and appended to the given
+ * device node.
+ *
+ * @np:		device node to which the property value is to be written.
+ * @propname:	name of the property to be written.
+ * value:	pointer to the string to write
+ *
+ * Search for a property in a device node and write a string to
+ * it. If the property does not exist, it will be created and appended to
+ * the device node. Returns 0 on success, -ENOMEM if the property or array
+ * of elements cannot be created.
+ */
+int of_property_write_string(struct device_node *np,
+			     const char *propname, const char *value)
+{
+	size_t len = strlen(value);
+
+	return of_set_property(np, propname, value, len + 1, 1);
+}
+
+/**
  * of_parse_phandle_from - Resolve a phandle property to a device_node pointer from
  * a given root node
  * @np: Pointer to device node holding phandle property
diff --git a/include/of.h b/include/of.h
index e3bb452b86..6bff13388d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -205,6 +205,8 @@ extern int of_property_write_u32_array(struct device_node *np,
 extern int of_property_write_u64_array(struct device_node *np,
 				const char *propname, const u64 *values,
 				size_t sz);
+extern int of_property_write_string(struct device_node *np, const char *propname,
+				    const char *value);
 
 extern struct device_node *of_parse_phandle(const struct device_node *np,
 					    const char *phandle_name,
@@ -466,6 +468,12 @@ static inline int of_property_write_u64_array(struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_property_write_string(struct device_node *np, const char *propname,
+				    const char *value)
+{
+	return -ENOSYS;
+}
+
 static inline struct device_node *of_parse_phandle(const struct device_node *np,
 					    const char *phandle_name, int index)
 {
-- 
2.11.0


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

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

* [PATCH 02/14] treewide: Use of_property_write_string() where appropriate
  2017-03-31  5:33 OF partitions rework Sascha Hauer
  2017-03-31  5:33 ` [PATCH 01/14] of: Add of_property_write_string() Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 03/14] of: partition: Move of_mtd_fixup to drivers/of/ Sascha Hauer
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Replace users which use of_set_property() to set a property to a string
with of_property_write_string().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/highbank/init.c |  6 ++----
 arch/arm/cpu/psci.c             |  6 ++----
 arch/sandbox/board/hostfile.c   |  6 ++----
 common/memory.c                 |  2 +-
 common/oftree.c                 |  2 +-
 common/state/state.c            |  5 ++---
 drivers/of/base.c               |  2 +-
 drivers/video/simplefb.c        | 12 ++++--------
 8 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/arch/arm/boards/highbank/init.c b/arch/arm/boards/highbank/init.c
index 577ccc0b74..32e217321a 100644
--- a/arch/arm/boards/highbank/init.c
+++ b/arch/arm/boards/highbank/init.c
@@ -37,14 +37,12 @@ static int hb_fixup(struct device_node *root, void *unused)
 
 	if (!(reg & HB_PWRDOM_STAT_SATA)) {
 		for_each_compatible_node_from(node, root, NULL, "calxeda,hb-ahci")
-			of_set_property(node, "status", "disabled",
-					sizeof("disabled"), 1);
+			of_property_write_string(node, "status", "disabled");
 	}
 
 	if (!(reg & HB_PWRDOM_STAT_EMMC)) {
 		for_each_compatible_node_from(node, root, NULL, "calxeda,hb-sdhci")
-			of_set_property(node, "status", "disabled",
-					sizeof("disabled"), 1);
+			of_property_write_string(node, "status", "disabled");
 	}
 
 	if ((opp_table[0] >> 16) != HB_OPP_VERSION)
diff --git a/arch/arm/cpu/psci.c b/arch/arm/cpu/psci.c
index d650c23ea2..eafb361a0a 100644
--- a/arch/arm/cpu/psci.c
+++ b/arch/arm/cpu/psci.c
@@ -204,13 +204,11 @@ static int of_psci_fixup(struct device_node *root, void *unused)
 	if (!psci)
 		return -EINVAL;
 
-	ret = of_set_property(psci, "compatible", "arm,psci-1.0",
-			strlen("arm,psci-1.0") + 1, 1);
+	ret = of_property_write_string(psci, "compatible", "arm,psci-1.0");
 	if (ret)
 		return ret;
 
-	ret = of_set_property(psci, "method", "smc",
-			strlen("smc") + 1, 1);
+	ret = of_property_write_string(psci, "method", "smc");
 	if (ret)
 		return ret;
 
diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index c1a2643bc7..e7d92ea031 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -133,8 +133,7 @@ static int of_hostfile_fixup(struct device_node *root, void *ctx)
 
 	node = of_new_node(root, hf->devname);
 
-	ret = of_set_property(node, "compatible", hostfile_dt_ids->compatible,
-			      strlen(hostfile_dt_ids->compatible) + 1, 1);
+	ret = of_property_write_string(node, "compatible", hostfile_dt_ids->compatible);
 	if (ret)
 		return ret;
 
@@ -146,8 +145,7 @@ static int of_hostfile_fixup(struct device_node *root, void *ctx)
 	if (ret)
 		return ret;
 
-	ret = of_set_property(node, "barebox,filename", hf->filename,
-			      strlen(hf->filename) + 1, 1);
+	ret = of_property_write_string(node, "barebox,filename", hf->filename);
 
 	return ret;
 }
diff --git a/common/memory.c b/common/memory.c
index ad38b00ecb..ff5bdc14e2 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -185,7 +185,7 @@ static int of_memory_fixup(struct device_node *node, void *unused)
 	if (!memnode)
 		return -ENOMEM;
 
-	err = of_set_property(memnode, "device_type", "memory", sizeof("memory"), 1);
+	err = of_property_write_string(memnode, "device_type", "memory");
 	if (err)
 		return err;
 
diff --git a/common/oftree.c b/common/oftree.c
index e98b908738..09a4455a9e 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -128,7 +128,7 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
 		return -ENOMEM;
 
 
-	err = of_set_property(node, "bootargs", str, strlen(str) + 1, 1);
+	err = of_property_write_string(node, "bootargs", str);
 
 	return err;
 }
diff --git a/common/state/state.c b/common/state/state.c
index 4020d5e1ea..02bb1bb24a 100644
--- a/common/state/state.c
+++ b/common/state/state.c
@@ -167,9 +167,8 @@ static int state_convert_node_variable(struct state *state,
 
 		if ((conv == STATE_CONVERT_TO_NODE)
 		    || (conv == STATE_CONVERT_FIXUP)) {
-			ret = of_set_property(new_node, "type",
-					      vtype->type_name,
-					      strlen(vtype->type_name) + 1, 1);
+			ret = of_property_write_string(new_node, "type",
+					      vtype->type_name);
 			if (ret)
 				goto out;
 
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 01ab38907d..6632f4d9dd 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2115,7 +2115,7 @@ int of_device_enable_path(const char *path)
  */
 int of_device_disable(struct device_node *node)
 {
-	return of_set_property(node, "status", "disabled", sizeof("disabled"), 1);
+	return of_property_write_string(node, "status", "disabled");
 }
 
 /**
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
index 357262988e..a2c59de364 100644
--- a/drivers/video/simplefb.c
+++ b/drivers/video/simplefb.c
@@ -89,9 +89,6 @@ static const struct simplefb_mode *simplefb_find_mode(const struct fb_info *fbi)
 static int simplefb_create_node(struct device_node *root,
 				const struct fb_info *fbi, const char *format)
 {
-	const char *compat = "simple-framebuffer";
-	const char *disabled = "disabled";
-	const char *okay = "okay";
 	struct device_node *node;
 	u32 cells[2];
 	int ret;
@@ -100,12 +97,11 @@ static int simplefb_create_node(struct device_node *root,
 	if (!node)
 		return -ENOMEM;
 
-	ret = of_set_property(node, "status", disabled,
-				strlen(disabled) + 1, 1);
+	ret = of_property_write_string(node, "status", "disabled");
 	if (ret < 0)
 		return ret;
 
-	ret = of_set_property(node, "compatible", compat, strlen(compat) + 1, 1);
+	ret = of_property_write_string(node, "compatible", "simple-framebuffer");
 	if (ret)
 		return ret;
 
@@ -130,14 +126,14 @@ static int simplefb_create_node(struct device_node *root,
 	if (ret < 0)
 		return ret;
 
-	ret = of_set_property(node, "format", format, strlen(format) + 1, 1);
+	ret = of_property_write_string(node, "format", format);
 	if (ret < 0)
 		return ret;
 
 	of_add_reserve_entry((u32)fbi->screen_base,
 			(u32)fbi->screen_base + fbi->screen_size);
 
-	return of_set_property(node, "status", okay, strlen(okay) + 1, 1);
+	return of_property_write_string(node, "status", "okay");
 }
 
 static int simplefb_of_fixup(struct device_node *root, void *ctx)
-- 
2.11.0


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

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

* [PATCH 03/14] of: partition: Move of_mtd_fixup to drivers/of/
  2017-03-31  5:33 OF partitions rework Sascha Hauer
  2017-03-31  5:33 ` [PATCH 01/14] of: Add of_property_write_string() Sascha Hauer
  2017-03-31  5:33 ` [PATCH 02/14] treewide: Use of_property_write_string() where appropriate Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 04/14] mtd: of: Make used partition binding configurable Sascha Hauer
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Move the fixup code where the parser code is already.
Since the code will not only be used for mtd in the future
drivers/of/ is a better place than drivers/mtd/.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c     | 65 +++--------------------------------------------
 drivers/of/partition.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of.h           |  6 +++++
 3 files changed, 78 insertions(+), 62 deletions(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 4e7bfdb3da..1eb8dd36d8 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -556,67 +556,6 @@ static int mtd_part_compare(struct list_head *a, struct list_head *b)
 	return 0;
 }
 
-static int of_mtd_fixup(struct device_node *root, void *ctx)
-{
-	struct mtd_info *mtd = ctx, *partmtd;
-	struct device_node *np, *part, *tmp;
-	int ret;
-
-	np = of_find_node_by_path_from(root, mtd->of_path);
-	if (!np) {
-		dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n",
-				mtd->of_path);
-		return -EINVAL;
-	}
-
-	for_each_child_of_node_safe(np, tmp, part) {
-		if (of_get_property(part, "compatible", NULL))
-			continue;
-		of_delete_node(part);
-	}
-
-	list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) {
-		int na, ns, len = 0;
-		char *name = basprintf("partition@%0llx",
-					 partmtd->master_offset);
-		void *p;
-		u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */
-
-		if (!name)
-			return -ENOMEM;
-
-		part = of_new_node(np, name);
-		free(name);
-		if (!part)
-			return -ENOMEM;
-
-		p = of_new_property(part, "label", partmtd->cdev.partname,
-                                strlen(partmtd->cdev.partname) + 1);
-		if (!p)
-			return -ENOMEM;
-
-		na = of_n_addr_cells(part);
-		ns = of_n_size_cells(part);
-
-		of_write_number(tmp + len, partmtd->master_offset, na);
-		len += na * 4;
-		of_write_number(tmp + len, partmtd->size, ns);
-		len += ns * 4;
-
-		ret = of_set_property(part, "reg", tmp, len, 1);
-		if (ret)
-			return ret;
-
-		if (partmtd->cdev.flags & DEVFS_PARTITION_READONLY) {
-			ret = of_set_property(part, "read-only", NULL, 0, 1);
-			if (ret)
-				return ret;
-		}
-	}
-
-	return 0;
-}
-
 static int mtd_detect(struct device_d *dev)
 {
 	struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
@@ -732,7 +671,9 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
 		if (IS_ENABLED(CONFIG_OFDEVICE) && mtd->parent->device_node) {
 			mtd->of_path = xstrdup(mtd->parent->device_node->full_name);
-			of_register_fixup(of_mtd_fixup, mtd);
+			ret = of_partitions_register_fixup(&mtd->cdev);
+			if (ret)
+				goto err1;
 		}
 	}
 
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 8c2aef2326..68f3812ed6 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -92,3 +92,72 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node)
 
 	return 0;
 }
+
+static int of_mtd_fixup(struct device_node *root, void *ctx)
+{
+	struct cdev *cdev = ctx;
+	struct mtd_info *mtd, *partmtd;
+	struct device_node *np, *part, *tmp;
+	int ret;
+
+	mtd = container_of(cdev, struct mtd_info, cdev);
+
+	np = of_find_node_by_path_from(root, mtd->of_path);
+	if (!np) {
+		dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n",
+				mtd->of_path);
+		return -EINVAL;
+	}
+
+	for_each_child_of_node_safe(np, tmp, part) {
+		if (of_get_property(part, "compatible", NULL))
+			continue;
+		of_delete_node(part);
+	}
+
+	list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) {
+		int na, ns, len = 0;
+		char *name = basprintf("partition@%0llx",
+					 partmtd->master_offset);
+		void *p;
+		u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */
+
+		if (!name)
+			return -ENOMEM;
+
+		part = of_new_node(np, name);
+		free(name);
+		if (!part)
+			return -ENOMEM;
+
+		p = of_new_property(part, "label", partmtd->cdev.partname,
+                                strlen(partmtd->cdev.partname) + 1);
+		if (!p)
+			return -ENOMEM;
+
+		na = of_n_addr_cells(part);
+		ns = of_n_size_cells(part);
+
+		of_write_number(tmp + len, partmtd->master_offset, na);
+		len += na * 4;
+		of_write_number(tmp + len, partmtd->size, ns);
+		len += ns * 4;
+
+		ret = of_set_property(part, "reg", tmp, len, 1);
+		if (ret)
+			return ret;
+
+		if (partmtd->cdev.flags & DEVFS_PARTITION_READONLY) {
+			ret = of_set_property(part, "read-only", NULL, 0, 1);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int of_partitions_register_fixup(struct cdev *cdev)
+{
+	return of_register_fixup(of_mtd_fixup, cdev);
+}
\ No newline at end of file
diff --git a/include/of.h b/include/of.h
index 6bff13388d..87d96055a2 100644
--- a/include/of.h
+++ b/include/of.h
@@ -240,6 +240,7 @@ extern struct device_d *of_device_enable_and_register_by_name(const char *name);
 
 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_partitions_register_fixup(struct cdev *cdev);
 int of_device_is_stdout_path(struct device_d *dev);
 const char *of_get_model(void);
 void *of_flatten_dtb(struct device_node *node);
@@ -264,6 +265,11 @@ static inline int of_parse_partitions(struct cdev *cdev,
 	return -EINVAL;
 }
 
+static inline int of_partitions_register_fixup(struct cdev *cdev)
+{
+	return -ENOSYS;
+}
+
 static inline int of_device_is_stdout_path(struct device_d *dev)
 {
 	return 0;
-- 
2.11.0


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

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

* [PATCH 04/14] mtd: of: Make used partition binding configurable
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (2 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 03/14] of: partition: Move of_mtd_fixup to drivers/of/ Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 05/14] of: partition: support 64bit partition sizes Sascha Hauer
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

So far we used the legacy partition binding when fixing up the
mtd partition nodes. Change this to default to the new binding
with a "partitions" submode. Make this behaviour configurable
though: This creates a new of_binding device variable for
mtd devices. This can be set to:

- "new": Use the new partition binding (default)
- "legacy": Use the old partition binding
- "donttouch": Do not touch the partition node

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/partition.c  | 84 ++++++++++++++++++++++++++++++++++++++++++++-----
 include/linux/mtd/mtd.h |  1 +
 2 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 68f3812ed6..f4d6c3322c 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -23,6 +23,16 @@
 #include <linux/mtd/mtd.h>
 #include <linux/err.h>
 #include <nand.h>
+#include <init.h>
+#include <globalvar.h>
+
+static unsigned int of_partition_binding;
+
+enum of_binding_name {
+	MTD_OF_BINDING_NEW,
+	MTD_OF_BINDING_LEGACY,
+	MTD_OF_BINDING_DONTTOUCH,
+};
 
 struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
 {
@@ -93,15 +103,36 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node)
 	return 0;
 }
 
+static void delete_subnodes(struct device_node *np)
+{
+	struct device_node *part, *tmp;
+
+	for_each_child_of_node_safe(np, tmp, part) {
+		if (of_get_property(part, "compatible", NULL))
+			continue;
+
+		of_delete_node(part);
+	}
+}
+
 static int of_mtd_fixup(struct device_node *root, void *ctx)
 {
 	struct cdev *cdev = ctx;
 	struct mtd_info *mtd, *partmtd;
-	struct device_node *np, *part, *tmp;
+	struct device_node *np, *part, *partnode;
 	int ret;
+	int n_cells;
 
 	mtd = container_of(cdev, struct mtd_info, cdev);
 
+	if (of_partition_binding == MTD_OF_BINDING_DONTTOUCH)
+		return 0;
+
+	if (mtd->size >= 0x100000000)
+		n_cells = 2;
+	else
+		n_cells = 1;
+
 	np = of_find_node_by_path_from(root, mtd->of_path);
 	if (!np) {
 		dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n",
@@ -109,12 +140,37 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 		return -EINVAL;
 	}
 
-	for_each_child_of_node_safe(np, tmp, part) {
-		if (of_get_property(part, "compatible", NULL))
-			continue;
-		of_delete_node(part);
+	partnode = of_get_child_by_name(np, "partitions");
+	if (partnode) {
+		if (of_partition_binding == MTD_OF_BINDING_LEGACY) {
+			of_delete_node(partnode);
+			partnode = np;
+		}
+		delete_subnodes(partnode);
+	} else {
+		delete_subnodes(np);
+
+		if (of_partition_binding == MTD_OF_BINDING_LEGACY)
+			partnode = np;
+		else
+			partnode = of_new_node(np, "partitions");
+	}
+
+	if (of_partition_binding == MTD_OF_BINDING_NEW) {
+		ret = of_property_write_string(partnode, "compatible",
+					       "fixed-partitions");
+		if (ret)
+			return ret;
 	}
 
+	of_property_write_u32(partnode, "#size-cells", n_cells);
+	if (ret)
+		return ret;
+
+	of_property_write_u32(partnode, "#addres-cells", n_cells);
+	if (ret)
+		return ret;
+
 	list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) {
 		int na, ns, len = 0;
 		char *name = basprintf("partition@%0llx",
@@ -125,7 +181,7 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 		if (!name)
 			return -ENOMEM;
 
-		part = of_new_node(np, name);
+		part = of_new_node(partnode, name);
 		free(name);
 		if (!part)
 			return -ENOMEM;
@@ -160,4 +216,18 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 int of_partitions_register_fixup(struct cdev *cdev)
 {
 	return of_register_fixup(of_mtd_fixup, cdev);
-}
\ No newline at end of file
+}
+
+static const char *of_binding_names[] = {
+	"new", "legacy", "donttouch"
+};
+
+static int of_partition_init(void)
+{
+	dev_add_param_enum(&global_device, "of_partition_binding", NULL, NULL,
+			   &of_partition_binding, of_binding_names,
+			   ARRAY_SIZE(of_binding_names), NULL);
+
+	return 0;
+}
+device_initcall(of_partition_init);
\ No newline at end of file
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index f93fac00f2..fa35c7ef39 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -228,6 +228,7 @@ struct mtd_info {
 	struct list_head partitions_entry;
 
 	char *of_path;
+	unsigned int of_binding;
 };
 
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
-- 
2.11.0


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

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

* [PATCH 05/14] of: partition: support 64bit partition sizes
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (3 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 04/14] mtd: of: Make used partition binding configurable Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset Sascha Hauer
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Do not assume that #address-cells and #size-cells are
both 1. Parse them appropriately to support devices
> 4GuB.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/partition.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index f4d6c3322c..30df6b32d1 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -40,10 +40,11 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
 	char *filename;
 	struct cdev *new;
 	const __be32 *reg;
-	unsigned long offset, size;
+	u64 offset, size;
 	const char *name;
 	int len;
 	unsigned long flags = 0;
+	int na, ns;
 
 	if (!node)
 		return NULL;
@@ -52,8 +53,16 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
 	if (!reg)
 		return NULL;
 
-	offset = be32_to_cpu(reg[0]);
-	size = be32_to_cpu(reg[1]);
+	na = of_n_addr_cells(node);
+	ns = of_n_size_cells(node);
+
+	if (len < (na + ns) * sizeof(__be32)) {
+		pr_err("reg property too small in %s\n", node->full_name);
+		return NULL;
+	}
+
+	offset = of_read_number(reg, na);
+	size = of_read_number(reg + na, ns);
 
 	partname = of_get_property(node, "label", &len);
 	if (!partname)
@@ -63,7 +72,7 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
 
 	name = (char *)partname;
 
-	debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdev->name, partname, offset, size);
+	debug("add partition: %s.%s 0x%08llx 0x%08llx\n", cdev->name, partname, offset, size);
 
 	if (of_get_property(node, "read-only", &len))
 		flags = DEVFS_PARTITION_READONLY;
-- 
2.11.0


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

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

* [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (4 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 05/14] of: partition: support 64bit partition sizes Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  8:46   ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 07/14] cdev: Collect partitions on list Sascha Hauer
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

cdev->offset is currently not used, but can be useful later when
we separate the of_partition_fixup from mtd, because then we will
need the offset of the partition.

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

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index 777cb758ce..745834384f 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -225,6 +225,8 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 	if (ret)
 		goto err;
 
+	part->cdev.offset = offset;
+
 	return part;
 err:
 	free(part->cdev.partname);
-- 
2.11.0


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

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

* [PATCH 07/14] cdev: Collect partitions on list
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (5 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 08/14] of: partition: Make partition fixup independent from mtd devices Sascha Hauer
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

We currently do not have a way to iterate over all partitions of
a cdev. Change this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/devfs-core.c  | 8 ++++++++
 include/driver.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 75ed3b0e66..c51ea6a871 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -277,6 +277,7 @@ int devfs_create(struct cdev *new)
 		return -EEXIST;
 
 	INIT_LIST_HEAD(&new->links);
+	INIT_LIST_HEAD(&new->partitions);
 
 	list_add_tail(&new->list, &cdev_list);
 	if (new->dev) {
@@ -326,6 +327,9 @@ int devfs_remove(struct cdev *cdev)
 	list_for_each_entry_safe(c, tmp, &cdev->links, link_entry)
 		devfs_remove(c);
 
+	if (cdev->master)
+		list_del(&cdev->partition_entry);
+
 	if (cdev->link)
 		free(cdev);
 
@@ -374,6 +378,8 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
 				partinfo->flags, partinfo->name);
 		if (IS_ERR(mtd))
 			return (void *)mtd;
+
+		list_add_tail(&mtd->cdev.partition_entry, &cdev->partitions);
 		return &mtd->cdev;
 	}
 
@@ -390,6 +396,8 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
 	new->dev = cdev->dev;
 	new->flags = partinfo->flags | DEVFS_IS_PARTITION;
 
+	list_add_tail(&new->partition_entry, &cdev->partitions);
+
 	devfs_create(new);
 
 	return new;
diff --git a/include/driver.h b/include/driver.h
index 6abaaad8b4..b7eaf290c4 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -459,6 +459,7 @@ struct cdev {
 	u8 dos_partition_type;
 	struct cdev *link;
 	struct list_head link_entry, links;
+	struct list_head partition_entry, partitions;
 };
 
 int devfs_create(struct cdev *);
-- 
2.11.0


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

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

* [PATCH 08/14] of: partition: Make partition fixup independent from mtd devices
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (6 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 07/14] cdev: Collect partitions on list Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 09/14] fs: devfs-core: remove unused code Sascha Hauer
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

The of partition parser is not only used for mtd device, but also
for regular block devices, so make the of_mtd_fixup code independent
of mtd devices also, so that other devices can be fixed up, too.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/partition.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 30df6b32d1..9b96a39edb 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -98,6 +98,8 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node)
 	if (!node)
 		return -EINVAL;
 
+	cdev->device_node = node;
+
 	subnode = of_get_child_by_name(node, "partitions");
 	if (subnode) {
 		if (!of_device_is_compatible(subnode, "fixed-partitions"))
@@ -124,28 +126,28 @@ static void delete_subnodes(struct device_node *np)
 	}
 }
 
-static int of_mtd_fixup(struct device_node *root, void *ctx)
+static int of_partition_fixup(struct device_node *root, void *ctx)
 {
-	struct cdev *cdev = ctx;
-	struct mtd_info *mtd, *partmtd;
+	struct cdev *cdev = ctx, *partcdev;
 	struct device_node *np, *part, *partnode;
 	int ret;
 	int n_cells;
 
-	mtd = container_of(cdev, struct mtd_info, cdev);
-
 	if (of_partition_binding == MTD_OF_BINDING_DONTTOUCH)
 		return 0;
 
-	if (mtd->size >= 0x100000000)
+	if (!cdev->device_node)
+		return -EINVAL;
+
+	if (cdev->size >= 0x100000000)
 		n_cells = 2;
 	else
 		n_cells = 1;
 
-	np = of_find_node_by_path_from(root, mtd->of_path);
+	np = of_find_node_by_path_from(root, cdev->device_node->full_name);
 	if (!np) {
-		dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n",
-				mtd->of_path);
+		dev_err(cdev->dev, "Cannot find nodepath %s, cannot fixup\n",
+				cdev->device_node->full_name);
 		return -EINVAL;
 	}
 
@@ -180,10 +182,10 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 	if (ret)
 		return ret;
 
-	list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) {
+	list_for_each_entry(partcdev, &cdev->partitions, partition_entry) {
 		int na, ns, len = 0;
 		char *name = basprintf("partition@%0llx",
-					 partmtd->master_offset);
+					 partcdev->offset);
 		void *p;
 		u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */
 
@@ -195,24 +197,24 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 		if (!part)
 			return -ENOMEM;
 
-		p = of_new_property(part, "label", partmtd->cdev.partname,
-                                strlen(partmtd->cdev.partname) + 1);
+		p = of_new_property(part, "label", partcdev->partname,
+                                strlen(partcdev->partname) + 1);
 		if (!p)
 			return -ENOMEM;
 
 		na = of_n_addr_cells(part);
 		ns = of_n_size_cells(part);
 
-		of_write_number(tmp + len, partmtd->master_offset, na);
+		of_write_number(tmp + len, partcdev->offset, na);
 		len += na * 4;
-		of_write_number(tmp + len, partmtd->size, ns);
+		of_write_number(tmp + len, partcdev->size, ns);
 		len += ns * 4;
 
 		ret = of_set_property(part, "reg", tmp, len, 1);
 		if (ret)
 			return ret;
 
-		if (partmtd->cdev.flags & DEVFS_PARTITION_READONLY) {
+		if (partcdev->flags & DEVFS_PARTITION_READONLY) {
 			ret = of_set_property(part, "read-only", NULL, 0, 1);
 			if (ret)
 				return ret;
@@ -224,7 +226,7 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
 
 int of_partitions_register_fixup(struct cdev *cdev)
 {
-	return of_register_fixup(of_mtd_fixup, cdev);
+	return of_register_fixup(of_partition_fixup, cdev);
 }
 
 static const char *of_binding_names[] = {
-- 
2.11.0


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

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

* [PATCH 09/14] fs: devfs-core: remove unused code
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (7 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 08/14] of: partition: Make partition fixup independent from mtd devices Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 10/14] fs: devfs-core: replace DEVFS_PARTITION_FIXED flag with pointer to the master cdev Sascha Hauer
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Partitions on mtd devices are implemented as mtd devices themselves
which have a ioctl hook. The DEVFS_IS_PARTITION flag is never set
for these devices, so the partition offset translation code in
fs/devfs-core.c is unused. Remove it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/devfs-core.c | 68 ---------------------------------------------------------
 1 file changed, 68 deletions(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index c51ea6a871..7b3754ed8e 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -184,76 +184,8 @@ int cdev_flush(struct cdev *cdev)
 	return cdev->ops->flush(cdev);
 }
 
-static int partition_ioctl(struct cdev *cdev, int request, void *buf)
-{
-	int ret = 0;
-	loff_t offset, *_buf = buf;
-	struct mtd_info_user *user = buf;
-
-	switch (request) {
-	case MEMSETBADBLOCK:
-	case MEMSETGOODBLOCK:
-	case MEMGETBADBLOCK:
-		offset = *_buf;
-		offset += cdev->offset;
-		ret = cdev->ops->ioctl(cdev, request, &offset);
-		break;
-	case MEMGETINFO:
-		if (cdev->mtd) {
-			user->type	= cdev->mtd->type;
-			user->flags	= cdev->mtd->flags;
-			user->size	= cdev->mtd->size;
-			user->erasesize	= cdev->mtd->erasesize;
-			user->writesize	= cdev->mtd->writesize;
-			user->oobsize	= cdev->mtd->oobsize;
-			user->subpagesize = cdev->mtd->writesize >> cdev->mtd->subpage_sft;
-			user->mtd	= cdev->mtd;
-			/* The below fields are obsolete */
-			user->ecctype	= -1;
-			user->eccsize	= 0;
-			break;
-		}
-		if (!cdev->ops->ioctl) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = cdev->ops->ioctl(cdev, request, buf);
-		break;
-#if (defined(CONFIG_NAND_ECC_HW) || defined(CONFIG_NAND_ECC_SOFT))
-	case ECCGETSTATS:
-#endif
-	case MEMERASE:
-		if (!cdev->ops->ioctl) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = cdev->ops->ioctl(cdev, request, buf);
-		break;
-#ifdef CONFIG_PARTITION
-	case MEMGETREGIONINFO:
-		if (cdev->mtd) {
-			struct region_info_user *reg = buf;
-			int erasesize_shift = ffs(cdev->mtd->erasesize) - 1;
-
-			reg->offset = cdev->offset;
-			reg->erasesize = cdev->mtd->erasesize;
-			reg->numblocks = cdev->size >> erasesize_shift;
-			reg->regionindex = cdev->mtd->index;
-		}
-	break;
-#endif
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
 int cdev_ioctl(struct cdev *cdev, int request, void *buf)
 {
-	if (cdev->flags & DEVFS_IS_PARTITION)
-		return partition_ioctl(cdev, request, buf);
-
 	if (!cdev->ops->ioctl)
 		return -EINVAL;
 
-- 
2.11.0


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

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

* [PATCH 10/14] fs: devfs-core: replace DEVFS_PARTITION_FIXED flag with pointer to the master cdev
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (8 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 09/14] fs: devfs-core: remove unused code Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 11/14] of: partition: only create partition node when partitions exist Sascha Hauer
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

Instead of having a flag indicating a cdev is a partition on
some master cdev, just add a master pointer to the cdev, so
that we can also find out who the master is.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/base/driver.c   | 2 +-
 drivers/mtd/partition.c | 1 +
 fs/devfs-core.c         | 6 +++---
 include/driver.h        | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 5867fe45d0..83260990af 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -221,7 +221,7 @@ int unregister_device(struct device_d *old_dev)
 	}
 
 	list_for_each_entry_safe(cdev, ct, &old_dev->cdevs, devices_list) {
-		if (cdev->flags & DEVFS_IS_PARTITION) {
+		if (cdev->master) {
 			dev_dbg(old_dev, "unregister part %s\n", cdev->name);
 			devfs_del_partition(cdev->name);
 		}
diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index 745834384f..2bdbef9227 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -226,6 +226,7 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 		goto err;
 
 	part->cdev.offset = offset;
+	part->cdev.master = &part->master->cdev;
 
 	return part;
 err:
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 7b3754ed8e..382606f1cf 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -37,7 +37,7 @@ int devfs_partition_complete(struct string_list *sl, char *instr)
 	len = strlen(instr);
 
 	list_for_each_entry(cdev, &cdev_list, list) {
-		if (cdev->flags & DEVFS_IS_PARTITION &&
+		if (cdev->master &&
 		    !strncmp(instr, cdev->name, len)) {
 			string_list_add_asprintf(sl, "%s ", cdev->name);
 		}
@@ -326,7 +326,7 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
 	new->offset = cdev->offset + offset;
 
 	new->dev = cdev->dev;
-	new->flags = partinfo->flags | DEVFS_IS_PARTITION;
+	new->master = cdev;
 
 	list_add_tail(&new->partition_entry, &cdev->partitions);
 
@@ -368,7 +368,7 @@ int devfs_del_partition(const char *name)
 		return ret;
 	}
 
-	if (!(cdev->flags & DEVFS_IS_PARTITION))
+	if (!cdev->master)
 		return -EINVAL;
 	if (cdev->flags & DEVFS_PARTITION_FIXED)
 		return -EPERM;
diff --git a/include/driver.h b/include/driver.h
index b7eaf290c4..2af66fe345 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -460,6 +460,7 @@ struct cdev {
 	struct cdev *link;
 	struct list_head link_entry, links;
 	struct list_head partition_entry, partitions;
+	struct cdev *master;
 };
 
 int devfs_create(struct cdev *);
@@ -482,7 +483,6 @@ int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset);
 
 #define DEVFS_PARTITION_FIXED		(1U << 0)
 #define DEVFS_PARTITION_READONLY	(1U << 1)
-#define DEVFS_IS_PARTITION		(1 << 2)
 #define DEVFS_IS_CHARACTER_DEV		(1 << 3)
 
 struct cdev *devfs_add_partition(const char *devname, loff_t offset,
-- 
2.11.0


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

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

* [PATCH 11/14] of: partition: only create partition node when partitions exist
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (9 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 10/14] fs: devfs-core: replace DEVFS_PARTITION_FIXED flag with pointer to the master cdev Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 12/14] of: partitions: flag partitions from a partition table Sascha Hauer
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

With the legacy partition binding we did not modify the device
node when no partition exist, but with the new binding we would
create the "partitions" node with compatible = "fixed-partitions".
Prevent that by catching the absence of partitions early.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/partition.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 9b96a39edb..2e2ba35e87 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -131,7 +131,7 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 	struct cdev *cdev = ctx, *partcdev;
 	struct device_node *np, *part, *partnode;
 	int ret;
-	int n_cells;
+	int n_cells, n_parts = 0;
 
 	if (of_partition_binding == MTD_OF_BINDING_DONTTOUCH)
 		return 0;
@@ -139,6 +139,13 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 	if (!cdev->device_node)
 		return -EINVAL;
 
+	list_for_each_entry(partcdev, &cdev->partitions, partition_entry) {
+		n_parts++;
+	}
+
+	if (!n_parts)
+		return 0;
+
 	if (cdev->size >= 0x100000000)
 		n_cells = 2;
 	else
-- 
2.11.0


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

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

* [PATCH 12/14] of: partitions: flag partitions from a partition table
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (10 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 11/14] of: partition: only create partition node when partitions exist Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 13/14] of: partition: Register the of partition fixup for of partition users Sascha Hauer
  2017-03-31  5:33 ` [PATCH 14/14] of: of_path: add of_find_node_by_devpath() Sascha Hauer
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

We are going to call the of_partition_fixup for regular block
devices like MMC/SD aswell. Add a flag to partitions indicating
they are instanciated from a on-disk partition table so that they
won't be added as device tree partitions during fixup.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/partitions.c    | 2 ++
 drivers/of/partition.c | 9 +++++++--
 include/driver.h       | 1 +
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index 69a2b1fefb..574b31fbbe 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -63,6 +63,8 @@ static int register_one_partition(struct block_device *blk,
 		goto out;
 	}
 
+	cdev->flags |= DEVFS_PARTITION_FROM_TABLE;
+
 	cdev->dos_partition_type = part->dos_partition_type;
 	strcpy(cdev->partuuid, part->partuuid);
 
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 2e2ba35e87..f180f33c1a 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -140,6 +140,8 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 		return -EINVAL;
 
 	list_for_each_entry(partcdev, &cdev->partitions, partition_entry) {
+		if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE)
+			continue;
 		n_parts++;
 	}
 
@@ -191,11 +193,14 @@ static int of_partition_fixup(struct device_node *root, void *ctx)
 
 	list_for_each_entry(partcdev, &cdev->partitions, partition_entry) {
 		int na, ns, len = 0;
-		char *name = basprintf("partition@%0llx",
-					 partcdev->offset);
+		char *name;
 		void *p;
 		u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */
 
+		if (partcdev->flags & DEVFS_PARTITION_FROM_TABLE)
+			continue;
+
+		name = basprintf("partition@%0llx", partcdev->offset);
 		if (!name)
 			return -ENOMEM;
 
diff --git a/include/driver.h b/include/driver.h
index 2af66fe345..52e06f7d62 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -484,6 +484,7 @@ int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset);
 #define DEVFS_PARTITION_FIXED		(1U << 0)
 #define DEVFS_PARTITION_READONLY	(1U << 1)
 #define DEVFS_IS_CHARACTER_DEV		(1 << 3)
+#define DEVFS_PARTITION_FROM_TABLE	(1 << 4)
 
 struct cdev *devfs_add_partition(const char *devname, loff_t offset,
 		loff_t size, unsigned int flags, const char *name);
-- 
2.11.0


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

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

* [PATCH 13/14] of: partition: Register the of partition fixup for of partition users
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (11 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 12/14] of: partitions: flag partitions from a partition table Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  2017-03-31  5:33 ` [PATCH 14/14] of: of_path: add of_find_node_by_devpath() Sascha Hauer
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

at24, at25 and mci core are using of_parse_partitions(). Register the
fixup for them aswell.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/eeprom/at24.c  | 1 +
 drivers/eeprom/at25.c  | 2 ++
 drivers/mci/mci-core.c | 4 +++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index 4ae3776554..1227286fbe 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -500,6 +500,7 @@ static int at24_probe(struct device_d *dev)
 		goto err_devfs_create;
 
 	of_parse_partitions(&at24->cdev, dev->device_node);
+	of_partitions_register_fixup(&at24->cdev);
 
 	return 0;
 
diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
index f7f8368c4b..1caaebd371 100644
--- a/drivers/eeprom/at25.c
+++ b/drivers/eeprom/at25.c
@@ -360,6 +360,8 @@ static int at25_probe(struct device_d *dev)
 
 	dev_dbg(dev, "%s probed\n", at25->cdev.name);
 	of_parse_partitions(&at25->cdev, dev->device_node);
+	of_partitions_register_fixup(&at25->cdev);
+
 	return 0;
 
 fail:
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 055a5e2b06..6ad0f48ec3 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1621,8 +1621,10 @@ static int mci_register_partition(struct mci_part *part)
 		rc = 0; /* it's not a failure */
 	}
 
-	if (np)
+	if (np) {
 		of_parse_partitions(&part->blk.cdev, np);
+		of_partitions_register_fixup(&part->blk.cdev);
+	}
 
 	return 0;
 }
-- 
2.11.0


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

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

* [PATCH 14/14] of: of_path: add of_find_node_by_devpath()
  2017-03-31  5:33 OF partitions rework Sascha Hauer
                   ` (12 preceding siblings ...)
  2017-03-31  5:33 ` [PATCH 13/14] of: partition: Register the of partition fixup for of partition users Sascha Hauer
@ 2017-03-31  5:33 ` Sascha Hauer
  13 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  5:33 UTC (permalink / raw)
  To: Barebox List

We already have of_find_path_by_node() which finds a device path
for a given device node. This is used by the state framework to
find its backend path. This path has to be translated back to
a device node when Linux is started. The current approach turned
out to be too simple: We assumed that the node path is the same
in the tree Linux is started with. This is not true in several
cases:
- partition nodes should have the name "partition@<offset>", but
  in several trees they have "partition@<num>"
- There are two different partition bindings: The legacy binding
  and the new one with an additional partitions subnode which has
  a compatible = "fixed-partitions" property.
The node path only stays the same when the internal tree uses the
same bindings and node names as the tree Linux is started with.

To overcome this limitation we create of_find_node_by_devpath()
which converts the device path back to a device node. It does
so by finding the device node of the hardware device rather than
the partition node. It then parses over the partitions in this
device node with the known bindings looking for a partition which
matches in offset and size to the barebox partition.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/of_path.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of.h         |   1 +
 2 files changed, 108 insertions(+)

diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
index e0b2dc1247..a5886dffac 100644
--- a/drivers/of/of_path.c
+++ b/drivers/of/of_path.c
@@ -104,6 +104,113 @@ int of_find_path_by_node(struct device_node *node, char **outpath, unsigned flag
 }
 
 /**
+ * of_find_node_by_devpath - translate a device path to a device tree node
+ *
+ * @root: The device tree root. Can be NULL, in this case the internal tree is used
+ * @path: The path to look the node up for. Can be "/dev/cdevname" or "cdevname" directly.
+ *
+ * This is the counterpart of of_find_path_by_node(). Given a path this function tries
+ * to find the corresponding node in the given device tree.
+ *
+ * We first have to find the hardware device in the tree we are passed and then find
+ * a partition matching offset/size in this tree. This is necessary because the
+ * passed tree may use another partition binding (legacy vs. fixed-partitions). Also
+ * the node names may differ (some device trees have partition@<num> instead of
+ * partition@<offset>.
+ */
+struct device_node *of_find_node_by_devpath(struct device_node *root, const char *path)
+{
+	struct cdev *cdev;
+	bool is_partition = false;
+	struct device_node *np, *partnode, *rnp;
+	loff_t part_offset = 0, part_size = 0;
+
+	pr_debug("%s: looking for path %s\n", __func__, path);
+
+	if (!strncmp(path, "/dev/", 5))
+		path += 5;
+
+	cdev = cdev_by_name(path);
+	if (!cdev) {
+		pr_debug("%s: cdev %s not found\n", __func__, path);
+		return NULL;
+	}
+
+	/*
+	 * Look for the device node of the master device (the one of_parse_partitions() has
+	 * been called with
+	 */
+	if (cdev->master) {
+		is_partition = true;
+		part_offset = cdev->offset;
+		part_size = cdev->size;
+		pr_debug("%s path %s: is a partition with offset 0x%08llx, size 0x%08llx\n",
+			 __func__, path, part_offset, part_size);
+		np = cdev->master->device_node;
+	} else {
+		np = cdev->device_node;
+	}
+
+	/*
+	 * Now find the device node of the master device in the device tree we have
+	 * been passed.
+	 */
+	rnp = of_find_node_by_path_from(root, np->full_name);
+	if (!rnp) {
+		pr_debug("%s path %s: %s not found in passed tree\n", __func__, path,
+			np->full_name);
+		return NULL;
+	}
+
+	if (!is_partition) {
+		pr_debug("%s path %s: returning full device node %s\n", __func__, path,
+			rnp->full_name);
+		return rnp;
+	}
+
+	/*
+	 * Look for a partition with matching offset/size in the device node of
+	 * the tree we have been passed.
+	 */
+	partnode = of_get_child_by_name(rnp, "partitions");
+	if (!partnode) {
+		pr_debug("%s path %s: using legacy partition binding\n", __func__, path);
+		partnode = rnp;
+	}
+
+	for_each_child_of_node(partnode, np) {
+		const __be32 *reg;
+		int na, ns, len;
+		loff_t offset, size;
+
+		reg = of_get_property(np, "reg", &len);
+		if (!reg)
+			return NULL;
+
+		na = of_n_addr_cells(np);
+		ns = of_n_size_cells(np);
+
+		if (len < (na + ns) * sizeof(__be32)) {
+			pr_err("reg property too small in %s\n", np->full_name);
+			continue;
+		}
+
+		offset = of_read_number(reg, na);
+		size = of_read_number(reg + na, ns);
+
+		if (part_offset == offset && part_size == size) {
+			pr_debug("%s path %s: found matching partition in %s\n", __func__, path,
+				np->full_name);
+			return np;
+		}
+	}
+
+	pr_debug("%s path %s: no matching node found\n", __func__, path);
+
+	return NULL;
+}
+
+/**
  * of_find_path - translate a path description in the devicetree to a barebox
  *                path
  *
diff --git a/include/of.h b/include/of.h
index 87d96055a2..0ba73f197f 100644
--- a/include/of.h
+++ b/include/of.h
@@ -251,6 +251,7 @@ struct device_d *of_find_device_by_node_path(const char *path);
 #define OF_FIND_PATH_FLAGS_BB 1		/* return .bb device if available */
 int of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags);
 int of_find_path_by_node(struct device_node *node, char **outpath, unsigned flags);
+struct device_node *of_find_node_by_devpath(struct device_node *root, const char *path);
 int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context);
 int of_unregister_fixup(int (*fixup)(struct device_node *, void *), void *context);
 int of_register_set_status_fixup(const char *node, bool status);
-- 
2.11.0


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

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

* Re: [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset
  2017-03-31  5:33 ` [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset Sascha Hauer
@ 2017-03-31  8:46   ` Sascha Hauer
  0 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2017-03-31  8:46 UTC (permalink / raw)
  To: Barebox List

On Fri, Mar 31, 2017 at 07:33:15AM +0200, Sascha Hauer wrote:
> cdev->offset is currently not used, but can be useful later when
> we separate the of_partition_fixup from mtd, because then we will
> need the offset of the partition.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/partition.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
> index 777cb758ce..745834384f 100644
> --- a/drivers/mtd/partition.c
> +++ b/drivers/mtd/partition.c
> @@ -225,6 +225,8 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
>  	if (ret)
>  		goto err;
>  
> +	part->cdev.offset = offset;
> +

Nah, this does not work. Will drop this one.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

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

end of thread, other threads:[~2017-03-31  8:46 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-31  5:33 OF partitions rework Sascha Hauer
2017-03-31  5:33 ` [PATCH 01/14] of: Add of_property_write_string() Sascha Hauer
2017-03-31  5:33 ` [PATCH 02/14] treewide: Use of_property_write_string() where appropriate Sascha Hauer
2017-03-31  5:33 ` [PATCH 03/14] of: partition: Move of_mtd_fixup to drivers/of/ Sascha Hauer
2017-03-31  5:33 ` [PATCH 04/14] mtd: of: Make used partition binding configurable Sascha Hauer
2017-03-31  5:33 ` [PATCH 05/14] of: partition: support 64bit partition sizes Sascha Hauer
2017-03-31  5:33 ` [PATCH 06/14] mtd: partition: set cdev->offset to the actual offset Sascha Hauer
2017-03-31  8:46   ` Sascha Hauer
2017-03-31  5:33 ` [PATCH 07/14] cdev: Collect partitions on list Sascha Hauer
2017-03-31  5:33 ` [PATCH 08/14] of: partition: Make partition fixup independent from mtd devices Sascha Hauer
2017-03-31  5:33 ` [PATCH 09/14] fs: devfs-core: remove unused code Sascha Hauer
2017-03-31  5:33 ` [PATCH 10/14] fs: devfs-core: replace DEVFS_PARTITION_FIXED flag with pointer to the master cdev Sascha Hauer
2017-03-31  5:33 ` [PATCH 11/14] of: partition: only create partition node when partitions exist Sascha Hauer
2017-03-31  5:33 ` [PATCH 12/14] of: partitions: flag partitions from a partition table Sascha Hauer
2017-03-31  5:33 ` [PATCH 13/14] of: partition: Register the of partition fixup for of partition users Sascha Hauer
2017-03-31  5:33 ` [PATCH 14/14] of: of_path: add of_find_node_by_devpath() Sascha Hauer

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