From 6b54054c4053215fe4add195c67daca9a466ba92 Mon Sep 17 00:00:00 2001 From: "ying.zhang" Date: Fri, 23 Dec 2016 22:21:22 +0800 Subject: [PATCH] mtd: extend physmap_of to let the device tree specify the parition probe This is to support custom partitioning schemes for embedded PPC. To use define your own mtd_part_parser and then add something like: linux,part-probe = "my_probe", "cmdlinepart"; To the board's dts file. If linux,part-probe is not specified then this behaves the same as before. Signed-off-by: Jason Gunthorpe Signed-off-by: David Woodhouse --- drivers/mtd/maps/physmap_of.c | 46 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -112,9 +112,47 @@ static struct mtd_info *obsolete_probe(s static const char * const part_probe_types_def[] = { "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; +static const char * const *of_get_probes(struct device_node *dp) +{ + const char *cp; + int cplen; + unsigned int l; + unsigned int count; + const char **res; + + cp = of_get_property(dp, "linux,part-probe", &cplen); + if (cp == NULL) + return part_probe_types_def; + + count = 0; + for (l = 0; l != cplen; l++) + if (cp[l] == 0) + count++; + + res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL); + if (!res) + return NULL; + count = 0; + while (cplen > 0) { + res[count] = cp; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + count++; + } + return res; +} + +static void of_free_probes(const char * const *probes) +{ + if (probes != part_probe_types_def) + kfree(probes); +} + static const struct of_device_id of_flash_match[]; static int of_flash_probe(struct platform_device *dev) { + const char * const *part_probe_types; const struct of_device_id *match; struct device_node *dp = dev->dev.of_node; struct resource res; @@ -273,8 +311,14 @@ static int of_flash_probe(struct platfor goto err_out; ppdata.of_node = dp; - mtd_device_parse_register(info->cmtd, part_probe_types_def, &ppdata, + part_probe_types = of_get_probes(dp); + if (!part_probe_types) { + err = -ENOMEM; + goto err_out; + } + mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata, NULL, 0); + of_free_probes(part_probe_types); kfree(mtd_list);