2021-01-15 15:42:07

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 1/3] dt-bindings: mtd: move partition binding to its own file

From: Rafał Miłecki <[email protected]>

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 <[email protected]>
---
.../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

diff --git a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
index 6d4a3450e064..ea4cace6a955 100644
--- 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"
diff --git a/Documentation/devicetree/bindings/mtd/partitions/partition.yaml b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml
new file mode 100644
index 000000000000..e1ac08064425
--- /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 <[email protected]>
+
+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
--
2.26.2


2021-01-15 15:42:15

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions

From: Rafał Miłecki <[email protected]>

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 <[email protected]>
---
.../partitions/brcm,bcm4908-partitions.yaml | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml

diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
new file mode 100644
index 000000000000..4090b61a3da7
--- /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 <[email protected]>
+
+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>;
+ };
+ };
--
2.26.2

2021-01-15 15:44:53

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions

From: Rafał Miłecki <[email protected]>

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 <[email protected]>
---
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

diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile
index b0c5f62f9e85..3e26001f743c 100644
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.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
diff --git a/drivers/mtd/parsers/bcm4908-partitions.c b/drivers/mtd/parsers/bcm4908-partitions.c
new file mode 100644
index 000000000000..032a4b1b8a5f
--- /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 <[email protected]>
+ */
+
+#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;
+}
diff --git a/drivers/mtd/parsers/bcm4908-partitions.h b/drivers/mtd/parsers/bcm4908-partitions.h
new file mode 100644
index 000000000000..df25f0487d0a
--- /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
diff --git a/drivers/mtd/parsers/ofpart.c b/drivers/mtd/parsers/ofpart.c
index daf507c123e6..6b221df8401c 100644
--- 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 mtd_info *master,
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 mtd_info *master,
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 mtd_info *master,
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) {
@@ -126,6 +144,9 @@ static int parse_fixed_partitions(struct mtd_info *master,
if (!nr_parts)
goto ofpart_none;

+ if (quirks && quirks->post_parse)
+ quirks->post_parse(master, parts, nr_parts);
+
*pparts = parts;
return nr_parts;

@@ -140,7 +161,10 @@ static int parse_fixed_partitions(struct mtd_info *master,
}

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);
--
2.26.2

2021-01-19 16:03:01

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions

Hi Rafał,

Rafał Miłecki <[email protected]> wrote on Fri, 15 Jan 2021 16:39:01
+0100:

> From: Rafał Miłecki <[email protected]>
>
> 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 <[email protected]>

The approach looks fine by me, let's see what other maintainers think.


Cheers,
Miquèl

2021-01-22 21:46:44

by Richard Weinberger

[permalink] [raw]
Subject: Re: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions

On Tue, Jan 19, 2021 at 5:01 PM Miquel Raynal <[email protected]> wrote:
> > Signed-off-by: Rafał Miłecki <[email protected]>
>
> The approach looks fine by me, let's see what other maintainers think.

Same, looks good to me! :-)

--
Thanks,
//richard

2021-01-25 22:26:20

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 1/3] dt-bindings: mtd: move partition binding to its own file

On Fri, 15 Jan 2021 16:38:59 +0100, Rafał Miłecki wrote:
> From: Rafał Miłecki <[email protected]>
>
> 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 <[email protected]>
> ---
> .../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
>

Reviewed-by: Rob Herring <[email protected]>

2021-01-25 22:45:38

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions

On Fri, Jan 15, 2021 at 04:39:00PM +0100, Rafał Miłecki wrote:
> From: Rafał Miłecki <[email protected]>
>
> 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 <[email protected]>
> ---
> .../partitions/brcm,bcm4908-partitions.yaml | 68 +++++++++++++++++++
> 1 file changed, 68 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
>
> diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
> new file mode 100644
> index 000000000000..4090b61a3da7
> --- /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 <[email protected]>
> +
> +properties:
> + compatible:
> + const: brcm,bcm4908-partitions
> +
> + "#address-cells": true
> +
> + "#size-cells": true

limit these to 1 and 2?

> +
> +patternProperties:
> + "@[0-9a-f]+$":

^partition@...

> + allOf:

You can drop 'allOf'.

> + - $ref: "partition.yaml#"
> + - properties:
> + compatible:
> + const: brcm,bcm4908-firmware

Also needs 'unevaluatedProperties: false'

> +
> +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>;
> + };
> + };
> --
> 2.26.2
>