bcm4908: add pending mtd patches for BCM4908 partitioning
BCM4908 can have multiple firmware partitions. MTD needs to detect which one is currently used. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		@@ -0,0 +1,113 @@
 | 
			
		||||
From 4fdbaa5a3dbe761b231c13feaa53242aae3306cc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Fri, 15 Jan 2021 15:23:02 +0100
 | 
			
		||||
Subject: [PATCH 1/3] dt-bindings: mtd: move partition binding to its own file
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Single partition binding is quite common and may be:
 | 
			
		||||
1. Used by multiple parsers
 | 
			
		||||
2. Extended for more specific cases
 | 
			
		||||
 | 
			
		||||
Move it to separated file to avoid code duplication.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
---
 | 
			
		||||
 .../mtd/partitions/fixed-partitions.yaml      | 33 +------------
 | 
			
		||||
 .../bindings/mtd/partitions/partition.yaml    | 47 +++++++++++++++++++
 | 
			
		||||
 2 files changed, 48 insertions(+), 32 deletions(-)
 | 
			
		||||
 create mode 100644 Documentation/devicetree/bindings/mtd/partitions/partition.yaml
 | 
			
		||||
 | 
			
		||||
--- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | 
			
		||||
+++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | 
			
		||||
@@ -27,38 +27,7 @@ properties:
 | 
			
		||||
 
 | 
			
		||||
 patternProperties:
 | 
			
		||||
   "@[0-9a-f]+$":
 | 
			
		||||
-    description: node describing a single flash partition
 | 
			
		||||
-    type: object
 | 
			
		||||
-
 | 
			
		||||
-    properties:
 | 
			
		||||
-      reg:
 | 
			
		||||
-        description: partition's offset and size within the flash
 | 
			
		||||
-        maxItems: 1
 | 
			
		||||
-
 | 
			
		||||
-      label:
 | 
			
		||||
-        description: The label / name for this partition. If omitted, the label
 | 
			
		||||
-          is taken from the node name (excluding the unit address).
 | 
			
		||||
-
 | 
			
		||||
-      read-only:
 | 
			
		||||
-        description: This parameter, if present, is a hint that this partition
 | 
			
		||||
-          should only be mounted read-only. This is usually used for flash
 | 
			
		||||
-          partitions containing early-boot firmware images or data which should
 | 
			
		||||
-          not be clobbered.
 | 
			
		||||
-        type: boolean
 | 
			
		||||
-
 | 
			
		||||
-      lock:
 | 
			
		||||
-        description: Do not unlock the partition at initialization time (not
 | 
			
		||||
-          supported on all devices)
 | 
			
		||||
-        type: boolean
 | 
			
		||||
-
 | 
			
		||||
-      slc-mode:
 | 
			
		||||
-        description: This parameter, if present, allows one to emulate SLC mode
 | 
			
		||||
-          on a partition attached to an MLC NAND thus making this partition
 | 
			
		||||
-          immune to paired-pages corruptions
 | 
			
		||||
-        type: boolean
 | 
			
		||||
-
 | 
			
		||||
-    required:
 | 
			
		||||
-      - reg
 | 
			
		||||
+    $ref: "partition.yaml#"
 | 
			
		||||
 
 | 
			
		||||
 required:
 | 
			
		||||
   - "#address-cells"
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml
 | 
			
		||||
@@ -0,0 +1,47 @@
 | 
			
		||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | 
			
		||||
+%YAML 1.2
 | 
			
		||||
+---
 | 
			
		||||
+$id: http://devicetree.org/schemas/mtd/partitions/partition.yaml#
 | 
			
		||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 | 
			
		||||
+
 | 
			
		||||
+title: Partition
 | 
			
		||||
+
 | 
			
		||||
+description: |
 | 
			
		||||
+  This binding describes a single flash partition. Each partition must have its
 | 
			
		||||
+  relative offset and size specified. Depending on partition function extra
 | 
			
		||||
+  properties can be used.
 | 
			
		||||
+
 | 
			
		||||
+maintainers:
 | 
			
		||||
+  - Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
+
 | 
			
		||||
+properties:
 | 
			
		||||
+  reg:
 | 
			
		||||
+    description: partition's offset and size within the flash
 | 
			
		||||
+    maxItems: 1
 | 
			
		||||
+
 | 
			
		||||
+  label:
 | 
			
		||||
+    description: The label / name for this partition. If omitted, the label
 | 
			
		||||
+      is taken from the node name (excluding the unit address).
 | 
			
		||||
+
 | 
			
		||||
+  read-only:
 | 
			
		||||
+    description: This parameter, if present, is a hint that this partition
 | 
			
		||||
