[MTD] MAPS: Merge Lubbock and Mainstone drivers into common PXA2xx driver
Todd Poynor [Mon, 7 Nov 2005 21:47:48 +0000 (21:47 +0000)]
Replace Lubbock and Mainstone board drivers with common PXA2xx driver,
convert to platform driver (corresponding platform device changes merged
to kernel.org for 2.6.15), add power management callbacks.

Signed-off-by: Todd Poynor <tpoynor@mvista.com>
Signed-off-by: Nicolas Pitre <npitre@mvista.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>

drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/lubbock-flash.c [deleted file]
drivers/mtd/maps/mainstone-flash.c [deleted file]
drivers/mtd/maps/pxa2xx-flash.c [new file with mode: 0644]

index 1c97163..7559950 100644 (file)
@@ -163,20 +163,12 @@ config MTD_SBC_GXX
          More info at
          <http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>.
 
-config MTD_LUBBOCK
-       tristate "CFI Flash device mapped on Intel Lubbock XScale eval board"
-       depends on ARCH_LUBBOCK && MTD_CFI_INTELEXT && MTD_PARTITIONS
-       help
-         This provides a driver for the on-board flash of the Intel
-         'Lubbock' XScale evaluation board.
-
-config MTD_MAINSTONE
-       tristate "CFI Flash device mapped on Intel Mainstone XScale eval board"
-       depends on MACH_MAINSTONE && MTD_CFI_INTELEXT
+config MTD_PXA2XX
+       tristate "CFI Flash device mapped on Intel XScale PXA2xx based boards"
+       depends on (PXA25x || PXA27x) && MTD_CFI_INTELEXT
        select MTD_PARTITIONS
        help
-         This provides a driver for the on-board flash of the Intel
-         'Mainstone PXA27x evaluation board.
+         This provides a driver for the NOR flash attached to a PXA2xx chip.
 
 config MTD_OCTAGON
        tristate "JEDEC Flash device mapped on Octagon 5066 SBC"
index 53fa2b5..1313eee 100644 (file)
@@ -20,8 +20,7 @@ obj-$(CONFIG_MTD_ESB2ROM)     += esb2rom.o
 obj-$(CONFIG_MTD_ICHXROM)      += ichxrom.o
 obj-$(CONFIG_MTD_CK804XROM)    += ck804xrom.o
 obj-$(CONFIG_MTD_TSUNAMI)      += tsunami_flash.o
