aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/pxa2xx-flash.c
diff options
context:
space:
mode:
authorTodd Poynor <tpoynor@mvista.com>2005-11-07 16:47:48 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-09-23 13:40:14 -0400
commite644f7d6289456657996df4192de76c5d0a9f9c7 (patch)
tree0c34302a7b43bc84ffd02acef5d11493e049eb31 /drivers/mtd/maps/pxa2xx-flash.c
parentb38178ee712e8608f20c8e741adf97f75f1aea39 (diff)
[MTD] MAPS: Merge Lubbock and Mainstone drivers into common PXA2xx driver
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>
Diffstat (limited to 'drivers/mtd/maps/pxa2xx-flash.c')
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
new file mode 100644
index 000000000000..cb933ac475d5
--- /dev/null
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -0,0 +1,200 @@
1/*
2 * Map driver for Intel XScale PXA2xx platforms.
3 *
4 * Author: Nicolas Pitre
5 * Copyright: (C) 2001 MontaVista Software Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/dma-mapping.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21
22#include <asm/io.h>
23#include <asm/hardware.h>
24
25#include <asm/mach/flash.h>
26
27static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
28 ssize_t len)
29{
30 consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
31}
32
33struct pxa2xx_flash_info {
34 struct mtd_partition *parts;
35 int nr_parts;
36 struct mtd_info *mtd;
37 struct map_info map;
38};
39
40
41static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
42
43
44static int __init pxa2xx_flash_probe(struct device *dev)
45{
46 struct platform_device *pdev = to_platform_device(dev);
47 struct flash_platform_data *flash = pdev->dev.platform_data;
48 struct pxa2xx_flash_info *info;
49 struct mtd_partition *parts;
50 struct resource *res;
51 int ret = 0;
52
53 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
54 if (!res)
55 return -ENODEV;
56
57 info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL);
58 if (!info)
59 return -ENOMEM;
60
61 memset(info, 0, sizeof(struct pxa2xx_flash_info));
62 info->map.name = (char *) flash->name;
63 info->map.bankwidth = flash->width;
64 info->map.phys = res->start;
65 info->map.size = res->end - res->start + 1;
66 info->parts = flash->parts;
67 info->nr_parts = flash->nr_parts;
68
69 info->map.virt = ioremap(info->map.phys, info->map.size);
70 if (!info->map.virt) {
71 printk(KERN_WARNING "Failed to ioremap %s\n",
72 info->map.name);
73 return -ENOMEM;
74 }
75 info->map.cached =
76 ioremap_cached(info->map.phys, info->map.size);
77 if (!info->map.cached)
78 printk(KERN_WARNING "Failed to ioremap cached %s\n",
79 info->map.name);
80 info->map.inval_cache = pxa2xx_map_inval_cache;
81 simple_map_init(&info->map);
82
83 printk(KERN_NOTICE
84 "Probing %s at physical address 0x%08lx"
85 " (%d-bit bankwidth)\n",
86 info->map.name, (unsigned long)info->map.phys,
87 info->map.bankwidth * 8);
88
89 info->mtd = do_map_probe(flash->map_name, &info->map);
90
91 if (!info->mtd) {
92 iounmap((void *)info->map.virt);
93 if (info->map.cached)
94 iounmap(info->map.cached);
95 return -EIO;
96 }
97 info->mtd->owner = THIS_MODULE;
98
99#ifdef CONFIG_MTD_PARTITIONS
100 ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
101
102 if (ret > 0) {
103 info->nr_parts = ret;
104 info->parts = parts;
105 }
106#endif
107
108 if (info->nr_parts) {
109 add_mtd_partitions(info->mtd, info->parts,
110 info->nr_parts);
111 } else {
112 printk("Registering %s as whole device\n",
113 info->map.name);
114 add_mtd_device(info->mtd);
115 }
116
117 dev_set_drvdata(dev, info);
118 return 0;
119}
120
121static int __exit pxa2xx_flash_remove(struct device *dev)
122{
123 struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
124
125 dev_set_drvdata(dev, NULL);
126
127#ifdef CONFIG_MTD_PARTITIONS
128 if (info->nr_parts)
129 del_mtd_partitions(info->mtd);
130 else
131#endif
132 del_mtd_device(info->mtd);
133
134 map_destroy(info->mtd);
135 iounmap(info->map.virt);
136 if (info->map.cached)
137 iounmap(info->map.cached);
138 kfree(info->parts);
139 kfree(info);
140 return 0;
141}
142
143#ifdef CONFIG_PM
144static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
145{
146 struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
147 int ret = 0;
148
149 if (info->mtd && info->mtd->suspend)
150 ret = info->mtd->suspend(info->mtd);
151 return ret;
152}
153
154static int pxa2xx_flash_resume(struct device *dev)
155{
156 struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
157
158 if (info->mtd && info->mtd->resume)
159 info->mtd->resume(info->mtd);
160 return 0;
161}
162static void pxa2xx_flash_shutdown(struct device *dev)
163{
164 struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
165
166 if (info && info->mtd->suspend(info->mtd) == 0)
167 info->mtd->resume(info->mtd);
168}
169#else
170#define pxa2xx_flash_suspend NULL
171#define pxa2xx_flash_resume NULL
172#define pxa2xx_flash_shutdown NULL
173#endif
174
175static struct device_driver pxa2xx_flash_driver = {
176 .name = "pxa2xx-flash",
177 .bus = &platform_bus_type,
178 .probe = pxa2xx_flash_probe,
179 .remove = __exit_p(pxa2xx_flash_remove),
180 .suspend = pxa2xx_flash_suspend,
181 .resume = pxa2xx_flash_resume,
182 .shutdown = pxa2xx_flash_shutdown,
183};
184
185static int __init init_pxa2xx_flash(void)
186{
187 return driver_register(&pxa2xx_flash_driver);
188}
189
190static void __exit cleanup_pxa2xx_flash(void)
191{
192 driver_unregister(&pxa2xx_flash_driver);
193}
194
195module_init(init_pxa2xx_flash);
196module_exit(cleanup_pxa2xx_flash);
197
198MODULE_LICENSE("GPL");
199MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
200MODULE_DESCRIPTION("MTD map driver for Intel XScale PXA2xx");