+      should only be mounted read-only. This is usually used for flash
 | 
			
		||||
+      partitions containing early-boot firmware images or data which should
 | 
			
		||||
+      not be clobbered.
 | 
			
		||||
+    type: boolean
 | 
			
		||||
+
 | 
			
		||||
+  lock:
 | 
			
		||||
+    description: Do not unlock the partition at initialization time (not
 | 
			
		||||
+      supported on all devices)
 | 
			
		||||
+    type: boolean
 | 
			
		||||
+
 | 
			
		||||
+  slc-mode:
 | 
			
		||||
+    description: This parameter, if present, allows one to emulate SLC mode
 | 
			
		||||
+      on a partition attached to an MLC NAND thus making this partition
 | 
			
		||||
+      immune to paired-pages corruptions
 | 
			
		||||
+    type: boolean
 | 
			
		||||
+
 | 
			
		||||
+required:
 | 
			
		||||
+  - reg
 | 
			
		||||
+
 | 
			
		||||
+additionalProperties: true
 | 
			
		||||
@@ -0,0 +1,89 @@
 | 
			
		||||
From 4f740351484e88bcea3776578288b6ec400829c8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Fri, 15 Jan 2021 16:01:04 +0100
 | 
			
		||||
Subject: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
BCM4908 uses fixed partitions layout but function of some partitions may
 | 
			
		||||
vary. Some devices use multiple firmware partitions and those should be
 | 
			
		||||
marked to let system discover their purpose.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
---
 | 
			
		||||
 .../partitions/brcm,bcm4908-partitions.yaml   | 68 +++++++++++++++++++
 | 
			
		||||
 1 file changed, 68 insertions(+)
 | 
			
		||||
 create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
 | 
			
		||||
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
 | 
			
		||||
@@ -0,0 +1,68 @@
 | 
			
		||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | 
			
		||||
+%YAML 1.2
 | 
			
		||||
+---
 | 
			
		||||
+$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm4908-partitions.yaml#
 | 
			
		||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 | 
			
		||||
+
 | 
			
		||||
+title: Broadcom BCM4908 partitioning
 | 
			
		||||
+
 | 
			
		||||
+description: |
 | 
			
		||||
+  Broadcom BCM4908 CFE bootloader supports two firmware partitions. One is used
 | 
			
		||||
+  for regular booting, the other is treated as fallback.
 | 
			
		||||
+
 | 
			
		||||
+  This binding allows defining all fixed partitions and marking those containing
 | 
			
		||||
+  firmware. System can use that information e.g. for booting or flashing
 | 
			
		||||
+  purposes.
 | 
			
		||||
+
 | 
			
		||||
+maintainers:
 | 
			
		||||
+  - Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
+
 | 
			
		||||
+properties:
 | 
			
		||||
+  compatible:
 | 
			
		||||
+    const: brcm,bcm4908-partitions
 | 
			
		||||
+
 | 
			
		||||
+  "#address-cells": true
 | 
			
		||||
+
 | 
			
		||||
+  "#size-cells": true
 | 
			
		||||
+
 | 
			
		||||
+patternProperties:
 | 
			
		||||
+  "@[0-9a-f]+$":
 | 
			
		||||
+    allOf:
 | 
			
		||||
+      - $ref: "partition.yaml#"
 | 
			
		||||
+      - properties:
 | 
			
		||||
+          compatible:
 | 
			
		||||
+            const: brcm,bcm4908-firmware
 | 
			
		||||
+
 | 
			
		||||
+required:
 | 
			
		||||
+  - "#address-cells"
 | 
			
		||||
+  - "#size-cells"
 | 
			
		||||
+
 | 
			
		||||
+additionalProperties: false
 | 
			
		||||
+
 | 
			
		||||
+examples:
 | 
			
		||||
+  - |
 | 
			
		||||
