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:
parent
7495acb555
commit
20a0d435d8
3 changed files with 393 additions and 0 deletions
|
@ -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);
|
Loading…
Reference in a new issue