Patchwork [RFC] physmap: support top-aligned flash chips

login
register
mail settings
Submitter Matthias Ludwig
Date May 18, 2009, 2:09 p.m.
Message ID <1242655784-21131-1-git-send-email-mludwig@ultratronik.de>
Download mbox | patch
Permalink /patch/27361/
State New
Headers show

Comments

Matthias Ludwig - May 18, 2009, 2:09 p.m.
Some machines (e.g. mips au1x00) map flash chips
on the "upper end" of a memory area. Such a machine
cannot be equiped with different sized flash chips
because only the "lower end" of the memory area is
probed for the device.
This patch allows automatically probing of memory
sub-areas where smaller chips can are found.
---
 drivers/mtd/maps/physmap.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

Patch

diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 29a9011..9c892dd 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -88,6 +88,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;
+	void __iomem *virt;
 	int err = 0;
 	int i;
 	int devices_found = 0;
@@ -126,9 +127,9 @@  static int physmap_flash_probe(struct platform_device *dev)
 		info->map[i].set_vpp = physmap_data->set_vpp;
 		info->map[i].pfow_base = physmap_data->pfow_base;
 
-		info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys,
+		virt = devm_ioremap(&dev->dev, info->map[i].phys,
 						 info->map[i].size);
-		if (info->map[i].virt == NULL) {
+		if (!virt) {
 			dev_err(&dev->dev, "Failed to ioremap flash region\n");
 			err = EIO;
 			goto err_out;
@@ -137,8 +138,22 @@  static int physmap_flash_probe(struct platform_device *dev)
 		simple_map_init(&info->map[i]);
 
 		probe_type = rom_probe_types;
-		for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
+		for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) {
+			info->map[i].phys = dev->resource[i].start;
+			info->map[i].size = dev->resource[i].end -
+					dev->resource[i].start + 1;
+			info->map[i].virt = virt;
+
+			info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
+
+			while (!info->mtd[i] && physmap_data->top_aligned &&
+					info->map[i].size > 0x40000) {
+				info->map[i].size >>= 1;
+				info->map[i].phys += info->map[i].size;
+				info->map[i].virt += info->map[i].size;
 			info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
+			}
+		}
 		if (info->mtd[i] == NULL) {
 			dev_err(&dev->dev, "map_probe failed\n");
 			err = -ENXIO;