From ecb5548dbd58d7f9e73e8b04b3a4b10b636196cc Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 13 Nov 2004 01:35:05 +0000 Subject: [PATCH] [MTD] sa1100: Obtain flash device location from platform device. Remove static flash device location definitions since they're now obsolete. Additionally, dynamically allocate driver private data structures. --- drivers/mtd/maps/sa1100-flash.c | 242 +++++++------------------------- 1 file changed, 54 insertions(+), 188 deletions(-) diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 4bd89f1fa3d8..0a6f861c4cd6 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -14,24 +14,18 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include #include -#include - -#ifndef CONFIG_ARCH_SA1100 -#error This is for SA1100 architecture only -#endif - #if 0 /* * This is here for documentation purposes only - until these people @@ -133,21 +127,17 @@ static void jornada56x_set_vpp(int vpp) #endif struct sa_subdev_info { - unsigned long base; - unsigned long size; char name[16]; struct map_info map; struct mtd_info *mtd; struct flash_platform_data *data; }; -#define NR_SUBMTD 4 - struct sa_info { struct mtd_partition *parts; struct mtd_info *mtd; int num_subdev; - struct sa_subdev_info subdev[NR_SUBMTD]; + struct sa_subdev_info subdev[0]; }; static void sa1100_set_vpp(struct map_info *map, int on) @@ -162,17 +152,17 @@ static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) map_destroy(subdev->mtd); if (subdev->map.virt) iounmap(subdev->map.virt); - release_mem_region(subdev->base, subdev->size); + release_mem_region(subdev->map.phys, subdev->map.size); } -static int sa1100_probe_subdev(struct sa_subdev_info *subdev) +static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *res) { unsigned long phys; unsigned int size; int ret; - phys = subdev->base; - size = subdev->size; + phys = res->start; + size = res->end - phys + 1; /* * Retrieve the bankwidth from the MSC registers. @@ -251,31 +241,58 @@ static void sa1100_destroy(struct sa_info *info) for (i = info->num_subdev - 1; i >= 0; i--) sa1100_destroy_subdev(&info->subdev[i]); + kfree(info); } -static int __init -sa1100_setup_mtd(struct sa_info *info, int nr, struct flash_platform_data *flash) +static struct sa_info *__init +sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash) { - struct mtd_info *cdev[nr]; - int i, ret = 0; + struct sa_info *info; + int nr, size, i, ret = 0; + + /* + * Count number of devices. + */ + for (nr = 0; ; nr++) + if (!platform_get_resource(pdev, IORESOURCE_MEM, nr)) + break; + + if (nr == 0) { + ret = -ENODEV; + goto out; + } + + size = sizeof(struct sa_info) + sizeof(struct sa_subdev_info) * nr; + + /* + * Allocate the map_info structs in one go. + */ + info = kmalloc(size, GFP_KERNEL); + if (!info) { + ret = -ENOMEM; + goto out; + } + + memset(info, 0, size); /* * Claim and then map the memory regions. */ for (i = 0; i < nr; i++) { struct sa_subdev_info *subdev = &info->subdev[i]; - if (subdev->base == (unsigned long)-1) + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) break; subdev->map.name = subdev->name; sprintf(subdev->name, "sa1100-%d", i); subdev->data = flash; - ret = sa1100_probe_subdev(subdev); + ret = sa1100_probe_subdev(subdev, res); if (ret) break; - - cdev[i] = subdev->mtd; } info->num_subdev = i; @@ -296,10 +313,14 @@ sa1100_setup_mtd(struct sa_info *info, int nr, struct flash_platform_data *flash info->mtd = info->subdev[0].mtd; ret = 0; } else if (info->num_subdev > 1) { +#ifdef CONFIG_MTD_CONCAT + struct mtd_info *cdev[nr]; /* * We detected multiple devices. Concatenate them together. */ -#ifdef CONFIG_MTD_CONCAT + for (i = 0; i < info->num_subdev; i++) + cdev[i] = info->subdev[i].mtd; + info->mtd = mtd_concat_create(cdev, info->num_subdev, "sa1100"); if (info->mtd == NULL) @@ -312,188 +333,33 @@ sa1100_setup_mtd(struct sa_info *info, int nr, struct flash_platform_data *flash } if (ret == 0) - return 0; + return info; err: sa1100_destroy(info); - return ret; -} - -static int __init sa1100_locate_flash(struct sa_info *info) -{ - int i, nr = -ENODEV; - - if (machine_is_adsbitsy()) { - info->subdev[0].base = SA1100_CS1_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_assabet()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - info->subdev[1].base = SA1100_CS1_PHYS; /* neponset */ - info->subdev[1].size = SZ_32M; - nr = 2; - } - if (machine_is_badge4()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_64M; - nr = 1; - } - if (machine_is_cerf()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_consus()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_flexanet()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_freebird()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_frodo()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_graphicsclient()) { - info->subdev[0].base = SA1100_CS1_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_graphicsmaster()) { - info->subdev[0].base = SA1100_CS1_PHYS; - info->subdev[0].size = SZ_16M; - nr = 1; - } - if (machine_is_h3xxx()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_huw_webpanel()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_16M; - nr = 1; - } - if (machine_is_itsy()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_jornada56x()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_jornada720()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_nanoengine()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[1].size = SZ_32M; - nr = 1; - } - if (machine_is_pangolin()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_64M; - nr = 1; - } - if (machine_is_pfs168()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_pleb()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_4M; - info->subdev[1].base = SA1100_CS1_PHYS; - info->subdev[1].size = SZ_4M; - nr = 2; - } - if (machine_is_pt_system3()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_16M; - nr = 1; - } - if (machine_is_shannon()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_4M; - nr = 1; - } - if (machine_is_sherman()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_simpad()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_16M; - info->subdev[1].base = SA1100_CS1_PHYS; - info->subdev[1].size = SZ_16M; - nr = 2; - } - if (machine_is_stork()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_32M; - nr = 1; - } - if (machine_is_trizeps()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_16M; - nr = 1; - } - if (machine_is_victor()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_2M; - nr = 1; - } - if (machine_is_yopy()) { - info->subdev[0].base = SA1100_CS0_PHYS; - info->subdev[0].size = SZ_64M; - info->subdev[1].base = SA1100_CS1_PHYS; - info->subdev[1].size = SZ_64M; - nr = 2; - } - - return nr; + out: + return ERR_PTR(ret); } static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; -static struct sa_info sa_info; - static int __init sa1100_mtd_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct flash_platform_data *flash = pdev->dev.platform_data; struct mtd_partition *parts; const char *part_type = NULL; - struct sa_info *info = &sa_info; + struct sa_info *info; int err, nr_parts = 0; - int nr; if (!flash) return -ENODEV; - nr = sa1100_locate_flash(info); - if (nr < 0) - return nr; - - err = sa1100_setup_mtd(info, nr, flash); - if (err != 0) + info = sa1100_setup_mtd(pdev, flash); + if (IS_ERR(info)) { + err = PTR_ERR(info); goto out; + } /* * Partition selection stuff. -- 2.39.5