-obj-$(CONFIG_MTD_LUBBOCK)      += lubbock-flash.o
-obj-$(CONFIG_MTD_MAINSTONE)    += mainstone-flash.o
+obj-$(CONFIG_MTD_PXA2XX)       += pxa2xx-flash.o
 obj-$(CONFIG_MTD_MBX860)       += mbx860.o
 obj-$(CONFIG_MTD_CEIVA)                += ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)      += octagon-5066.o
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
deleted file mode 100644 (file)
index 1aa0447..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
- *
- * Map driver for the Lubbock developer platform.
- *
- * Author:     Nicolas Pitre
- * Copyright:  (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/dma-mapping.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/lubbock.h>
-
-
-#define ROM_ADDR       0x00000000
-#define FLASH_ADDR     0x04000000
-
-#define WINDOW_SIZE    64*1024*1024
-
-static void lubbock_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len)
-{
-       consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
-}
-
-static struct map_info lubbock_maps[2] = { {
-       .size =         WINDOW_SIZE,
-       .phys =         0x00000000,
-       .inval_cache =  lubbock_map_inval_cache,
-}, {
-       .size =         WINDOW_SIZE,
-       .phys =         0x04000000,
-       .inval_cache =  lubbock_map_inval_cache,
-} };
-
-static struct mtd_partition lubbock_partitions[] = {
-       {
-               .name =         "Bootloader",
-               .size =         0x00040000,
-               .offset =       0,
-               .mask_flags =   MTD_WRITEABLE  /* force read-only */
-       },{
-               .name =         "Kernel",
-               .size =         0x00100000,
-               .offset =       0x00040000,
-       },{
-               .name =         "Filesystem",
-               .size =         MTDPART_SIZ_FULL,
-               .offset =       0x00140000
-       }
-};
-
-static struct mtd_info *mymtds[2];
-static struct mtd_partition *parsed_parts[2];
-static int nr_parsed_parts[2];
-
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
-static int __init init_lubbock(void)
-{
-       int flashboot = (LUB_CONF_SWITCHES & 1);
-       int ret = 0, i;
-
-       lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
-               (BOOT_DEF & 1) ? 2 : 4;
-
-       /* Compensate for the nROMBT switch which swaps the flash banks */
-       printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
-              flashboot?"Flash":"ROM", flashboot);
-
-       lubbock_maps[flashboot^1].name = "Lubbock Application Flash";
-       lubbock_maps[flashboot].name = "Lubbock Boot ROM";
-
-       for (i = 0; i < 2; i++) {
-               lubbock_maps[i].virt = ioremap(lubbock_maps[i].phys, WINDOW_SIZE);
-               if (!lubbock_maps[i].virt) {
-                       printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name);
-                       if (!ret)
-                               ret = -ENOMEM;
-                       continue;
-               }
-               lubbock_maps[i].cached = ioremap_cached(lubbock_maps[i].phys, WINDOW_SIZE);
-               if (!lubbock_maps[i].cached)
-                       printk(KERN_WARNING "Failed to ioremap cached %s\n", lubbock_maps[i].name);
-               simple_map_init(&lubbock_maps[i]);
-
-               printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
-                      lubbock_maps[i].name, lubbock_maps[i].phys,
-                      lubbock_maps[i].bankwidth * 8);
-
-               mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
-
-               if (!mymtds[i]) {
-                       iounmap((void *)lubbock_maps[i].virt);
-                       if (lubbock_maps[i].cached)
-                               iounmap(lubbock_maps[i].cached);
-                       if (!ret)
-                               ret = -EIO;
-                       continue;
-               }
-               mymtds[i]->owner = THIS_MODULE;
-
-               ret = parse_mtd_partitions(mymtds[i], probes,
-                                          &parsed_parts[i], 0);
-
-               if (ret > 0)
-                       nr_parsed_parts[i] = ret;
-       }
-
-       if (!mymtds[0] && !mymtds[1])
-               return ret;
-
-       for (i = 0; i < 2; i++) {
-               if (!mymtds[i]) {
-                       printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
-               } else if (nr_parsed_parts[i]) {
-                       add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
-               } else if (!i) {
-                       printk("Using static partitions on %s\n", lubbock_maps[i].name);
-                       add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions));
-               } else {
-                       printk("Registering %s as whole device\n", lubbock_maps[i].name);
-                       add_mtd_device(mymtds[i]);
-               }
-       }
-       return 0;
-}
-
-static void __exit cleanup_lubbock(void)
-{
-       int i;
-       for (i = 0; i < 2; i++) {
-               if (!mymtds[i])
-                       continue;
-
-               if (nr_parsed_parts[i] || !i)
-                       del_mtd_partitions(mymtds[i]);
-               else
-                       del_mtd_device(mymtds[i]);
-
-               map_destroy(mymtds[i]);
-               iounmap((void *)lubbock_maps[i].virt);
-               if (lubbock_maps[i].cached)
-                       iounmap(lubbock_maps[i].cached);
-
-               kfree(parsed_parts[i]);
-       }
-}
-
-module_init(init_lubbock);
-module_exit(cleanup_lubbock);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-MODULE_DESCRIPTION("MTD map driver for Intel Lubbock");
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
deleted file mode 100644 (file)
index eaa4bbb..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * $Id:  $
- *
- * Map driver for the Mainstone developer platform.
- *
- * Author:     Nicolas Pitre
- * Copyright:  (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/mainstone.h>
-
-
-#define ROM_ADDR       0x00000000
-#define FLASH_ADDR     0x04000000
-
-#define WINDOW_SIZE    0x04000000
-
-static void mainstone_map_inval_cache(struct map_info *map, unsigned long from,
-                                     ssize_t len)
-{
-       consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
-}
-
-static struct map_info mainstone_maps[2] = { {
-       .size =         WINDOW_SIZE,
-       .phys =         PXA_CS0_PHYS,
-       .inval_cache =  mainstone_map_inval_cache,
-}, {
-       .size =         WINDOW_SIZE,
-       .phys =         PXA_CS1_PHYS,
-       .inval_cache =  mainstone_map_inval_cache,
-} };
-
-static struct mtd_partition mainstone_partitions[] = {
-       {
-               .name =         "Bootloader",
-               .size =         0x00040000,
-               .offset =       0,
-               .mask_flags =   MTD_WRITEABLE  /* force read-only */
-       },{
-               .name =         "Kernel",
-               .size =         0x00400000,
-               .offset =       0x00040000,
-       },{
-               .name =         "Filesystem",
-               .size =         MTDPART_SIZ_FULL,
-               .offset =       0x00440000
-       }
-};
-
-static struct mtd_info *mymtds[2];
-static struct mtd_partition *parsed_parts[2];
-static int nr_parsed_parts[2];
-
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
-static int __init init_mainstone(void)
-{
-       int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
-       int ret = 0, i;
-
-       mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4;
-       mainstone_maps[1].bankwidth = 4;
-
-       /* Compensate for SW7 which swaps the flash banks */
-       mainstone_maps[SW7].name = "processor flash";
-       mainstone_maps[SW7 ^ 1].name = "main board flash";
-
-       printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
-              mainstone_maps[0].name);
-
-       for (i = 0; i < 2; i++) {
-               mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
-                                                WINDOW_SIZE);
-               if (!mainstone_maps[i].virt) {
-                       printk(KERN_WARNING "Failed to ioremap %s\n",
-                              mainstone_maps[i].name);
-                       if (!ret)
-                               ret = -ENOMEM;
-                       continue;
-               }
-               mainstone_maps[i].cached =
-                       ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
-               if (!mainstone_maps[i].cached)
-                       printk(KERN_WARNING "Failed to ioremap cached %s\n",
-                              mainstone_maps[i].name);
-               simple_map_init(&mainstone_maps[i]);
-
-               printk(KERN_NOTICE
-                      "Probing %s at physical address 0x%08lx"
-                      " (%d-bit bankwidth)\n",
-                      mainstone_maps[i].name, mainstone_maps[i].phys,
-                      mainstone_maps[i].bankwidth * 8);
-
-               mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
-
-               if (!mymtds[i]) {
-                       iounmap((void *)mainstone_maps[i].virt);
-                       if (mainstone_maps[i].cached)
-                               iounmap(mainstone_maps[i].cached);
-                       if (!ret)
-                               ret = -EIO;
-                       continue;
-               }
-               mymtds[i]->owner = THIS_MODULE;
-
-               ret = parse_mtd_partitions(mymtds[i], probes,
-                                          &parsed_parts[i], 0);
-
-               if (ret > 0)
-                       nr_parsed_parts[i] = ret;
-       }
-
-       if (!mymtds[0] && !mymtds[1])
-               return ret;
-
-       for (i = 0; i < 2; i++) {
-               if (!mymtds[i]) {
-                       printk(KERN_WARNING "%s is absent. Skipping\n",
-                              mainstone_maps[i].name);
-               } else if (nr_parsed_parts[i]) {
-                       add_mtd_partitions(mymtds[i], parsed_parts[i],
-                                          nr_parsed_parts[i]);
-               } else if (!i) {
-                       printk("Using static partitions on %s\n",
-                              mainstone_maps[i].name);
-                       add_mtd_partitions(mymtds[i], mainstone_partitions,
-                                          ARRAY_SIZE(mainstone_partitions));
-               } else {
-                       printk("Registering %s as whole device\n",
-                              mainstone_maps[i].name);
-                       add_mtd_device(mymtds[i]);
-               }
-       }
-       return 0;
-}
-
-static void __exit cleanup_mainstone(void)
-{
-       int i;
-       for (i = 0; i < 2; i++) {
-               if (!mymtds[i])
-                       continue;
-
-               if (nr_parsed_parts[i] || !i)
-                       del_mtd_partitions(mymtds[i]);
-               else
-                       del_mtd_device(mymtds[i]);
-
-               map_destroy(mymtds[i]);
-               iounmap((void *)mainstone_maps[i].virt);
-               if (mainstone_maps[i].cached)
-                       iounmap(mainstone_maps[i].cached);
-               kfree(parsed_parts[i]);
-       }
-}
-
-module_init(init_mainstone);
-module_exit(cleanup_mainstone);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-MODULE_DESCRIPTION("MTD map driver for Intel Mainstone");
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
new file mode 100644 (file)
index 0000000..cb933ac
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Map driver for Intel XScale PXA2xx platforms.
+ *
+ * Author:     Nicolas Pitre
+ * Copyright:  (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/flash.h>
+
+static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
+                                     ssize_t len)
+{
+       consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
+}
+
+struct pxa2xx_flash_info {
+       struct mtd_partition    *parts;
+       int                     nr_parts;
+       struct mtd_info         *mtd;
+       struct map_info         map;
+};
+
+
+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+
+
+static int __init pxa2xx_flash_probe(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct flash_platform_data *flash = pdev->dev.platform_data;
+       struct pxa2xx_flash_info *info;
+       struct mtd_partition *parts;
+       struct resource *res;
+       int ret = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       memset(info, 0, sizeof(struct pxa2xx_flash_info));
+       info->map.name = (char *) flash->name;
+       info->map.bankwidth = flash->width;
+       info->map.phys = res->start;
+       info->map.size = res->end - res->start + 1;
+       info->parts = flash->parts;
+       info->nr_parts = flash->nr_parts;
+
+       info->map.virt = ioremap(info->map.phys, info->map.size);
+       if (!info->map.virt) {
+               printk(KERN_WARNING "Failed to ioremap %s\n",
+                      info->map.name);
+               return -ENOMEM;
+       }
+       info->map.cached =
+               ioremap_cached(info->map.phys, info->map.size);
+       if (!info->map.cached)
+               printk(KERN_WARNING "Failed to ioremap cached %s\n",
+                      info->map.name);
+       info->map.inval_cache = pxa2xx_map_inval_cache;
+       simple_map_init(&info->map);
+
+       printk(KERN_NOTICE
+              "Probing %s at physical address 0x%08lx"
+              " (%d-bit bankwidth)\n",
+              info->map.name, (unsigned long)info->map.phys,
+              info->map.bankwidth * 8);
+
+       info->mtd = do_map_probe(flash->map_name, &info->map);
+
+       if (!info->mtd) {
+               iounmap((void *)info->map.virt);
+               if (info->map.cached)
+                       iounmap(info->map.cached);
+               return -EIO;
+       }
+       info->mtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+       ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
+
+       if (ret > 0) {
+               info->nr_parts = ret;
+               info->parts = parts;
+       }
+#endif
+
+       if (info->nr_parts) {
+               add_mtd_partitions(info->mtd, info->parts,
+                                  info->nr_parts);
+       } else {
+               printk("Registering %s as whole device\n",
+                      info->map.name);
+               add_mtd_device(info->mtd);
+       }
+
+       dev_set_drvdata(dev, info);
+       return 0;
+}
+
+static int __exit pxa2xx_flash_remove(struct device *dev)
+{
+       struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+
+       dev_set_drvdata(dev, NULL);
+
+#ifdef CONFIG_MTD_PARTITIONS
+       if (info->nr_parts)
+               del_mtd_partitions(info->mtd);
+       else
+#endif
+               del_mtd_device(info->mtd);
+
+       map_destroy(info->mtd);
+       iounmap(info->map.virt);
+       if (info->map.cached)
+               iounmap(info->map.cached);
+       kfree(info->parts);
+       kfree(info);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+{
+       struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (info->mtd && info->mtd->suspend)
+               ret = info->mtd->suspend(info->mtd);
+       return ret;
+}
+
+static int pxa2xx_flash_resume(struct device *dev)
+{
+       struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+
+       if (info->mtd && info->mtd->resume)
+               info->mtd->resume(info->mtd);
+       return 0;
+}
+static void pxa2xx_flash_shutdown(struct device *dev)
+{
+       struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+
+       if (info && info->mtd->suspend(info->mtd) == 0)
+               info->mtd->resume(info->mtd);
+}
+#else
+#define pxa2xx_flash_suspend NULL
+#define pxa2xx_flash_resume NULL
+#define pxa2xx_flash_shutdown NULL
+#endif
+
+static struct device_driver pxa2xx_flash_driver = {
+       .name           = "pxa2xx-flash",
+       .bus            = &platform_bus_type,
+       .probe          = pxa2xx_flash_probe,
+       .remove         = __exit_p(pxa2xx_flash_remove),
+       .suspend        = pxa2xx_flash_suspend,
+       .resume         = pxa2xx_flash_resume,
+       .shutdown       = pxa2xx_flash_shutdown,
+};
+
+static int __init init_pxa2xx_flash(void)
+{
+       return driver_register(&pxa2xx_flash_driver);
+}
+
+static void __exit cleanup_pxa2xx_flash(void)
+{
+       driver_unregister(&pxa2xx_flash_driver);
+}
+
+module_init(init_pxa2xx_flash);
+module_exit(cleanup_pxa2xx_flash);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("MTD map driver for Intel XScale PXA2xx");