aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r--drivers/mtd/maps/Kconfig7
-rw-r--r--drivers/mtd/maps/Makefile2
-rw-r--r--drivers/mtd/maps/integrator-flash.c309
-rw-r--r--drivers/mtd/maps/lantiq-flash.c251
-rw-r--r--drivers/mtd/maps/pcmciamtd.c2
-rw-r--r--drivers/mtd/maps/physmap.c28
-rw-r--r--drivers/mtd/maps/pismo.c40
7 files changed, 289 insertions, 350 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 195b9ef3b7e..c0c328c5b13 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -257,6 +257,13 @@ config MTD_BCM963XX
257 Support for parsing CFE image tag and creating MTD partitions on 257 Support for parsing CFE image tag and creating MTD partitions on
258 Broadcom BCM63xx boards. 258 Broadcom BCM63xx boards.
259 259
260config MTD_LANTIQ
261 tristate "Lantiq SoC NOR support"
262 depends on LANTIQ
263 select MTD_PARTITIONS
264 help
265 Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
266
260config MTD_DILNETPC 267config MTD_DILNETPC
261 tristate "CFI Flash device mapped on DIL/Net PC" 268 tristate "CFI Flash device mapped on DIL/Net PC"
262 depends on X86 && MTD_CFI_INTELEXT && BROKEN 269 depends on X86 && MTD_CFI_INTELEXT && BROKEN
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 08533bd5cba..cb48b11afff 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -8,7 +8,6 @@ endif
8 8
9# Chip mappings 9# Chip mappings
10obj-$(CONFIG_MTD_CDB89712) += cdb89712.o 10obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
11obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
12obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o 11obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
13obj-$(CONFIG_MTD_DC21285) += dc21285.o 12obj-$(CONFIG_MTD_DC21285) += dc21285.o
14obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o 13obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
@@ -60,3 +59,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o
60obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o 59obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
61obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o 60obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
62obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o 61obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o
62obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
deleted file mode 100644
index a97bbcf0d58..00000000000
--- a/drivers/mtd/maps/integrator-flash.c
+++ /dev/null
@@ -1,309 +0,0 @@
1/*======================================================================
2
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
4
5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 This is access code for flashes using ARM's flash partitioning
23 standards.
24
25======================================================================*/
26
27#include <linux/module.h>
28#include <linux/types.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/ioport.h>
32#include <linux/platform_device.h>
33#include <linux/init.h>
34#include <linux/io.h>
35
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h>
38#include <linux/mtd/partitions.h>
39#include <linux/mtd/concat.h>
40
41#include <asm/mach/flash.h>
42#include <mach/hardware.h>
43#include <asm/system.h>
44
45struct armflash_subdev_info {
46 char *name;
47 struct mtd_info *mtd;
48 struct map_info map;
49 struct flash_platform_data *plat;
50};
51
52struct armflash_info {
53 struct resource *res;
54 struct mtd_partition *parts;
55 struct mtd_info *mtd;
56 int nr_subdev;
57 struct armflash_subdev_info subdev[0];
58};
59
60static void armflash_set_vpp(struct map_info *map, int on)
61{
62 struct armflash_subdev_info *info =
63 container_of(map, struct armflash_subdev_info, map);
64
65 if (info->plat && info->plat->set_vpp)
66 info->plat->set_vpp(on);
67}
68
69static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
70
71static int armflash_subdev_probe(struct armflash_subdev_info *subdev,
72 struct resource *res)
73{
74 struct flash_platform_data *plat = subdev->plat;
75 resource_size_t size = res->end - res->start + 1;
76 void __iomem *base;
77 int err = 0;
78
79 if (!request_mem_region(res->start, size, subdev->name)) {
80 err = -EBUSY;
81 goto out;
82 }
83
84 base = ioremap(res->start, size);
85 if (!base) {
86 err = -ENOMEM;
87 goto no_mem;
88 }
89
90 /*
91 * look for CFI based flash parts fitted to this board
92 */
93 subdev->map.size = size;
94 subdev->map.bankwidth = plat->width;
95 subdev->map.phys = res->start;
96 subdev->map.virt = base;
97 subdev->map.name = subdev->name;
98 subdev->map.set_vpp = armflash_set_vpp;
99
100 simple_map_init(&subdev->map);
101
102 /*
103 * Also, the CFI layer automatically works out what size
104 * of chips we have, and does the necessary identification
105 * for us automatically.
106 */
107 subdev->mtd = do_map_probe(plat->map_name, &subdev->map);
108 if (!subdev->mtd) {
109 err = -ENXIO;
110 goto no_device;
111 }
112
113 subdev->mtd->owner = THIS_MODULE;
114
115 /* Successful? */
116 if (err == 0)
117 return err;
118
119 if (subdev->mtd)
120 map_destroy(subdev->mtd);
121 no_device:
122 iounmap(base);
123 no_mem:
124 release_mem_region(res->start, size);
125 out:
126 return err;
127}
128
129static void armflash_subdev_remove(struct armflash_subdev_info *subdev)
130{
131 if (subdev->mtd)
132 map_destroy(subdev->mtd);
133 if (subdev->map.virt)
134 iounmap(subdev->map.virt);
135 kfree(subdev->name);
136 subdev->name = NULL;
137 release_mem_region(subdev->map.phys, subdev->map.size);
138}
139
140static int armflash_probe(struct platform_device *dev)
141{
142 struct flash_platform_data *plat = dev->dev.platform_data;
143 unsigned int size;
144 struct armflash_info *info;
145 int i, nr, err;
146
147 /* Count the number of devices */
148 for (nr = 0; ; nr++)
149 if (!platform_get_resource(dev, IORESOURCE_MEM, nr))
150 break;
151 if (nr == 0) {
152 err = -ENODEV;
153 goto out;
154 }
155
156 size = sizeof(struct armflash_info) +
157 sizeof(struct armflash_subdev_info) * nr;
158 info = kzalloc(size, GFP_KERNEL);
159 if (!info) {
160 err = -ENOMEM;
161 goto out;
162 }
163
164 if (plat && plat->init) {
165 err = plat->init();
166 if (err)
167 goto no_resource;
168 }
169
170 for (i = 0; i < nr; i++) {
171 struct armflash_subdev_info *subdev = &info->subdev[i];
172 struct resource *res;
173
174 res = platform_get_resource(dev, IORESOURCE_MEM, i);
175 if (!res)
176 break;
177
178 if (nr == 1)
179 /* No MTD concatenation, just use the default name */
180 subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL);
181 else
182 subdev->name = kasprintf(GFP_KERNEL, "%s-%d",
183 dev_name(&dev->dev), i);
184 if (!subdev->name) {
185 err = -ENOMEM;
186 break;
187 }
188 subdev->plat = plat;
189
190 err = armflash_subdev_probe(subdev, res);
191 if (err) {
192 kfree(subdev->name);
193 subdev->name = NULL;
194 break;
195 }
196 }
197 info->nr_subdev = i;
198
199 if (err)
200 goto subdev_err;
201
202 if (info->nr_subdev == 1)
203 info->mtd = info->subdev[0].mtd;
204 else if (info->nr_subdev > 1) {
205 struct mtd_info *cdev[info->nr_subdev];
206
207 /*
208 * We detected multiple devices. Concatenate them together.
209 */
210 for (i = 0; i < info->nr_subdev; i++)
211 cdev[i] = info->subdev[i].mtd;
212
213 info->mtd = mtd_concat_create(cdev, info->nr_subdev,
214 dev_name(&dev->dev));
215 if (info->mtd == NULL)
216 err = -ENXIO;
217 }
218
219 if (err < 0)
220 goto cleanup;
221
222 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
223 if (err > 0) {
224 err = mtd_device_register(info->mtd, info->parts, err);
225 if (err)
226 printk(KERN_ERR
227 "mtd partition registration failed: %d\n", err);
228 }
229
230 if (err == 0) {
231 platform_set_drvdata(dev, info);
232 return err;
233 }
234
235 /*
236 * We got an error, free all resources.
237 */
238 cleanup:
239 if (info->mtd) {
240 mtd_device_unregister(info->mtd);
241 if (info->mtd != info->subdev[0].mtd)
242 mtd_concat_destroy(info->mtd);
243 }
244 kfree(info->parts);
245 subdev_err:
246 for (i = info->nr_subdev - 1; i >= 0; i--)
247 armflash_subdev_remove(&info->subdev[i]);
248 no_resource:
249 if (plat && plat->exit)
250 plat->exit();
251 kfree(info);
252 out:
253 return err;
254}
255
256static int armflash_remove(struct platform_device *dev)
257{
258 struct armflash_info *info = platform_get_drvdata(dev);
259 struct flash_platform_data *plat = dev->dev.platform_data;
260 int i;
261
262 platform_set_drvdata(dev, NULL);
263
264 if (info) {
265 if (info->mtd) {
266 mtd_device_unregister(info->mtd);
267 if (info->mtd != info->subdev[0].mtd)
268 mtd_concat_destroy(info->mtd);
269 }
270 kfree(info->parts);
271
272 for (i = info->nr_subdev - 1; i >= 0; i--)
273 armflash_subdev_remove(&info->subdev[i]);
274
275 if (plat && plat->exit)
276 plat->exit();
277
278 kfree(info);
279 }
280
281 return 0;
282}
283
284static struct platform_driver armflash_driver = {
285 .probe = armflash_probe,
286 .remove = armflash_remove,
287 .driver = {
288 .name = "armflash",
289 .owner = THIS_MODULE,
290 },
291};
292
293static int __init armflash_init(void)
294{
295 return platform_driver_register(&armflash_driver);
296}
297
298static void __exit armflash_exit(void)
299{
300 platform_driver_unregister(&armflash_driver);
301}
302
303module_init(armflash_init);
304module_exit(armflash_exit);
305
306MODULE_AUTHOR("ARM Ltd");
307MODULE_DESCRIPTION("ARM Integrator CFI map driver");
308MODULE_LICENSE("GPL");
309MODULE_ALIAS("platform:armflash");
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c
new file mode 100644
index 00000000000..a90cabd7b84
--- /dev/null
+++ b/drivers/mtd/maps/lantiq-flash.c
@@ -0,0 +1,251 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
7 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/module.h>
11#include <linux/types.h>
12#include <linux/kernel.h>
13#include <linux/io.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h>
18#include <linux/mtd/partitions.h>
19#include <linux/mtd/cfi.h>
20#include <linux/platform_device.h>
21#include <linux/mtd/physmap.h>
22
23#include <lantiq_soc.h>
24#include <lantiq_platform.h>
25
26/*
27 * The NOR flash is connected to the same external bus unit (EBU) as PCI.
28 * To make PCI work we need to enable the endianness swapping for the address
29 * written to the EBU. This endianness swapping works for PCI correctly but
30 * fails for attached NOR devices. To workaround this we need to use a complex
31 * map. The workaround involves swapping all addresses whilst probing the chip.
32 * Once probing is complete we stop swapping the addresses but swizzle the
33 * unlock addresses to ensure that access to the NOR device works correctly.
34 */
35
36enum {
37 LTQ_NOR_PROBING,
38 LTQ_NOR_NORMAL
39};
40
41struct ltq_mtd {
42 struct resource *res;
43 struct mtd_info *mtd;
44 struct map_info *map;
45};
46
47static char ltq_map_name[] = "ltq_nor";
48
49static map_word
50ltq_read16(struct map_info *map, unsigned long adr)
51{
52 unsigned long flags;
53 map_word temp;
54
55 if (map->map_priv_1 == LTQ_NOR_PROBING)
56 adr ^= 2;
57 spin_lock_irqsave(&ebu_lock, flags);
58 temp.x[0] = *(u16 *)(map->virt + adr);
59 spin_unlock_irqrestore(&ebu_lock, flags);
60 return temp;
61}
62
63static void
64ltq_write16(struct map_info *map, map_word d, unsigned long adr)
65{
66 unsigned long flags;
67
68 if (map->map_priv_1 == LTQ_NOR_PROBING)
69 adr ^= 2;
70 spin_lock_irqsave(&ebu_lock, flags);
71 *(u16 *)(map->virt + adr) = d.x[0];
72 spin_unlock_irqrestore(&ebu_lock, flags);
73}
74
75/*
76 * The following 2 functions copy data between iomem and a cached memory
77 * section. As memcpy() makes use of pre-fetching we cannot use it here.
78 * The normal alternative of using memcpy_{to,from}io also makes use of
79 * memcpy() on MIPS so it is not applicable either. We are therefore stuck
80 * with having to use our own loop.
81 */
82static void
83ltq_copy_from(struct map_info *map, void *to,
84 unsigned long from, ssize_t len)
85{
86 unsigned char *f = (unsigned char *)map->virt + from;
87 unsigned char *t = (unsigned char *)to;
88 unsigned long flags;
89
90 spin_lock_irqsave(&ebu_lock, flags);
91 while (len--)
92 *t++ = *f++;
93 spin_unlock_irqrestore(&ebu_lock, flags);
94}
95
96static void
97ltq_copy_to(struct map_info *map, unsigned long to,
98 const void *from, ssize_t len)
99{
100 unsigned char *f = (unsigned char *)from;
101 unsigned char *t = (unsigned char *)map->virt + to;
102 unsigned long flags;
103
104 spin_lock_irqsave(&ebu_lock, flags);
105 while (len--)
106 *t++ = *f++;
107 spin_unlock_irqrestore(&ebu_lock, flags);
108}
109
110static const char const *part_probe_types[] = { "cmdlinepart", NULL };
111
112static int __init
113ltq_mtd_probe(struct platform_device *pdev)
114{
115 struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
116 struct ltq_mtd *ltq_mtd;
117 struct mtd_partition *parts;
118 struct resource *res;
119 int nr_parts = 0;
120 struct cfi_private *cfi;
121 int err;
122
123 ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
124 platform_set_drvdata(pdev, ltq_mtd);
125
126 ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
127 if (!ltq_mtd->res) {
128 dev_err(&pdev->dev, "failed to get memory resource");
129 err = -ENOENT;
130 goto err_out;
131 }
132
133 res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start,
134 resource_size(ltq_mtd->res), dev_name(&pdev->dev));
135 if (!ltq_mtd->res) {
136 dev_err(&pdev->dev, "failed to request mem resource");
137 err = -EBUSY;
138 goto err_out;
139 }
140
141 ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
142 ltq_mtd->map->phys = res->start;
143 ltq_mtd->map->size = resource_size(res);
144 ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev,
145 ltq_mtd->map->phys, ltq_mtd->map->size);
146 if (!ltq_mtd->map->virt) {
147 dev_err(&pdev->dev, "failed to ioremap!\n");
148 err = -ENOMEM;
149 goto err_free;
150 }
151
152 ltq_mtd->map->name = ltq_map_name;
153 ltq_mtd->map->bankwidth = 2;
154 ltq_mtd->map->read = ltq_read16;
155 ltq_mtd->map->write = ltq_write16;
156 ltq_mtd->map->copy_from = ltq_copy_from;
157 ltq_mtd->map->copy_to = ltq_copy_to;
158
159 ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
160 ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
161 ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
162
163 if (!ltq_mtd->mtd) {
164 dev_err(&pdev->dev, "probing failed\n");
165 err = -ENXIO;
166 goto err_unmap;
167 }
168
169 ltq_mtd->mtd->owner = THIS_MODULE;
170
171 cfi = ltq_mtd->map->fldrv_priv;
172 cfi->addr_unlock1 ^= 1;
173 cfi->addr_unlock2 ^= 1;
174
175 nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
176 part_probe_types, &parts, 0);
177 if (nr_parts > 0) {
178 dev_info(&pdev->dev,
179 "using %d partitions from cmdline", nr_parts);
180 } else {
181 nr_parts = ltq_mtd_data->nr_parts;
182 parts = ltq_mtd_data->parts;
183 }
184
185 err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts);
186 if (err) {
187 dev_err(&pdev->dev, "failed to add partitions\n");
188 goto err_destroy;
189 }
190
191 return 0;
192
193err_destroy:
194 map_destroy(ltq_mtd->mtd);
195err_unmap:
196 iounmap(ltq_mtd->map->virt);
197err_free:
198 kfree(ltq_mtd->map);
199err_out:
200 kfree(ltq_mtd);
201 return err;
202}
203
204static int __devexit
205ltq_mtd_remove(struct platform_device *pdev)
206{
207 struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
208
209 if (ltq_mtd) {
210 if (ltq_mtd->mtd) {
211 del_mtd_partitions(ltq_mtd->mtd);
212 map_destroy(ltq_mtd->mtd);
213 }
214 if (ltq_mtd->map->virt)
215 iounmap(ltq_mtd->map->virt);
216 kfree(ltq_mtd->map);
217 kfree(ltq_mtd);
218 }
219 return 0;
220}
221
222static struct platform_driver ltq_mtd_driver = {
223 .remove = __devexit_p(ltq_mtd_remove),
224 .driver = {
225 .name = "ltq_nor",
226 .owner = THIS_MODULE,
227 },
228};
229
230static int __init
231init_ltq_mtd(void)
232{
233 int ret = platform_driver_probe(&ltq_mtd_driver, ltq_mtd_probe);
234
235 if (ret)
236 pr_err("ltq_nor: error registering platform driver");
237 return ret;
238}
239
240static void __exit
241exit_ltq_mtd(void)
242{
243 platform_driver_unregister(&ltq_mtd_driver);
244}
245
246module_init(init_ltq_mtd);
247module_exit(exit_ltq_mtd);
248
249MODULE_LICENSE("GPL");
250MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
251MODULE_DESCRIPTION("Lantiq SoC NOR");
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index a523e2a6af5..bbe168b65c2 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -694,7 +694,7 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
694 return pcmciamtd_config(link); 694 return pcmciamtd_config(link);
695} 695}
696 696
697static struct pcmcia_device_id pcmciamtd_ids[] = { 697static const struct pcmcia_device_id pcmciamtd_ids[] = {
698 PCMCIA_DEVICE_FUNC_ID(1), 698 PCMCIA_DEVICE_FUNC_ID(1),
699 PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21), 699 PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21),
700 PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21), 700 PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21),
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index d2059261ca8..f64cee4a3bf 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -56,16 +56,33 @@ static int physmap_flash_remove(struct platform_device *dev)
56 if (info->mtd[i] != NULL) 56 if (info->mtd[i] != NULL)
57 map_destroy(info->mtd[i]); 57 map_destroy(info->mtd[i]);
58 } 58 }
59
60 if (physmap_data->exit)
61 physmap_data->exit(dev);
62
59 return 0; 63 return 0;
60} 64}
61 65
66static void physmap_set_vpp(struct map_info *map, int state)
67{
68 struct platform_device *pdev;
69 struct physmap_flash_data *physmap_data;
70
71 pdev = (struct platform_device *)map->map_priv_1;
72 physmap_data = pdev->dev.platform_data;
73
74 if (physmap_data->set_vpp)
75 physmap_data->set_vpp(pdev, state);
76}
77
62static const char *rom_probe_types[] = { 78static const char *rom_probe_types[] = {
63 "cfi_probe", 79 "cfi_probe",
64 "jedec_probe", 80 "jedec_probe",
65 "qinfo_probe", 81 "qinfo_probe",
66 "map_rom", 82 "map_rom",
67 NULL }; 83 NULL };
68static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; 84static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs",
85 NULL };
69 86
70static int physmap_flash_probe(struct platform_device *dev) 87static int physmap_flash_probe(struct platform_device *dev)
71{ 88{
@@ -87,6 +104,12 @@ static int physmap_flash_probe(struct platform_device *dev)
87 goto err_out; 104 goto err_out;
88 } 105 }
89 106
107 if (physmap_data->init) {
108 err = physmap_data->init(dev);
109 if (err)
110 goto err_out;
111 }
112
90 platform_set_drvdata(dev, info); 113 platform_set_drvdata(dev, info);
91 114
92 for (i = 0; i < dev->num_resources; i++) { 115 for (i = 0; i < dev->num_resources; i++) {
@@ -107,8 +130,9 @@ static int physmap_flash_probe(struct platform_device *dev)
107 info->map[i].phys = dev->resource[i].start; 130 info->map[i].phys = dev->resource[i].start;
108 info->map[i].size = resource_size(&dev->resource[i]); 131 info->map[i].size = resource_size(&dev->resource[i]);
109 info->map[i].bankwidth = physmap_data->width; 132 info->map[i].bankwidth = physmap_data->width;
110 info->map[i].set_vpp = physmap_data->set_vpp; 133 info->map[i].set_vpp = physmap_set_vpp;
111 info->map[i].pfow_base = physmap_data->pfow_base; 134 info->map[i].pfow_base = physmap_data->pfow_base;
135 info->map[i].map_priv_1 = (unsigned long)dev;
112 136
113 info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, 137 info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys,
114 info->map[i].size); 138 info->map[i].size);
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c
index f4ce273e93f..65bd1cd4d62 100644
--- a/drivers/mtd/maps/pismo.c
+++ b/drivers/mtd/maps/pismo.c
@@ -50,39 +50,13 @@ struct pismo_data {
50 struct platform_device *dev[PISMO_NUM_CS]; 50 struct platform_device *dev[PISMO_NUM_CS];
51}; 51};
52 52
53/* FIXME: set_vpp could do with a better calling convention */ 53static void pismo_set_vpp(struct platform_device *pdev, int on)
54static struct pismo_data *vpp_pismo;
55static DEFINE_MUTEX(pismo_mutex);
56
57static int pismo_setvpp_probe_fix(struct pismo_data *pismo)
58{ 54{
59 mutex_lock(&pismo_mutex); 55 struct i2c_client *client = to_i2c_client(pdev->dev.parent);
60 if (vpp_pismo) { 56 struct pismo_data *pismo = i2c_get_clientdata(client);
61 mutex_unlock(&pismo_mutex);
62 kfree(pismo);
63 return -EBUSY;
64 }
65 vpp_pismo = pismo;
66 mutex_unlock(&pismo_mutex);
67 return 0;
68}
69
70static void pismo_setvpp_remove_fix(struct pismo_data *pismo)
71{
72 mutex_lock(&pismo_mutex);
73 if (vpp_pismo == pismo)
74 vpp_pismo = NULL;
75 mutex_unlock(&pismo_mutex);
76}
77
78static void pismo_set_vpp(struct map_info *map, int on)
79{
80 struct pismo_data *pismo = vpp_pismo;
81 57
82 pismo->vpp(pismo->vpp_data, on); 58 pismo->vpp(pismo->vpp_data, on);
83} 59}
84/* end of hack */
85
86 60
87static unsigned int __devinit pismo_width_to_bytes(unsigned int width) 61static unsigned int __devinit pismo_width_to_bytes(unsigned int width)
88{ 62{
@@ -231,9 +205,6 @@ static int __devexit pismo_remove(struct i2c_client *client)
231 for (i = 0; i < ARRAY_SIZE(pismo->dev); i++) 205 for (i = 0; i < ARRAY_SIZE(pismo->dev); i++)
232 platform_device_unregister(pismo->dev[i]); 206 platform_device_unregister(pismo->dev[i]);
233 207
234 /* FIXME: set_vpp needs saner arguments */
235 pismo_setvpp_remove_fix(pismo);
236
237 kfree(pismo); 208 kfree(pismo);
238 209
239 return 0; 210 return 0;
@@ -257,11 +228,6 @@ static int __devinit pismo_probe(struct i2c_client *client,
257 if (!pismo) 228 if (!pismo)
258 return -ENOMEM; 229 return -ENOMEM;
259 230
260 /* FIXME: set_vpp needs saner arguments */
261 ret = pismo_setvpp_probe_fix(pismo);
262 if (ret)
263 return ret;
264
265 pismo->client = client; 231 pismo->client = client;
266 if (pdata) { 232 if (pdata) {
267 pismo->vpp = pdata->set_vpp; 233 pismo->vpp = pdata->set_vpp;