Subject: [PATCH 0/7] MTD: MAPS: remove bcm963xx-flash

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:04 +0100

While trying to improve the bcm963xx CFE partition parsing, I noticed
that it could be completely replaced by the generic physmap flash
driver using a custom parser.

The following patch set tries to accomplish that.

The first few patches clean take care of some minor code style issues
first to prevent checkpatch from complaining when moving code around.

After that I move the CFE partition parsing into a parser and make
bcm963xx-flash use it to make sure I don't create a non working version.

Finally I'll allow physmap_flash_data to take partition parser names for
overriding the default parsers list (the OF version already allows that),
let BCM63XX use it, and remove the bcm963xx-flash driver as it is now
completely replaced by physmap + CFE parser.

While most patches are limited to the MTD tree, patch 6/7 touches MIPS,
so it could go in either tree. But since the MTD tree already has some
modifications for bcm963xx-flash, I think it's better to let it go
through the MTD tree, to reduce the (potential for) conflicts.

Regards
Jonas

P.S: This patchset is based on l2-mtd-2.6.git, which seems to be the
"correct" tree now (the website says mtd-2.6.git, but it doesn't look
like the correct one, having no commits). 

Jonas Gorski (7):
  MTD: MAPS: bcm963xx-flash: fix word order for spare partition
  MTD: MAPS: bcm963xx-flash: remove superfluous semicolons
  MTD: MAPS: bcm963xx-flash: clean up printk usage
  MTD: MAPS: bcm963xx-flash: make CFE partition parsing an mtd parser
  MTD: MAPS: physmap: allow partition parsers for physmap_flash_data
  MIPS: BCM63XX: use the new bcm63xxpart parser
  MTD: MAPS: remove the now unused bcm963xx-flash

 arch/mips/bcm63xx/boards/board_bcm963xx.c |    3 +
 drivers/mtd/Kconfig                       |    8 +
 drivers/mtd/Makefile                      |    1 +
 drivers/mtd/bcm63xxpart.c                 |  189 ++++++++++++++++++++
 drivers/mtd/maps/Kconfig                  |    1 +
 drivers/mtd/maps/bcm963xx-flash.c         |  265 -----------------------------
 drivers/mtd/maps/physmap.c                |    5 +-
 include/linux/mtd/physmap.h               |    1 +
 8 files changed, 207 insertions(+), 266 deletions(-)
 create mode 100644 drivers/mtd/bcm63xxpart.c
 delete mode 100644 drivers/mtd/maps/bcm963xx-flash.c

-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:05 +0100

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/maps/bcm963xx-flash.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
index c7d3949..b908d92 100644
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -144,7 +144,7 @@ static int parse_cfe_partitions(struct mtd_info *master,
 					(long unsigned int)(parts[i].offset),
 					(long unsigned int)(parts[i].size));
 
-	printk(KERN_INFO PFX "Spare partition is %x offset and length %x\n",
+	printk(KERN_INFO PFX "Spare partition is offset %x and length %x\n",
 							spareaddr, sparelen);
 	*pparts = parts;
 	vfree(buf);
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:06 +0100

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/maps/bcm963xx-flash.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
index b908d92..58cbaf2 100644
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -93,18 +93,18 @@ static int parse_cfe_partitions(struct mtd_info *master,
 	if (rootfslen > 0) {
 		nrparts++;
 		namelen += 6;
-	};
+	}
 	if (kernellen > 0) {
 		nrparts++;
 		namelen += 6;
-	};
+	}
 
 	/* Ask kernel for more memory */
 	parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
 	if (!parts) {
 		vfree(buf);
 		return -ENOMEM;
-	};
+	}
 
 	/* Start building partition list */
 	parts[curpart].name = "CFE";