+    partitions {
 | 
			
		||||
+        compatible = "brcm,bcm4908-partitions";
 | 
			
		||||
+        #address-cells = <1>;
 | 
			
		||||
+        #size-cells = <1>;
 | 
			
		||||
+
 | 
			
		||||
+        partition@0 {
 | 
			
		||||
+            label = "cferom";
 | 
			
		||||
+            reg = <0x0 0x100000>;
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        partition@100000 {
 | 
			
		||||
+            compatible = "brcm,bcm4908-firmware";
 | 
			
		||||
+            reg = <0x100000 0xf00000>;
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        partition@1000000 {
 | 
			
		||||
+            compatible = "brcm,bcm4908-firmware";
 | 
			
		||||
+            reg = <0x1000000 0xf00000>;
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        partition@1f00000 {
 | 
			
		||||
+            label = "calibration";
 | 
			
		||||
+            reg = <0x1f00000 0x100000>;
 | 
			
		||||
+        };
 | 
			
		||||
+    };
 | 
			
		||||
@@ -0,0 +1,191 @@
 | 
			
		||||
From db18357719613cc40234300b10e28e4dfa075375 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Fri, 15 Jan 2021 16:23:01 +0100
 | 
			
		||||
Subject: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
BCM4908 partitioning is based on fixed layout but allows specifying
 | 
			
		||||
multiple firmware partitions. It requires detecting which firmware
 | 
			
		||||
partition was used for booting current kernel.
 | 
			
		||||
 | 
			
		||||
To support such cases without duplicating a lot of code (without copying
 | 
			
		||||
most of the ofpart.c code) support for post-parsing callback was added.
 | 
			
		||||
 | 
			
		||||
BCM4908 callback simply reads offset of currently used firmware
 | 
			
		||||
partition from the DT. Bootloader specifies it using the "brcm_blparms"
 | 
			
		||||
property.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
---
 | 
			
		||||
 drivers/mtd/parsers/Makefile             |  1 +
 | 
			
		||||
 drivers/mtd/parsers/bcm4908-partitions.c | 62 ++++++++++++++++++++++++
 | 
			
		||||
 drivers/mtd/parsers/bcm4908-partitions.h |  7 +++
 | 
			
		||||
 drivers/mtd/parsers/ofpart.c             | 28 ++++++++++-
 | 
			
		||||
 4 files changed, 96 insertions(+), 2 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/mtd/parsers/bcm4908-partitions.c
 | 
			
		||||
 create mode 100644 drivers/mtd/parsers/bcm4908-partitions.h
 | 
			
		||||
 | 
			
		||||
--- a/drivers/mtd/parsers/Makefile
 | 
			
		||||
+++ b/drivers/mtd/parsers/Makefile
 | 
			
		||||
@@ -5,6 +5,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS)		+= bcm6
 | 
			
		||||
 obj-$(CONFIG_MTD_CMDLINE_PARTS)		+= cmdlinepart.o
 | 
			
		||||
 obj-$(CONFIG_MTD_MYLOADER_PARTS)		+= myloader.o
 | 
			
		||||
 obj-$(CONFIG_MTD_OF_PARTS)		+= ofpart.o
 | 
			
		||||
+obj-$(CONFIG_MTD_OF_PARTS)		+= bcm4908-partitions.o
 | 
			
		||||
 obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o
 | 
			
		||||
 obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o
 | 
			
		||||
 obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/mtd/parsers/bcm4908-partitions.c
 | 
			
		||||
@@ -0,0 +1,62 @@
 | 
			
		||||
+// SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/module.h>
 | 
			
		||||
+#include <linux/init.h>
 | 
			
		||||
+#include <linux/of.h>
 | 
			
		||||
+#include <linux/mtd/mtd.h>
 | 
			
		||||
+#include <linux/slab.h>
 | 
			
		||||
+#include <linux/mtd/partitions.h>
 | 
			
		||||
+
 | 
			
		||||
+#define BLPARAMS_FW_OFFSET		"NAND_RFS_OFS"
 | 
			
		||||
+
 | 
			
		||||
+static long long bcm4908_partitions_fw_offset(void)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device_node *root;
 | 
			
		||||
+	struct property *prop;
 | 
			
		||||
+	const char *s;
 | 
			
		||||
+
 | 
			
		||||
+	root = of_find_node_by_path("/");
 | 
			
		||||
+	if (!root)
 | 
			
		||||
+		return -ENOENT;
 | 
			
		||||
+
 | 
			
		||||
+	of_property_for_each_string(root, "brcm_blparms", prop, s) {
 | 
			
		||||
+		size_t len = strlen(BLPARAMS_FW_OFFSET);
 | 
			
		||||
+		unsigned long offset;
 | 
			
		||||
+		int err;
 | 
			
		||||
+
 | 
			
		||||
+		if (strncmp(s, BLPARAMS_FW_OFFSET, len) || s[len] != '=')
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		err = kstrtoul(s + len + 1, 0, &offset);
 | 
			
		||||
+		if (err) {
 | 
			
		||||
+			pr_err("failed to parse %s\n", s + len + 1);
 | 
			
		||||
+			return err;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		return offset << 10;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return -ENOENT;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts)
 | 
			
		||||
+{
 | 
			
		||||
+	long long fw_offset;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	fw_offset = bcm4908_partitions_fw_offset();
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < nr_parts; i++) {
 | 
			
		||||
+		if (of_device_is_compatible(parts[i].of_node, "brcm,bcm4908-firmware")) {
 | 
			
		||||
+			if (fw_offset < 0 || parts[i].offset == fw_offset)
 | 
			
		||||
+				parts[i].name = "firmware";
 | 
			
		||||
+			else
 | 
			
		||||
+				parts[i].name = "backup";
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/mtd/parsers/bcm4908-partitions.h
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
+/* SPDX-License-Identifier: GPL-2.0 */
 | 
			
		||||
+#ifndef __BCM4908_PARTITIONS_H
 | 
			
		||||
+#define __BCM4908_PARTITIONS_H
 | 
			
		||||
+
 | 
			
		||||
+int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | 
			
		||||
+
 | 
			
		||||
+#endif
 | 
			
		||||
--- a/drivers/mtd/parsers/ofpart.c
 | 
			
		||||
+++ b/drivers/mtd/parsers/ofpart.c
 | 
			
		||||
@@ -16,6 +16,18 @@
 | 
			
		||||
 #include <linux/slab.h>
 | 
			
		||||
 #include <linux/mtd/partitions.h>
 | 
			
		||||
 
 | 
			
		||||
+#include "bcm4908-partitions.h"
 | 
			
		||||
+
 | 
			
		||||
+struct fixed_partitions_quirks {
 | 
			
		||||
+	int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct fixed_partitions_quirks bcm4908_partitions_quirks = {
 | 
			
		||||
+	.post_parse = bcm4908_partitions_post_parse,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct of_device_id parse_ofpart_match_table[];
 | 
			
		||||
+
 | 
			
		||||
 static bool node_has_compatible(struct device_node *pp)
 | 
			
		||||
 {
 | 
			
		||||
 	return of_get_property(pp, "compatible", NULL);
 | 
			
		||||
@@ -25,6 +37,8 @@ static int parse_fixed_partitions(struct
 | 
			
		||||
 				  const struct mtd_partition **pparts,
 | 
			
		||||
 				  struct mtd_part_parser_data *data)
 | 
			
		||||
 {
 | 
			
		||||
+	const struct fixed_partitions_quirks *quirks;
 | 
			
		||||
+	const struct of_device_id *of_id;
 | 
			
		||||
 	struct mtd_partition *parts;
 | 
			
		||||
 	struct device_node *mtd_node;
 | 
			
		||||
 	struct device_node *ofpart_node;
 | 
			
		||||
@@ -33,7 +47,6 @@ static int parse_fixed_partitions(struct
 | 
			
		||||
 	int nr_parts, i, ret = 0;
 | 
			
		||||
 	bool dedicated = true;
 | 
			
		||||
 
 | 
			
		||||
-
 | 
			
		||||
 	/* Pull of_node from the master device node */
 | 
			
		||||
 	mtd_node = mtd_get_of_node(master);
 | 
			
		||||
 	if (!mtd_node)
 | 
			
		||||
@@ -50,11 +63,16 @@ static int parse_fixed_partitions(struct
 | 
			
		||||
 			 master->name, mtd_node);
 | 
			
		||||
 		ofpart_node = mtd_node;
 | 
			
		||||
 		dedicated = false;
 | 
			
		||||
-	} else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	of_id = of_match_node(parse_ofpart_match_table, ofpart_node);
 | 
			
		||||
+	if (dedicated && !of_id) {
 | 
			
		||||
 		/* The 'partitions' subnode might be used by another parser */
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	quirks = of_id ? of_id->data : NULL;
 | 
			
		||||
+
 | 
			
		||||
 	/* First count the subnodes */
 | 
			
		||||
 	nr_parts = 0;
 | 
			
		||||
 	for_each_child_of_node(ofpart_node,  pp) {
 | 
			
		||||
@@ -123,6 +141,9 @@ static int parse_fixed_partitions(struct
 | 
			
		||||
 	if (!nr_parts)
 | 
			
		||||
 		goto ofpart_none;
 | 
			
		||||
 
 | 
			
		||||
+	if (quirks && quirks->post_parse)
 | 
			
		||||
+		quirks->post_parse(master, parts, nr_parts);
 | 
			
		||||
+
 | 
			
		||||
 	*pparts = parts;
 | 
			
		||||
 	return nr_parts;
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +158,10 @@ ofpart_none:
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct of_device_id parse_ofpart_match_table[] = {
 | 
			
		||||
+	/* Generic */
 | 
			
		||||
 	{ .compatible = "fixed-partitions" },
 | 
			
		||||
+	/* Customized */
 | 
			
		||||
+	{ .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, },
 | 
			
		||||
 	{},
 | 
			
		||||
 };
 | 
			
		||||
 MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
 | 
			
		||||
		Reference in New Issue
	
	Block a user