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
	 Rafał Miłecki
					Rafał Miłecki