@@ -117,7 +117,7 @@ static int parse_cfe_partitions(struct mtd_info *master,
 		parts[curpart].offset = kerneladdr;
 		parts[curpart].size = kernellen;
 		curpart++;
-	};
+	}
 
 	if (rootfslen > 0) {
 		parts[curpart].name = "rootfs";
@@ -126,7 +126,7 @@ static int parse_cfe_partitions(struct mtd_info *master,
 		if (sparelen > 0)
 			parts[curpart].size += sparelen;
 		curpart++;
-	};
+	}
 
 	parts[curpart].name = "nvram";
 	parts[curpart].offset = master->size - master->erasesize;
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:10 +0100

Signed-off-by: Jonas Gorski <[email-masked]>
---
 arch/mips/bcm63xx/boards/board_bcm963xx.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 40b223b..c223854 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -834,10 +834,13 @@ static struct mtd_partition mtd_partitions[] = {
 	}
 };
 
+static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
+
 static struct physmap_flash_data flash_data = {
 	.width			= 2,
 	.nr_parts		= ARRAY_SIZE(mtd_partitions),
 	.parts			= mtd_partitions,
+	.part_probe_types	= bcm63xx_part_types,
 };
 
 static struct resource mtd_resources[] = {
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:07 +0100

Replace raw printk's with their pr_XXX equivalent and unify broken up
strings so they become grepable.

Also replace the PFX definition with a pr_fmt().

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/maps/bcm963xx-flash.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
index 58cbaf2..ce2ca2a 100644
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -33,8 +35,6 @@
 #define BCM63XX_BUSWIDTH	2		/* Buswidth */
 #define BCM63XX_EXTENDED_SIZE	0xBFC00000	/* Extended flash address */
 
-#define PFX KBUILD_MODNAME ": "
-
 static struct mtd_partition *parsed_parts;
 
 static struct mtd_info *bcm963xx_mtd_info;
@@ -79,8 +79,8 @@ static int parse_cfe_partitions(struct mtd_info *master,
 	tagversion = &(buf->tag_version[0]);
 	boardid = &(buf->board_id[0]);
 
-	printk(KERN_INFO PFX "CFE boot tag found with version %s "
-				"and board type %s\n", tagversion, boardid);
+	pr_info("CFE boot tag found with version %s and board type %s\n",
+		tagversion, boardid);
 
 	kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
 	rootfsaddr = kerneladdr + kernellen;
@@ -139,13 +139,13 @@ static int parse_cfe_partitions(struct mtd_info *master,
 	parts[curpart].size = master->size - parts[0].size - parts[3].size;
 
 	for (i = 0; i < nrparts; i++)
-		printk(KERN_INFO PFX "Partition %d is %s offset %lx and "
-					"length %lx\n", i, parts[i].name,
-					(long unsigned int)(parts[i].offset),
-					(long unsigned int)(parts[i].size));
+		pr_info("Partition %d is %s offset %lx and length %lx\n", i,
+			parts[i].name, (long unsigned int)(parts[i].offset),
+			(long unsigned int)(parts[i].size));
+
+	pr_info("Spare partition is offset %x and length %x\n",	spareaddr,
+		sparelen);
 
-	printk(KERN_INFO PFX "Spare partition is offset %x and length %x\n",
-							spareaddr, sparelen);
 	*pparts = parts;
 	vfree(buf);
 
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:11 +0100

bcm963xx-flash does nothing meaningful anymore.

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/maps/bcm963xx-flash.c |  118 -------------------------------------
 1 files changed, 0 insertions(+), 118 deletions(-)
 delete mode 100644 drivers/mtd/maps/bcm963xx-flash.c

diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
deleted file mode 100644
index c106632..0000000
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright © 2006-2008  Florian Fainelli <[email-masked]>
- *			  Mike Albon <[email-masked]>
- * Copyright © 2009-2010  Daniel Dickinson <[email-masked]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#define BCM63XX_BUSWIDTH	2		/* Buswidth */
-
-static struct mtd_info *bcm963xx_mtd_info;
-
-static struct map_info bcm963xx_map = {
-	.name		= "bcm963xx",
-	.bankwidth	= BCM63XX_BUSWIDTH,
-};
-
-static const char *part_types[] = { "bcm63xxpart", NULL };
-
-static int bcm963xx_probe(struct platform_device *pdev)
-{
-	int err = 0;
-	struct resource *r;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		dev_err(&pdev->dev, "no resource supplied\n");
-		return -ENODEV;
-	}
-
-	bcm963xx_map.phys = r->start;
-	bcm963xx_map.size = resource_size(r);
-	bcm963xx_map.virt = ioremap(r->start, resource_size(r));
-	if (!bcm963xx_map.virt) {
-		dev_err(&pdev->dev, "failed to ioremap\n");
-		return -EIO;
-	}
-
-	dev_info(&pdev->dev, "0x%08lx at 0x%08x\n",
-					bcm963xx_map.size, bcm963xx_map.phys);
-
-	simple_map_init(&bcm963xx_map);
-
-	bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
-	if (!bcm963xx_mtd_info) {
-		dev_err(&pdev->dev, "failed to probe using CFI\n");
-		bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map);
-		if (bcm963xx_mtd_info)
-			goto probe_ok;
-		dev_err(&pdev->dev, "failed to probe using JEDEC\n");
-		err = -EIO;
-		goto err_probe;
-	}
-
-probe_ok:
-	bcm963xx_mtd_info->owner = THIS_MODULE;
-
-	return mtd_device_parse_register(bcm963xx_mtd_info, part_types, NULL,
-					 NULL, 0);
-err_probe:
-	iounmap(bcm963xx_map.virt);
-	return err;
-}
-
-static int bcm963xx_remove(struct platform_device *pdev)
-{
-	if (bcm963xx_mtd_info) {
-		mtd_device_unregister(bcm963xx_mtd_info);
-		map_destroy(bcm963xx_mtd_info);
-	}
-
-	if (bcm963xx_map.virt) {
-		iounmap(bcm963xx_map.virt);
-		bcm963xx_map.virt = 0;
-	}
-
-	return 0;
-}
-
-static struct platform_driver bcm63xx_mtd_dev = {
-	.probe	= bcm963xx_probe,
-	.remove = bcm963xx_remove,
-	.driver = {
-		.name	= "bcm963xx-flash",
-		.owner	= THIS_MODULE,
-	},
-};
-
-module_platform_driver(bcm63xx_mtd_dev);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Broadcom BCM63xx MTD driver for CFE and RedBoot");
-MODULE_AUTHOR("Daniel Dickinson <[email-masked]>");
-MODULE_AUTHOR("Florian Fainelli <[email-masked]>");
-MODULE_AUTHOR("Mike Albon <[email-masked]>");
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:08 +0100

Recent BCM63XX devices support a variety of flash types (parallel, SPI,
NAND) and share the partition layout. To prevent code duplication make
the CFE partition parsing code a stand alone mtd parser to allow SPI or
NAND flash drivers to use it.

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/Kconfig               |    8 ++
 drivers/mtd/Makefile              |    1 +
 drivers/mtd/bcm63xxpart.c         |  189 +++++++++++++++++++++++++++++++++++++
 drivers/mtd/maps/Kconfig          |    1 +
 drivers/mtd/maps/bcm963xx-flash.c |  153 +-----------------------------
 5 files changed, 202 insertions(+), 150 deletions(-)
 create mode 100644 drivers/mtd/bcm63xxpart.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 318a869..1be6218 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -140,6 +140,14 @@ config MTD_AR7_PARTS
 	---help---
 	  TI AR7 partitioning support
 
+config MTD_BCM63XX_PARTS
+	tristate "BCM63XX CFE partitioning support"
+	depends on BCM63XX
+	select CRC32
+	help
+	  This provides partions parsing for BCM63xx devices with CFE
+	  bootloaders.
+
 comment "User Modules And Translation Layers"
 
 config MTD_CHAR
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 9aaac3a..f901354 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
 obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
+obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
new file mode 100644
index 0000000..ac7d3c8
--- /dev/null
+++ b/drivers/mtd/bcm63xxpart.c
@@ -0,0 +1,189 @@
+/*
+ * BCM63XX CFE image tag parser
+ *
+ * Copyright © 2006-2008  Florian Fainelli <[email-masked]>
+ *			  Mike Albon <[email-masked]>
+ * Copyright © 2009-2010  Daniel Dickinson <[email-masked]>
+ * Copyright © 2011 Jonas Gorski <[email-masked]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-bcm63xx/bcm963xx_tag.h>
+
+#define BCM63XX_EXTENDED_SIZE	0xBFC00000	/* Extended flash address */
+
+static int bcm63xx_detect_cfe(struct mtd_info *master)
+{
+	int idoffset = 0x4e0;
+	static char idstring[8] = "CFE1CFE1";
+	char buf[9];
+	int ret;
+	size_t retlen;
+
+	ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
+	buf[retlen] = 0;
+	pr_info("Read Signature value of %s\n", buf);
+
+	return strncmp(idstring, buf, 8);
+}
+
+static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
+					struct mtd_partition **pparts,
+					struct mtd_part_parser_data *data)
+{
+	/* CFE, NVRAM and global Linux are always present */
+	int nrparts = 3, curpart = 0;
+	struct bcm_tag *buf;
+	struct mtd_partition *parts;
+	int ret;
+	size_t retlen;
+	unsigned int rootfsaddr, kerneladdr, spareaddr;
+	unsigned int rootfslen, kernellen, sparelen, totallen;
+	int namelen = 0;
+	int i;
+	char *boardid;
+	char *tagversion;
+
+	if (bcm63xx_detect_cfe(master))
+		return -EINVAL;
+
+	/* Allocate memory for buffer */
+	buf = vmalloc(sizeof(struct bcm_tag));
+	if (!buf)
+		return -ENOMEM;
+
+	/* Get the tag */
+	ret = master->read(master, master->erasesize, sizeof(struct bcm_tag),
+							&retlen, (void *)buf);
+	if (retlen != sizeof(struct bcm_tag)) {
+		vfree(buf);
+		return -EIO;
+	}
+
+	sscanf(buf->kernel_address, "%u", &kerneladdr);
+	sscanf(buf->kernel_length, "%u", &kernellen);
+	sscanf(buf->total_length, "%u", &totallen);
+	tagversion = &(buf->tag_version[0]);
+	boardid = &(buf->board_id[0]);
+
+	pr_info("CFE boot tag found with version %s and board type %s\n",
+		tagversion, boardid);
+
+	kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
+	rootfsaddr = kerneladdr + kernellen;
+	spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
+	sparelen = master->size - spareaddr - master->erasesize;
+	rootfslen = spareaddr - rootfsaddr;
+
+	/* Determine number of partitions */
+	namelen = 8;
+	if (rootfslen > 0) {
+		nrparts++;
+		namelen += 6;
+	}
+	if (kernellen > 0) {
+		nrparts++;
+		namelen += 6;
+	}
+
+	/* Ask kernel for more memory */
+	parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
+	if (!parts) {
+		vfree(buf);
+		return -ENOMEM;
+	}
+
+	/* Start building partition list */
+	parts[curpart].name = "CFE";
+	parts[curpart].offset = 0;
+	parts[curpart].size = master->erasesize;
+	curpart++;
+
+	if (kernellen > 0) {
+		parts[curpart].name = "kernel";
+		parts[curpart].offset = kerneladdr;
+		parts[curpart].size = kernellen;
+		curpart++;
+	}
+
+	if (rootfslen > 0) {
+		parts[curpart].name = "rootfs";
+		parts[curpart].offset = rootfsaddr;
+		parts[curpart].size = rootfslen;
+		if (sparelen > 0)
+			parts[curpart].size += sparelen;
+		curpart++;
+	}
+
+	parts[curpart].name = "nvram";
+	parts[curpart].offset = master->size - master->erasesize;
+	parts[curpart].size = master->erasesize;
+
+	/* Global partition "linux" to make easy firmware upgrade */
+	curpart++;
+	parts[curpart].name = "linux";
+	parts[curpart].offset = parts[0].size;
+	parts[curpart].size = master->size - parts[0].size - parts[3].size;
+
+	for (i = 0; i < nrparts; i++)
+		pr_info("Partition %d is %s offset %lx and length %lx\n", i,
+			parts[i].name, (long unsigned int)(parts[i].offset),
+			(long unsigned int)(parts[i].size));
+
+	pr_info("Spare partition is offset %x and length %x\n",	spareaddr,
+		sparelen);
+
+	*pparts = parts;
+	vfree(buf);
+
+	return nrparts;
+};
+
+static struct mtd_part_parser bcm63xx_cfe_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = bcm63xx_parse_cfe_partitions,
+	.name = "bcm63xxpart",
+};
+
+static int __init bcm63xx_cfe_parser_init(void)
+{
+	return register_mtd_parser(&bcm63xx_cfe_parser);
+}
+
+static void __exit bcm63xx_cfe_parser_exit(void)
+{
+	deregister_mtd_parser(&bcm63xx_cfe_parser);
+}
+
+module_init(bcm63xx_cfe_parser_init);
+module_exit(bcm63xx_cfe_parser_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Dickinson <[email-masked]>");
+MODULE_AUTHOR("Florian Fainelli <[email-masked]>");
+MODULE_AUTHOR("Mike Albon <[email-masked]>");
+MODULE_AUTHOR("Jonas Gorski <[email-masked]");
+MODULE_DESCRIPTION("MTD partitioning for BCM63XX CFE bootloaders");
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 8e0c4bf..acc5e08 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -247,6 +247,7 @@ config MTD_BCM963XX
         depends on BCM63XX
 	select MTD_MAP_BANK_WIDTH_2
 	select MTD_CFI_I1
+	select MTD_BCM63XX_PARTS
         help
 	  Support for parsing CFE image tag and creating MTD partitions on
 	  Broadcom BCM63xx boards.
diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
index ce2ca2a..c106632 100644
--- a/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -26,16 +26,10 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/vmalloc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <asm/mach-bcm63xx/bcm963xx_tag.h>
-
 #define BCM63XX_BUSWIDTH	2		/* Buswidth */
-#define BCM63XX_EXTENDED_SIZE	0xBFC00000	/* Extended flash address */
-
-static struct mtd_partition *parsed_parts;

@@ -44,134 +38,11 @@ static struct map_info bcm963xx_map = {
 	.bankwidth	= BCM63XX_BUSWIDTH,
 };
 
-static int parse_cfe_partitions(struct mtd_info *master,
-						struct mtd_partition **pparts)
-{
-	/* CFE, NVRAM and global Linux are always present */
-	int nrparts = 3, curpart = 0;
-	struct bcm_tag *buf;
-	struct mtd_partition *parts;
-	int ret;
-	size_t retlen;
-	unsigned int rootfsaddr, kerneladdr, spareaddr;
-	unsigned int rootfslen, kernellen, sparelen, totallen;
-	int namelen = 0;
-	int i;
-	char *boardid;
-	char *tagversion;
-
-	/* Allocate memory for buffer */
-	buf = vmalloc(sizeof(struct bcm_tag));
-	if (!buf)
-		return -ENOMEM;
-
-	/* Get the tag */
-	ret = master->read(master, master->erasesize, sizeof(struct bcm_tag),
-							&retlen, (void *)buf);
-	if (retlen != sizeof(struct bcm_tag)) {
-		vfree(buf);
-		return -EIO;
-	}
-
-	sscanf(buf->kernel_address, "%u", &kerneladdr);
-	sscanf(buf->kernel_length, "%u", &kernellen);
-	sscanf(buf->total_length, "%u", &totallen);
-	tagversion = &(buf->tag_version[0]);
-	boardid = &(buf->board_id[0]);
-
-	pr_info("CFE boot tag found with version %s and board type %s\n",
-		tagversion, boardid);
-
-	kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
-	rootfsaddr = kerneladdr + kernellen;
-	spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
-	sparelen = master->size - spareaddr - master->erasesize;
-	rootfslen = spareaddr - rootfsaddr;
-
-	/* Determine number of partitions */
-	namelen = 8;
-	if (rootfslen > 0) {
-		nrparts++;
-		namelen += 6;
-	}
-	if (kernellen > 0) {
-		nrparts++;
-		namelen += 6;
-	}
-
-	/* Ask kernel for more memory */
-	parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
-	if (!parts) {
-		vfree(buf);
-		return -ENOMEM;
-	}
-
-	/* Start building partition list */
-	parts[curpart].name = "CFE";
-	parts[curpart].offset = 0;
-	parts[curpart].size = master->erasesize;
-	curpart++;
-
-	if (kernellen > 0) {
-		parts[curpart].name = "kernel";
-		parts[curpart].offset = kerneladdr;
-		parts[curpart].size = kernellen;
-		curpart++;
-	}
-
-	if (rootfslen > 0) {
-		parts[curpart].name = "rootfs";
-		parts[curpart].offset = rootfsaddr;
-		parts[curpart].size = rootfslen;
-		if (sparelen > 0)
-			parts[curpart].size += sparelen;
-		curpart++;
-	}
-
-	parts[curpart].name = "nvram";
-	parts[curpart].offset = master->size - master->erasesize;
-	parts[curpart].size = master->erasesize;
-
-	/* Global partition "linux" to make easy firmware upgrade */
-	curpart++;
-	parts[curpart].name = "linux";
-	parts[curpart].offset = parts[0].size;
-	parts[curpart].size = master->size - parts[0].size - parts[3].size;
-
-	for (i = 0; i < nrparts; i++)
-		pr_info("Partition %d is %s offset %lx and length %lx\n", i,
-			parts[i].name, (long unsigned int)(parts[i].offset),
-			(long unsigned int)(parts[i].size));
-
-	pr_info("Spare partition is offset %x and length %x\n",	spareaddr,
-		sparelen);
-
-	*pparts = parts;
-	vfree(buf);
-
-	return nrparts;
-};
-
-static int bcm963xx_detect_cfe(struct mtd_info *master)
-{
-	int idoffset = 0x4e0;
-	static char idstring[8] = "CFE1CFE1";
-	char buf[9];
-	int ret;
-	size_t retlen;
-
-	ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
-	buf[retlen] = 0;
-	printk(KERN_INFO PFX "Read Signature value of %s\n", buf);
-
-	return strncmp(idstring, buf, 8);
-}
+static const char *part_types[] = { "bcm63xxpart", NULL };
 
 static int bcm963xx_probe(struct platform_device *pdev)
 {
 	int err = 0;
-	int parsed_nr_parts = 0;
-	char *part_type;
 	struct resource *r;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -207,26 +78,8 @@ static int bcm963xx_probe(struct platform_device *pdev)
 probe_ok:
 	bcm963xx_mtd_info->owner = THIS_MODULE;
 
-	/* This is mutually exclusive */
-	if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) {
-		dev_info(&pdev->dev, "CFE bootloader detected\n");
-		if (parsed_nr_parts == 0) {
-			int ret = parse_cfe_partitions(bcm963xx_mtd_info,
-							&parsed_parts);
-			if (ret > 0) {
-				part_type = "CFE";
-				parsed_nr_parts = ret;
-			}
-		}
-	} else {
-		dev_info(&pdev->dev, "unsupported bootloader\n");
-		err = -ENODEV;
-		goto err_probe;
-	}
-
-	return mtd_device_register(bcm963xx_mtd_info, parsed_parts,
-				   parsed_nr_parts);
-
+	return mtd_device_parse_register(bcm963xx_mtd_info, part_types, NULL,
+					 NULL, 0);
 err_probe:
 	iounmap(bcm963xx_map.virt);
 	return err;
-- 
1.7.2.5

---

From: Jonas Gorski <[email-masked]>
Date: Mon, 5 Dec 2011 16:08:09 +0100

Arch setup code might want to use their own partition parsers, but still
use the generic physmap flash driver.

Signed-off-by: Jonas Gorski <[email-masked]>
---
 drivers/mtd/maps/physmap.c  |    5 ++++-
 include/linux/mtd/physmap.h |    1 +
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 66e8200..1f749d58 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -85,6 +85,7 @@ static int physmap_flash_probe(struct platform_device *dev)
 	struct physmap_flash_data *physmap_data;
 	struct physmap_flash_info *info;
 	const char **probe_type;
+	const char **part_types;
 	int err = 0;
 	int i;
 	int devices_found = 0;
@@ -171,7 +172,9 @@ static int physmap_flash_probe(struct platform_device *dev)
 	if (err)
 		goto err_out;
 
-	mtd_device_parse_register(info->cmtd, part_probe_types, 0,
+	part_types = physmap_data->part_probe_types ? : part_probe_types;
+
+	mtd_device_parse_register(info->cmtd, part_types, 0,
 				  physmap_data->parts, physmap_data->nr_parts);
 	return 0;
 
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index 04e0181..d2887e7 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -30,6 +30,7 @@ struct physmap_flash_data {
 	unsigned int		pfow_base;
 	char                    *probe_type;
 	struct mtd_partition	*parts;
+	const char		**part_probe_types;
 };
 
 #endif /* __LINUX_MTD_PHYSMAP__ */
-- 
1.7.2.5

---

From: Florian Fainelli <[email-masked]>
Date: Mon, 5 Dec 2011 23:36:07 +0100

Hello Jonas,

> through the MTD tree, to reduce the (potential for) conflicts.

For the whole series, feel free to add my:

Acked-by: Florian Fainelli <[email-masked]>

thanks!

>  drivers/mtd/maps/bcm963xx-flash.c         |  265
> ----------------------------- drivers/mtd/maps/physmap.c                | 
>   5 +-

-- 
Florian

---

From: Artem Bityutskiy <[email-masked]>
Date: Tue, 06 Dec 2011 14:02:44 +0200

> driver using a custom parser.

Hi,

would you please send a version which applies cleanly to my
l2-mtd-2.6.git tree:

http://git.infradead.org/users/dedekind/l2-mtd-2.6.git

Artem.

---

From: Jonas Gorski <[email-masked]>
Date: Tue, 6 Dec 2011 13:13:03 +0100

> like the correct one, having no commits).

And these patches do apply cleanly for me on my local copy of your git
(latest commit from 29 hours ago according to gitweb).

Regards
Jonas

---

From: Artem Bityutskiy <[email-masked]>
Date: Tue, 06 Dec 2011 23:01:33 +0200

> (latest commit from 29 hours ago according to gitweb).

Sorry, indeed they apply cleanly, I used wrong branch. Pushed to
l2-mtd-2.6.git, thanks.

Artem.

---

From: Brian Norris <[email-masked]>
Date: Tue, 6 Dec 2011 21:45:16 -0800

> like the correct one, having no commits).

Hi Jonas,

I see that you are nowhere near the first one to have at least a
little bit of trouble with the mtd-2.6.git vs. l2-mtd-2.6.git
question.

Artem or David,

Is it sensible to change the website documentation to reflect the fact
that most MTD development is tracked in Artem's l2 repository
primarily? I can send a patch against mtd-www.git sometime to update
this.

Brian