diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/maps/Kconfig | 12 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/integrator-flash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/pxa2xx-flash.c | 37 | ||||
-rw-r--r-- | drivers/mtd/maps/sa1100-flash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/vmu-flash.c | 832 | ||||
-rw-r--r-- | drivers/mtd/mtdsuper.c | 7 | ||||
-rw-r--r-- | drivers/mtd/nand/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/cmx270_nand.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/excite_nandflash.c | 25 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 1 | ||||
-rw-r--r-- | drivers/mtd/onenand/generic.c | 26 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_oobtest.c | 24 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_readtest.c | 2 |
17 files changed, 915 insertions, 69 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index a2d9b95bcdd7..82923bd2d9c5 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -551,5 +551,15 @@ config MTD_PLATRAM | |||
551 | 551 | ||
552 | This selection automatically selects the map_ram driver. | 552 | This selection automatically selects the map_ram driver. |
553 | 553 | ||
554 | endmenu | 554 | config MTD_VMU |
555 | tristate "Map driver for Dreamcast VMU" | ||
556 | depends on MAPLE | ||
557 | help | ||
558 | This driver enables access to the Dreamcast Visual Memory Unit (VMU). | ||
559 | |||
560 | Most Dreamcast users will want to say Y here. | ||
555 | 561 | ||
562 | To build this as a module select M here, the module will be called | ||
563 | vmu-flash. | ||
564 | |||
565 | endmenu | ||
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index ba62013485a7..2dbc1bec8488 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o | |||
61 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o | 61 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o |
62 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o | 62 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o |
63 | obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o | 63 | obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o |
64 | obj-$(CONFIG_MTD_VMU) += vmu-flash.o | ||
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index d2ec262666c7..c9681a339a59 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/io.h> | ||
34 | 35 | ||
35 | #include <linux/mtd/mtd.h> | 36 | #include <linux/mtd/mtd.h> |
36 | #include <linux/mtd/map.h> | 37 | #include <linux/mtd/map.h> |
@@ -38,7 +39,6 @@ | |||
38 | 39 | ||
39 | #include <asm/mach/flash.h> | 40 | #include <asm/mach/flash.h> |
40 | #include <mach/hardware.h> | 41 | #include <mach/hardware.h> |
41 | #include <asm/io.h> | ||
42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
43 | 43 | ||
44 | #ifdef CONFIG_ARCH_P720T | 44 | #ifdef CONFIG_ARCH_P720T |
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 771139c5bf87..572d32fdf38a 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info { | |||
41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
42 | 42 | ||
43 | 43 | ||
44 | static int __init pxa2xx_flash_probe(struct device *dev) | 44 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) |
45 | { | 45 | { |
46 | struct platform_device *pdev = to_platform_device(dev); | ||
47 | struct flash_platform_data *flash = pdev->dev.platform_data; | 46 | struct flash_platform_data *flash = pdev->dev.platform_data; |
48 | struct pxa2xx_flash_info *info; | 47 | struct pxa2xx_flash_info *info; |
49 | struct mtd_partition *parts; | 48 | struct mtd_partition *parts; |
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev) | |||
114 | add_mtd_device(info->mtd); | 113 | add_mtd_device(info->mtd); |
115 | } | 114 | } |
116 | 115 | ||
117 | dev_set_drvdata(dev, info); | 116 | platform_set_drvdata(pdev, info); |
118 | return 0; | 117 | return 0; |
119 | } | 118 | } |
120 | 119 | ||
121 | static int __exit pxa2xx_flash_remove(struct device *dev) | 120 | static int __devexit pxa2xx_flash_remove(struct platform_device *dev) |
122 | { | 121 | { |
123 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 122 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
124 | 123 | ||
125 | dev_set_drvdata(dev, NULL); | 124 | platform_set_drvdata(dev, NULL); |
126 | 125 | ||
127 | #ifdef CONFIG_MTD_PARTITIONS | 126 | #ifdef CONFIG_MTD_PARTITIONS |
128 | if (info->nr_parts) | 127 | if (info->nr_parts) |
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev) | |||
141 | } | 140 | } |
142 | 141 | ||
143 | #ifdef CONFIG_PM | 142 | #ifdef CONFIG_PM |
144 | static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state) | 143 | static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state) |
145 | { | 144 | { |
146 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 145 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
147 | int ret = 0; | 146 | int ret = 0; |
148 | 147 | ||
149 | if (info->mtd && info->mtd->suspend) | 148 | if (info->mtd && info->mtd->suspend) |
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state) | |||
151 | return ret; | 150 | return ret; |
152 | } | 151 | } |
153 | 152 | ||
154 | static int pxa2xx_flash_resume(struct device *dev) | 153 | static int pxa2xx_flash_resume(struct platform_device *dev) |
155 | { | 154 | { |
156 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 155 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
157 | 156 | ||
158 | if (info->mtd && info->mtd->resume) | 157 | if (info->mtd && info->mtd->resume) |
159 | info->mtd->resume(info->mtd); | 158 | info->mtd->resume(info->mtd); |
160 | return 0; | 159 | return 0; |
161 | } | 160 | } |
162 | static void pxa2xx_flash_shutdown(struct device *dev) | 161 | static void pxa2xx_flash_shutdown(struct platform_device *dev) |
163 | { | 162 | { |
164 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 163 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
165 | 164 | ||
166 | if (info && info->mtd->suspend(info->mtd) == 0) | 165 | if (info && info->mtd->suspend(info->mtd) == 0) |
167 | info->mtd->resume(info->mtd); | 166 | info->mtd->resume(info->mtd); |
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev) | |||
172 | #define pxa2xx_flash_shutdown NULL | 171 | #define pxa2xx_flash_shutdown NULL |
173 | #endif | 172 | #endif |
174 | 173 | ||
175 | static struct device_driver pxa2xx_flash_driver = { | 174 | static struct platform_driver pxa2xx_flash_driver = { |
176 | .name = "pxa2xx-flash", | 175 | .driver = { |
177 | .bus = &platform_bus_type, | 176 | .name = "pxa2xx-flash", |
177 | .owner = THIS_MODULE, | ||
178 | }, | ||
178 | .probe = pxa2xx_flash_probe, | 179 | .probe = pxa2xx_flash_probe, |
179 | .remove = __exit_p(pxa2xx_flash_remove), | 180 | .remove = __devexit_p(pxa2xx_flash_remove), |
180 | .suspend = pxa2xx_flash_suspend, | 181 | .suspend = pxa2xx_flash_suspend, |
181 | .resume = pxa2xx_flash_resume, | 182 | .resume = pxa2xx_flash_resume, |
182 | .shutdown = pxa2xx_flash_shutdown, | 183 | .shutdown = pxa2xx_flash_shutdown, |
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = { | |||
184 | 185 | ||
185 | static int __init init_pxa2xx_flash(void) | 186 | static int __init init_pxa2xx_flash(void) |
186 | { | 187 | { |
187 | return driver_register(&pxa2xx_flash_driver); | 188 | return platform_driver_register(&pxa2xx_flash_driver); |
188 | } | 189 | } |
189 | 190 | ||
190 | static void __exit cleanup_pxa2xx_flash(void) | 191 | static void __exit cleanup_pxa2xx_flash(void) |
191 | { | 192 | { |
192 | driver_unregister(&pxa2xx_flash_driver); | 193 | platform_driver_unregister(&pxa2xx_flash_driver); |
193 | } | 194 | } |
194 | 195 | ||
195 | module_init(init_pxa2xx_flash); | 196 | module_init(init_pxa2xx_flash); |
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 1757ab01b0e4..05e9362dc7f0 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/io.h> | ||
15 | 16 | ||
16 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
17 | #include <linux/mtd/map.h> | 18 | #include <linux/mtd/map.h> |
@@ -19,7 +20,6 @@ | |||
19 | #include <linux/mtd/concat.h> | 20 | #include <linux/mtd/concat.h> |
20 | 21 | ||
21 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
22 | #include <asm/io.h> | ||
23 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
24 | #include <asm/mach/flash.h> | 24 | #include <asm/mach/flash.h> |
25 | 25 | ||
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c new file mode 100644 index 000000000000..1f73297e7776 --- /dev/null +++ b/drivers/mtd/maps/vmu-flash.c | |||
@@ -0,0 +1,832 @@ | |||
1 | /* vmu-flash.c | ||
2 | * Driver for SEGA Dreamcast Visual Memory Unit | ||
3 | * | ||
4 | * Copyright (c) Adrian McMenamin 2002 - 2009 | ||
5 | * Copyright (c) Paul Mundt 2001 | ||
6 | * | ||
7 | * Licensed under version 2 of the | ||
8 | * GNU General Public Licence | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/maple.h> | ||
14 | #include <linux/mtd/mtd.h> | ||
15 | #include <linux/mtd/map.h> | ||
16 | |||
17 | struct vmu_cache { | ||
18 | unsigned char *buffer; /* Cache */ | ||
19 | unsigned int block; /* Which block was cached */ | ||
20 | unsigned long jiffies_atc; /* When was it cached? */ | ||
21 | int valid; | ||
22 | }; | ||
23 | |||
24 | struct mdev_part { | ||
25 | struct maple_device *mdev; | ||
26 | int partition; | ||
27 | }; | ||
28 | |||
29 | struct vmupart { | ||
30 | u16 user_blocks; | ||
31 | u16 root_block; | ||
32 | u16 numblocks; | ||
33 | char *name; | ||
34 | struct vmu_cache *pcache; | ||
35 | }; | ||
36 | |||
37 | struct memcard { | ||
38 | u16 tempA; | ||
39 | u16 tempB; | ||
40 | u32 partitions; | ||
41 | u32 blocklen; | ||
42 | u32 writecnt; | ||
43 | u32 readcnt; | ||
44 | u32 removeable; | ||
45 | int partition; | ||
46 | int read; | ||
47 | unsigned char *blockread; | ||
48 | struct vmupart *parts; | ||
49 | struct mtd_info *mtd; | ||
50 | }; | ||
51 | |||
52 | struct vmu_block { | ||
53 | unsigned int num; /* block number */ | ||
54 | unsigned int ofs; /* block offset */ | ||
55 | }; | ||
56 | |||
57 | static struct vmu_block *ofs_to_block(unsigned long src_ofs, | ||
58 | struct mtd_info *mtd, int partition) | ||
59 | { | ||
60 | struct vmu_block *vblock; | ||
61 | struct maple_device *mdev; | ||
62 | struct memcard *card; | ||
63 | struct mdev_part *mpart; | ||
64 | int num; | ||
65 | |||
66 | mpart = mtd->priv; | ||
67 | mdev = mpart->mdev; | ||
68 | card = maple_get_drvdata(mdev); | ||
69 | |||
70 | if (src_ofs >= card->parts[partition].numblocks * card->blocklen) | ||
71 | goto failed; | ||
72 | |||
73 | num = src_ofs / card->blocklen; | ||
74 | if (num > card->parts[partition].numblocks) | ||
75 | goto failed; | ||
76 | |||
77 | vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL); | ||
78 | if (!vblock) | ||
79 | goto failed; | ||
80 | |||
81 | vblock->num = num; | ||
82 | vblock->ofs = src_ofs % card->blocklen; | ||
83 | return vblock; | ||
84 | |||
85 | failed: | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | /* Maple bus callback function for reads */ | ||
90 | static void vmu_blockread(struct mapleq *mq) | ||
91 | { | ||
92 | struct maple_device *mdev; | ||
93 | struct memcard *card; | ||
94 | |||
95 | mdev = mq->dev; | ||
96 | card = maple_get_drvdata(mdev); | ||
97 | /* copy the read in data */ | ||
98 | |||
99 | if (unlikely(!card->blockread)) | ||
100 | return; | ||
101 | |||
102 | memcpy(card->blockread, mq->recvbuf->buf + 12, | ||
103 | card->blocklen/card->readcnt); | ||
104 | |||
105 | } | ||
106 | |||
107 | /* Interface with maple bus to read blocks | ||
108 | * caching the results so that other parts | ||
109 | * of the driver can access block reads */ | ||
110 | static int maple_vmu_read_block(unsigned int num, unsigned char *buf, | ||
111 | struct mtd_info *mtd) | ||
112 | { | ||
113 | struct memcard *card; | ||
114 | struct mdev_part *mpart; | ||
115 | struct maple_device *mdev; | ||
116 | int partition, error = 0, x, wait; | ||
117 | unsigned char *blockread = NULL; | ||
118 | struct vmu_cache *pcache; | ||
119 | __be32 sendbuf; | ||
120 | |||
121 | mpart = mtd->priv; | ||
122 | mdev = mpart->mdev; | ||
123 | partition = mpart->partition; | ||
124 | card = maple_get_drvdata(mdev); | ||
125 | pcache = card->parts[partition].pcache; | ||
126 | pcache->valid = 0; | ||
127 | |||
128 | /* prepare the cache for this block */ | ||
129 | if (!pcache->buffer) { | ||
130 | pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL); | ||
131 | if (!pcache->buffer) { | ||
132 | dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due" | ||
133 | " to lack of memory\n", mdev->port, | ||
134 | mdev->unit); | ||
135 | error = -ENOMEM; | ||
136 | goto outB; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Reads may be phased - again the hardware spec | ||
142 | * supports this - though may not be any devices in | ||
143 | * the wild that implement it, but we will here | ||
144 | */ | ||
145 | for (x = 0; x < card->readcnt; x++) { | ||
146 | sendbuf = cpu_to_be32(partition << 24 | x << 16 | num); | ||
147 | |||
148 | if (atomic_read(&mdev->busy) == 1) { | ||
149 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
150 | atomic_read(&mdev->busy) == 0, HZ); | ||
151 | if (atomic_read(&mdev->busy) == 1) { | ||
152 | dev_notice(&mdev->dev, "VMU at (%d, %d)" | ||
153 | " is busy\n", mdev->port, mdev->unit); | ||
154 | error = -EAGAIN; | ||
155 | goto outB; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | atomic_set(&mdev->busy, 1); | ||
160 | blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL); | ||
161 | if (!blockread) { | ||
162 | error = -ENOMEM; | ||
163 | atomic_set(&mdev->busy, 0); | ||
164 | goto outB; | ||
165 | } | ||
166 | card->blockread = blockread; | ||
167 | |||
168 | maple_getcond_callback(mdev, vmu_blockread, 0, | ||
169 | MAPLE_FUNC_MEMCARD); | ||
170 | error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
171 | MAPLE_COMMAND_BREAD, 2, &sendbuf); | ||
172 | /* Very long timeouts seem to be needed when box is stressed */ | ||
173 | wait = wait_event_interruptible_timeout(mdev->maple_wait, | ||
174 | (atomic_read(&mdev->busy) == 0 || | ||
175 | atomic_read(&mdev->busy) == 2), HZ * 3); | ||
176 | /* | ||
177 | * MTD layer does not handle hotplugging well | ||
178 | * so have to return errors when VMU is unplugged | ||
179 | * in the middle of a read (busy == 2) | ||
180 | */ | ||
181 | if (error || atomic_read(&mdev->busy) == 2) { | ||
182 | if (atomic_read(&mdev->busy) == 2) | ||
183 | error = -ENXIO; | ||
184 | atomic_set(&mdev->busy, 0); | ||
185 | card->blockread = NULL; | ||
186 | goto outA; | ||
187 | } | ||
188 | if (wait == 0 || wait == -ERESTARTSYS) { | ||
189 | card->blockread = NULL; | ||
190 | atomic_set(&mdev->busy, 0); | ||
191 | error = -EIO; | ||
192 | list_del_init(&(mdev->mq->list)); | ||
193 | kfree(mdev->mq->sendbuf); | ||
194 | mdev->mq->sendbuf = NULL; | ||
195 | if (wait == -ERESTARTSYS) { | ||
196 | dev_warn(&mdev->dev, "VMU read on (%d, %d)" | ||
197 | " interrupted on block 0x%X\n", | ||
198 | mdev->port, mdev->unit, num); | ||
199 | } else | ||
200 | dev_notice(&mdev->dev, "VMU read on (%d, %d)" | ||
201 | " timed out on block 0x%X\n", | ||
202 | mdev->port, mdev->unit, num); | ||
203 | goto outA; | ||
204 | } | ||
205 | |||
206 | memcpy(buf + (card->blocklen/card->readcnt) * x, blockread, | ||
207 | card->blocklen/card->readcnt); | ||
208 | |||
209 | memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x, | ||
210 | card->blockread, card->blocklen/card->readcnt); | ||
211 | card->blockread = NULL; | ||
212 | pcache->block = num; | ||
213 | pcache->jiffies_atc = jiffies; | ||
214 | pcache->valid = 1; | ||
215 | kfree(blockread); | ||
216 | } | ||
217 | |||
218 | return error; | ||
219 | |||
220 | outA: | ||
221 | kfree(blockread); | ||
222 | outB: | ||
223 | return error; | ||
224 | } | ||
225 | |||
226 | /* communicate with maple bus for phased writing */ | ||
227 | static int maple_vmu_write_block(unsigned int num, const unsigned char *buf, | ||
228 | struct mtd_info *mtd) | ||
229 | { | ||
230 | struct memcard *card; | ||
231 | struct mdev_part *mpart; | ||
232 | struct maple_device *mdev; | ||
233 | int partition, error, locking, x, phaselen, wait; | ||
234 | __be32 *sendbuf; | ||
235 | |||
236 | mpart = mtd->priv; | ||
237 | mdev = mpart->mdev; | ||
238 | partition = mpart->partition; | ||
239 | card = maple_get_drvdata(mdev); | ||
240 | |||
241 | phaselen = card->blocklen/card->writecnt; | ||
242 | |||
243 | sendbuf = kmalloc(phaselen + 4, GFP_KERNEL); | ||
244 | if (!sendbuf) { | ||
245 | error = -ENOMEM; | ||
246 | goto fail_nosendbuf; | ||
247 | } | ||
248 | for (x = 0; x < card->writecnt; x++) { | ||
249 | sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num); | ||
250 | memcpy(&sendbuf[1], buf + phaselen * x, phaselen); | ||
251 | /* wait until the device is not busy doing something else | ||
252 | * or 1 second - which ever is longer */ | ||
253 | if (atomic_read(&mdev->busy) == 1) { | ||
254 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
255 | atomic_read(&mdev->busy) == 0, HZ); | ||
256 | if (atomic_read(&mdev->busy) == 1) { | ||
257 | error = -EBUSY; | ||
258 | dev_notice(&mdev->dev, "VMU write at (%d, %d)" | ||
259 | "failed - device is busy\n", | ||
260 | mdev->port, mdev->unit); | ||
261 | goto fail_nolock; | ||
262 | } | ||
263 | } | ||
264 | atomic_set(&mdev->busy, 1); | ||
265 | |||
266 | locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
267 | MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf); | ||
268 | wait = wait_event_interruptible_timeout(mdev->maple_wait, | ||
269 | atomic_read(&mdev->busy) == 0, HZ/10); | ||
270 | if (locking) { | ||
271 | error = -EIO; | ||
272 | atomic_set(&mdev->busy, 0); | ||
273 | goto fail_nolock; | ||
274 | } | ||
275 | if (atomic_read(&mdev->busy) == 2) { | ||
276 | atomic_set(&mdev->busy, 0); | ||
277 | } else if (wait == 0 || wait == -ERESTARTSYS) { | ||
278 | error = -EIO; | ||
279 | dev_warn(&mdev->dev, "Write at (%d, %d) of block" | ||
280 | " 0x%X at phase %d failed: could not" | ||
281 | " communicate with VMU", mdev->port, | ||
282 | mdev->unit, num, x); | ||
283 | atomic_set(&mdev->busy, 0); | ||
284 | kfree(mdev->mq->sendbuf); | ||
285 | mdev->mq->sendbuf = NULL; | ||
286 | list_del_init(&(mdev->mq->list)); | ||
287 | goto fail_nolock; | ||
288 | } | ||
289 | } | ||
290 | kfree(sendbuf); | ||
291 | |||
292 | return card->blocklen; | ||
293 | |||
294 | fail_nolock: | ||
295 | kfree(sendbuf); | ||
296 | fail_nosendbuf: | ||
297 | dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port, | ||
298 | mdev->unit); | ||
299 | return error; | ||
300 | } | ||
301 | |||
302 | /* mtd function to simulate reading byte by byte */ | ||
303 | static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval, | ||
304 | struct mtd_info *mtd) | ||
305 | { | ||
306 | struct vmu_block *vblock; | ||
307 | struct memcard *card; | ||
308 | struct mdev_part *mpart; | ||
309 | struct maple_device *mdev; | ||
310 | unsigned char *buf, ret; | ||
311 | int partition, error; | ||
312 | |||
313 | mpart = mtd->priv; | ||
314 | mdev = mpart->mdev; | ||
315 | partition = mpart->partition; | ||
316 | card = maple_get_drvdata(mdev); | ||
317 | *retval = 0; | ||
318 | |||
319 | buf = kmalloc(card->blocklen, GFP_KERNEL); | ||
320 | if (!buf) { | ||
321 | *retval = 1; | ||
322 | ret = -ENOMEM; | ||
323 | goto finish; | ||
324 | } | ||
325 | |||
326 | vblock = ofs_to_block(ofs, mtd, partition); | ||
327 | if (!vblock) { | ||
328 | *retval = 3; | ||
329 | ret = -ENOMEM; | ||
330 | goto out_buf; | ||
331 | } | ||
332 | |||
333 | error = maple_vmu_read_block(vblock->num, buf, mtd); | ||
334 | if (error) { | ||
335 | ret = error; | ||
336 | *retval = 2; | ||
337 | goto out_vblock; | ||
338 | } | ||
339 | |||
340 | ret = buf[vblock->ofs]; | ||
341 | |||
342 | out_vblock: | ||
343 | kfree(vblock); | ||
344 | out_buf: | ||
345 | kfree(buf); | ||
346 | finish: | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | /* mtd higher order function to read flash */ | ||
351 | static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
352 | size_t *retlen, u_char *buf) | ||
353 | { | ||
354 | struct maple_device *mdev; | ||
355 | struct memcard *card; | ||
356 | struct mdev_part *mpart; | ||
357 | struct vmu_cache *pcache; | ||
358 | struct vmu_block *vblock; | ||
359 | int index = 0, retval, partition, leftover, numblocks; | ||
360 | unsigned char cx; | ||
361 | |||
362 | if (len < 1) | ||
363 | return -EIO; | ||
364 | |||
365 | mpart = mtd->priv; | ||
366 | mdev = mpart->mdev; | ||
367 | partition = mpart->partition; | ||
368 | card = maple_get_drvdata(mdev); | ||
369 | |||
370 | numblocks = card->parts[partition].numblocks; | ||
371 | if (from + len > numblocks * card->blocklen) | ||
372 | len = numblocks * card->blocklen - from; | ||
373 | if (len == 0) | ||
374 | return -EIO; | ||
375 | /* Have we cached this bit already? */ | ||
376 | pcache = card->parts[partition].pcache; | ||
377 | do { | ||
378 | vblock = ofs_to_block(from + index, mtd, partition); | ||
379 | if (!vblock) | ||
380 | return -ENOMEM; | ||
381 | /* Have we cached this and is the cache valid and timely? */ | ||
382 | if (pcache->valid && | ||
383 | time_before(jiffies, pcache->jiffies_atc + HZ) && | ||
384 | (pcache->block == vblock->num)) { | ||
385 | /* we have cached it, so do necessary copying */ | ||
386 | leftover = card->blocklen - vblock->ofs; | ||
387 | if (vblock->ofs + len - index < card->blocklen) { | ||
388 | /* only a bit of this block to copy */ | ||
389 | memcpy(buf + index, | ||
390 | pcache->buffer + vblock->ofs, | ||
391 | len - index); | ||
392 | index = len; | ||
393 | } else { | ||
394 | /* otherwise copy remainder of whole block */ | ||
395 | memcpy(buf + index, pcache->buffer + | ||
396 | vblock->ofs, leftover); | ||
397 | index += leftover; | ||
398 | } | ||
399 | } else { | ||
400 | /* | ||
401 | * Not cached so read one byte - | ||
402 | * but cache the rest of the block | ||
403 | */ | ||
404 | cx = vmu_flash_read_char(from + index, &retval, mtd); | ||
405 | if (retval) { | ||
406 | *retlen = index; | ||
407 | kfree(vblock); | ||
408 | return cx; | ||
409 | } | ||
410 | memset(buf + index, cx, 1); | ||
411 | index++; | ||
412 | } | ||
413 | kfree(vblock); | ||
414 | } while (len > index); | ||
415 | *retlen = index; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
421 | size_t *retlen, const u_char *buf) | ||
422 | { | ||
423 | struct maple_device *mdev; | ||
424 | struct memcard *card; | ||
425 | struct mdev_part *mpart; | ||
426 | int index = 0, partition, error = 0, numblocks; | ||
427 | struct vmu_cache *pcache; | ||
428 | struct vmu_block *vblock; | ||
429 | unsigned char *buffer; | ||
430 | |||
431 | mpart = mtd->priv; | ||
432 | mdev = mpart->mdev; | ||
433 | partition = mpart->partition; | ||
434 | card = maple_get_drvdata(mdev); | ||
435 | |||
436 | /* simple sanity checks */ | ||
437 | if (len < 1) { | ||
438 | error = -EIO; | ||
439 | goto failed; | ||
440 | } | ||
441 | numblocks = card->parts[partition].numblocks; | ||
442 | if (to + len > numblocks * card->blocklen) | ||
443 | len = numblocks * card->blocklen - to; | ||
444 | if (len == 0) { | ||
445 | error = -EIO; | ||
446 | goto failed; | ||
447 | } | ||
448 | |||
449 | vblock = ofs_to_block(to, mtd, partition); | ||
450 | if (!vblock) { | ||
451 | error = -ENOMEM; | ||
452 | goto failed; | ||
453 | } | ||
454 | |||
455 | buffer = kmalloc(card->blocklen, GFP_KERNEL); | ||
456 | if (!buffer) { | ||
457 | error = -ENOMEM; | ||
458 | goto fail_buffer; | ||
459 | } | ||
460 | |||
461 | do { | ||
462 | /* Read in the block we are to write to */ | ||
463 | error = maple_vmu_read_block(vblock->num, buffer, mtd); | ||
464 | if (error) | ||
465 | goto fail_io; | ||
466 | |||
467 | do { | ||
468 | buffer[vblock->ofs] = buf[index]; | ||
469 | vblock->ofs++; | ||
470 | index++; | ||
471 | if (index >= len) | ||
472 | break; | ||
473 | } while (vblock->ofs < card->blocklen); | ||
474 | |||
475 | /* write out new buffer */ | ||
476 | error = maple_vmu_write_block(vblock->num, buffer, mtd); | ||
477 | /* invalidate the cache */ | ||
478 | pcache = card->parts[partition].pcache; | ||
479 | pcache->valid = 0; | ||
480 | |||
481 | if (error != card->blocklen) | ||
482 | goto fail_io; | ||
483 | |||
484 | vblock->num++; | ||
485 | vblock->ofs = 0; | ||
486 | } while (len > index); | ||
487 | |||
488 | kfree(buffer); | ||
489 | *retlen = index; | ||
490 | kfree(vblock); | ||
491 | return 0; | ||
492 | |||
493 | fail_io: | ||
494 | kfree(buffer); | ||
495 | fail_buffer: | ||
496 | kfree(vblock); | ||
497 | failed: | ||
498 | dev_err(&mdev->dev, "VMU write failing with error %d\n", error); | ||
499 | return error; | ||
500 | } | ||
501 | |||
502 | static void vmu_flash_sync(struct mtd_info *mtd) | ||
503 | { | ||
504 | /* Do nothing here */ | ||
505 | } | ||
506 | |||
507 | /* Maple bus callback function to recursively query hardware details */ | ||
508 | static void vmu_queryblocks(struct mapleq *mq) | ||
509 | { | ||
510 | struct maple_device *mdev; | ||
511 | unsigned short *res; | ||
512 | struct memcard *card; | ||
513 | __be32 partnum; | ||
514 | struct vmu_cache *pcache; | ||
515 | struct mdev_part *mpart; | ||
516 | struct mtd_info *mtd_cur; | ||
517 | struct vmupart *part_cur; | ||
518 | int error; | ||
519 | |||
520 | mdev = mq->dev; | ||
521 | card = maple_get_drvdata(mdev); | ||
522 | res = (unsigned short *) (mq->recvbuf->buf); | ||
523 | card->tempA = res[12]; | ||
524 | card->tempB = res[6]; | ||
525 | |||
526 | dev_info(&mdev->dev, "VMU device at partition %d has %d user " | ||
527 | "blocks with a root block at %d\n", card->partition, | ||
528 | card->tempA, card->tempB); | ||
529 | |||
530 | part_cur = &card->parts[card->partition]; | ||
531 | part_cur->user_blocks = card->tempA; | ||
532 | part_cur->root_block = card->tempB; | ||
533 | part_cur->numblocks = card->tempB + 1; | ||
534 | part_cur->name = kmalloc(12, GFP_KERNEL); | ||
535 | if (!part_cur->name) | ||
536 | goto fail_name; | ||
537 | |||
538 | sprintf(part_cur->name, "vmu%d.%d.%d", | ||
539 | mdev->port, mdev->unit, card->partition); | ||
540 | mtd_cur = &card->mtd[card->partition]; | ||
541 | mtd_cur->name = part_cur->name; | ||
542 | mtd_cur->type = 8; | ||
543 | mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE; | ||
544 | mtd_cur->size = part_cur->numblocks * card->blocklen; | ||
545 | mtd_cur->erasesize = card->blocklen; | ||
546 | mtd_cur->write = vmu_flash_write; | ||
547 | mtd_cur->read = vmu_flash_read; | ||
548 | mtd_cur->sync = vmu_flash_sync; | ||
549 | mtd_cur->writesize = card->blocklen; | ||
550 | |||
551 | mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL); | ||
552 | if (!mpart) | ||
553 | goto fail_mpart; | ||
554 | |||
555 | mpart->mdev = mdev; | ||
556 | mpart->partition = card->partition; | ||
557 | mtd_cur->priv = mpart; | ||
558 | mtd_cur->owner = THIS_MODULE; | ||
559 | |||
560 | pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL); | ||
561 | if (!pcache) | ||
562 | goto fail_cache_create; | ||
563 | part_cur->pcache = pcache; | ||
564 | |||
565 | error = add_mtd_device(mtd_cur); | ||
566 | if (error) | ||
567 | goto fail_mtd_register; | ||
568 | |||
569 | maple_getcond_callback(mdev, NULL, 0, | ||
570 | MAPLE_FUNC_MEMCARD); | ||
571 | |||
572 | /* | ||
573 | * Set up a recursive call to the (probably theoretical) | ||
574 | * second or more partition | ||
575 | */ | ||
576 | if (++card->partition < card->partitions) { | ||
577 | partnum = cpu_to_be32(card->partition << 24); | ||
578 | maple_getcond_callback(mdev, vmu_queryblocks, 0, | ||
579 | MAPLE_FUNC_MEMCARD); | ||
580 | maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
581 | MAPLE_COMMAND_GETMINFO, 2, &partnum); | ||
582 | } | ||
583 | return; | ||
584 | |||
585 | fail_mtd_register: | ||
586 | dev_err(&mdev->dev, "Could not register maple device at (%d, %d)" | ||
587 | "error is 0x%X\n", mdev->port, mdev->unit, error); | ||
588 | for (error = 0; error <= card->partition; error++) { | ||
589 | kfree(((card->parts)[error]).pcache); | ||
590 | ((card->parts)[error]).pcache = NULL; | ||
591 | } | ||
592 | fail_cache_create: | ||
593 | fail_mpart: | ||
594 | for (error = 0; error <= card->partition; error++) { | ||
595 | kfree(((card->mtd)[error]).priv); | ||
596 | ((card->mtd)[error]).priv = NULL; | ||
597 | } | ||
598 | maple_getcond_callback(mdev, NULL, 0, | ||
599 | MAPLE_FUNC_MEMCARD); | ||
600 | kfree(part_cur->name); | ||
601 | fail_name: | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | /* Handles very basic info about the flash, queries for details */ | ||
606 | static int __devinit vmu_connect(struct maple_device *mdev) | ||
607 | { | ||
608 | unsigned long test_flash_data, basic_flash_data; | ||
609 | int c, error; | ||
610 | struct memcard *card; | ||
611 | u32 partnum = 0; | ||
612 | |||
613 | test_flash_data = be32_to_cpu(mdev->devinfo.function); | ||
614 | /* Need to count how many bits are set - to find out which | ||
615 | * function_data element has details of the memory card: | ||
616 | * using Brian Kernighan's/Peter Wegner's method */ | ||
617 | for (c = 0; test_flash_data; c++) | ||
618 | test_flash_data &= test_flash_data - 1; | ||
619 | |||
620 | basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]); | ||
621 | |||
622 | card = kmalloc(sizeof(struct memcard), GFP_KERNEL); | ||
623 | if (!card) { | ||
624 | error = ENOMEM; | ||
625 | goto fail_nomem; | ||
626 | } | ||
627 | |||
628 | card->partitions = (basic_flash_data >> 24 & 0xFF) + 1; | ||
629 | card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5; | ||
630 | card->writecnt = basic_flash_data >> 12 & 0xF; | ||
631 | card->readcnt = basic_flash_data >> 8 & 0xF; | ||
632 | card->removeable = basic_flash_data >> 7 & 1; | ||
633 | |||
634 | card->partition = 0; | ||
635 | |||
636 | /* | ||
637 | * Not sure there are actually any multi-partition devices in the | ||
638 | * real world, but the hardware supports them, so, so will we | ||
639 | */ | ||
640 | card->parts = kmalloc(sizeof(struct vmupart) * card->partitions, | ||
641 | GFP_KERNEL); | ||
642 | if (!card->parts) { | ||
643 | error = -ENOMEM; | ||
644 | goto fail_partitions; | ||
645 | } | ||
646 | |||
647 | card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions, | ||
648 | GFP_KERNEL); | ||
649 | if (!card->mtd) { | ||
650 | error = -ENOMEM; | ||
651 | goto fail_mtd_info; | ||
652 | } | ||
653 | |||
654 | maple_set_drvdata(mdev, card); | ||
655 | |||
656 | /* | ||
657 | * We want to trap meminfo not get cond | ||
658 | * so set interval to zero, but rely on maple bus | ||
659 | * driver to pass back the results of the meminfo | ||
660 | */ | ||
661 | maple_getcond_callback(mdev, vmu_queryblocks, 0, | ||
662 | MAPLE_FUNC_MEMCARD); | ||
663 | |||
664 | /* Make sure we are clear to go */ | ||
665 | if (atomic_read(&mdev->busy) == 1) { | ||
666 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
667 | atomic_read(&mdev->busy) == 0, HZ); | ||
668 | if (atomic_read(&mdev->busy) == 1) { | ||
669 | dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n", | ||
670 | mdev->port, mdev->unit); | ||
671 | error = -EAGAIN; | ||
672 | goto fail_device_busy; | ||
673 | } | ||
674 | } | ||
675 | |||
676 | atomic_set(&mdev->busy, 1); | ||
677 | |||
678 | /* | ||
679 | * Set up the minfo call: vmu_queryblocks will handle | ||
680 | * the information passed back | ||
681 | */ | ||
682 | error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
683 | MAPLE_COMMAND_GETMINFO, 2, &partnum); | ||
684 | if (error) { | ||
685 | dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)" | ||
686 | " error is 0x%X\n", mdev->port, mdev->unit, error); | ||
687 | goto fail_mtd_info; | ||
688 | } | ||
689 | return 0; | ||
690 | |||
691 | fail_device_busy: | ||
692 | kfree(card->mtd); | ||
693 | fail_mtd_info: | ||
694 | kfree(card->parts); | ||
695 | fail_partitions: | ||
696 | kfree(card); | ||
697 | fail_nomem: | ||
698 | return error; | ||
699 | } | ||
700 | |||
701 | static void __devexit vmu_disconnect(struct maple_device *mdev) | ||
702 | { | ||
703 | struct memcard *card; | ||
704 | struct mdev_part *mpart; | ||
705 | int x; | ||
706 | |||
707 | mdev->callback = NULL; | ||
708 | card = maple_get_drvdata(mdev); | ||
709 | for (x = 0; x < card->partitions; x++) { | ||
710 | mpart = ((card->mtd)[x]).priv; | ||
711 | mpart->mdev = NULL; | ||
712 | del_mtd_device(&((card->mtd)[x])); | ||
713 | kfree(((card->parts)[x]).name); | ||
714 | } | ||
715 | kfree(card->parts); | ||
716 | kfree(card->mtd); | ||
717 | kfree(card); | ||
718 | } | ||
719 | |||
720 | /* Callback to handle eccentricities of both mtd subsystem | ||
721 | * and general flakyness of Dreamcast VMUs | ||
722 | */ | ||
723 | static int vmu_can_unload(struct maple_device *mdev) | ||
724 | { | ||
725 | struct memcard *card; | ||
726 | int x; | ||
727 | struct mtd_info *mtd; | ||
728 | |||
729 | card = maple_get_drvdata(mdev); | ||
730 | for (x = 0; x < card->partitions; x++) { | ||
731 | mtd = &((card->mtd)[x]); | ||
732 | if (mtd->usecount > 0) | ||
733 | return 0; | ||
734 | } | ||
735 | return 1; | ||
736 | } | ||
737 | |||
738 | #define ERRSTR "VMU at (%d, %d) file error -" | ||
739 | |||
740 | static void vmu_file_error(struct maple_device *mdev, void *recvbuf) | ||
741 | { | ||
742 | enum maple_file_errors error = ((int *)recvbuf)[1]; | ||
743 | |||
744 | switch (error) { | ||
745 | |||
746 | case MAPLE_FILEERR_INVALID_PARTITION: | ||
747 | dev_notice(&mdev->dev, ERRSTR " invalid partition number\n", | ||
748 | mdev->port, mdev->unit); | ||
749 | break; | ||
750 | |||
751 | case MAPLE_FILEERR_PHASE_ERROR: | ||
752 | dev_notice(&mdev->dev, ERRSTR " phase error\n", | ||
753 | mdev->port, mdev->unit); | ||
754 | break; | ||
755 | |||
756 | case MAPLE_FILEERR_INVALID_BLOCK: | ||
757 | dev_notice(&mdev->dev, ERRSTR " invalid block number\n", | ||
758 | mdev->port, mdev->unit); | ||
759 | break; | ||
760 | |||
761 | case MAPLE_FILEERR_WRITE_ERROR: | ||
762 | dev_notice(&mdev->dev, ERRSTR " write error\n", | ||
763 | mdev->port, mdev->unit); | ||
764 | break; | ||
765 | |||
766 | case MAPLE_FILEERR_INVALID_WRITE_LENGTH: | ||
767 | dev_notice(&mdev->dev, ERRSTR " invalid write length\n", | ||
768 | mdev->port, mdev->unit); | ||
769 | break; | ||
770 | |||
771 | case MAPLE_FILEERR_BAD_CRC: | ||
772 | dev_notice(&mdev->dev, ERRSTR " bad CRC\n", | ||
773 | mdev->port, mdev->unit); | ||
774 | break; | ||
775 | |||
776 | default: | ||
777 | dev_notice(&mdev->dev, ERRSTR " 0x%X\n", | ||
778 | mdev->port, mdev->unit, error); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | |||
783 | static int __devinit probe_maple_vmu(struct device *dev) | ||
784 | { | ||
785 | int error; | ||
786 | struct maple_device *mdev = to_maple_dev(dev); | ||
787 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | ||
788 | |||
789 | mdev->can_unload = vmu_can_unload; | ||
790 | mdev->fileerr_handler = vmu_file_error; | ||
791 | mdev->driver = mdrv; | ||
792 | |||
793 | error = vmu_connect(mdev); | ||
794 | if (error) | ||
795 | return error; | ||
796 | |||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | static int __devexit remove_maple_vmu(struct device *dev) | ||
801 | { | ||
802 | struct maple_device *mdev = to_maple_dev(dev); | ||
803 | |||
804 | vmu_disconnect(mdev); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | static struct maple_driver vmu_flash_driver = { | ||
809 | .function = MAPLE_FUNC_MEMCARD, | ||
810 | .drv = { | ||
811 | .name = "Dreamcast_visual_memory", | ||
812 | .probe = probe_maple_vmu, | ||
813 | .remove = __devexit_p(remove_maple_vmu), | ||
814 | }, | ||
815 | }; | ||
816 | |||
817 | static int __init vmu_flash_map_init(void) | ||
818 | { | ||
819 | return maple_driver_register(&vmu_flash_driver); | ||
820 | } | ||
821 | |||
822 | static void __exit vmu_flash_map_exit(void) | ||
823 | { | ||
824 | maple_driver_unregister(&vmu_flash_driver); | ||
825 | } | ||
826 | |||
827 | module_init(vmu_flash_map_init); | ||
828 | module_exit(vmu_flash_map_exit); | ||
829 | |||
830 | MODULE_LICENSE("GPL"); | ||
831 | MODULE_AUTHOR("Adrian McMenamin"); | ||
832 | MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory"); | ||
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c index 00d46e137b2a..92285d0089c2 100644 --- a/drivers/mtd/mtdsuper.c +++ b/drivers/mtd/mtdsuper.c | |||
@@ -81,13 +81,16 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags, | |||
81 | 81 | ||
82 | /* go */ | 82 | /* go */ |
83 | sb->s_flags |= MS_ACTIVE; | 83 | sb->s_flags |= MS_ACTIVE; |
84 | return simple_set_mnt(mnt, sb); | 84 | simple_set_mnt(mnt, sb); |
85 | |||
86 | return 0; | ||
85 | 87 | ||
86 | /* new mountpoint for an already mounted superblock */ | 88 | /* new mountpoint for an already mounted superblock */ |
87 | already_mounted: | 89 | already_mounted: |
88 | DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", | 90 | DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", |
89 | mtd->index, mtd->name); | 91 | mtd->index, mtd->name); |
90 | ret = simple_set_mnt(mnt, sb); | 92 | simple_set_mnt(mnt, sb); |
93 | ret = 0; | ||
91 | goto out_put; | 94 | goto out_put; |
92 | 95 | ||
93 | out_error: | 96 | out_error: |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 3419944c8892..890936d0275e 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -273,7 +273,7 @@ config MTD_NAND_CAFE | |||
273 | 273 | ||
274 | config MTD_NAND_CS553X | 274 | config MTD_NAND_CS553X |
275 | tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" | 275 | tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" |
276 | depends on X86_32 && (X86_PC || X86_GENERICARCH) | 276 | depends on X86_32 |
277 | help | 277 | help |
278 | The CS553x companion chips for the AMD Geode processor | 278 | The CS553x companion chips for the AMD Geode processor |
279 | include NAND flash controllers with built-in hardware ECC | 279 | include NAND flash controllers with built-in hardware ECC |
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index fa129c09bca8..10081e656a6f 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c | |||
@@ -26,8 +26,7 @@ | |||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
28 | 28 | ||
29 | #include <mach/hardware.h> | 29 | #include <mach/pxa2xx-regs.h> |
30 | #include <mach/pxa-regs.h> | ||
31 | 30 | ||
32 | #define GPIO_NAND_CS (11) | 31 | #define GPIO_NAND_CS (11) |
33 | #define GPIO_NAND_RB (89) | 32 | #define GPIO_NAND_RB (89) |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index e4226e02d63e..e51c1ed7ac18 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc); | |||
1773 | 1773 | ||
1774 | MODULE_LICENSE("GPL"); | 1774 | MODULE_LICENSE("GPL"); |
1775 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | 1775 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
1776 | MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n"); | 1776 | MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver"); |
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c index ced14b5294d5..72446fb48d4b 100644 --- a/drivers/mtd/nand/excite_nandflash.c +++ b/drivers/mtd/nand/excite_nandflash.c | |||
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd) | |||
128 | * The binding to the mtd and all allocated | 128 | * The binding to the mtd and all allocated |
129 | * resources are released. | 129 | * resources are released. |
130 | */ | 130 | */ |
131 | static int __exit excite_nand_remove(struct device *dev) | 131 | static int __exit excite_nand_remove(struct platform_device *dev) |
132 | { | 132 | { |
133 | struct excite_nand_drvdata * const this = dev_get_drvdata(dev); | 133 | struct excite_nand_drvdata * const this = platform_get_drvdata(dev); |
134 | 134 | ||
135 | dev_set_drvdata(dev, NULL); | 135 | platform_set_drvdata(dev, NULL); |
136 | 136 | ||
137 | if (unlikely(!this)) { | 137 | if (unlikely(!this)) { |
138 | printk(KERN_ERR "%s: called %s without private data!!", | 138 | printk(KERN_ERR "%s: called %s without private data!!", |
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev) | |||
159 | * it can allocate all necessary resources then calls the | 159 | * it can allocate all necessary resources then calls the |
160 | * nand layer to look for devices. | 160 | * nand layer to look for devices. |
161 | */ | 161 | */ |
162 | static int __init excite_nand_probe(struct device *dev) | 162 | static int __init excite_nand_probe(struct platform_device *pdev) |
163 | { | 163 | { |
164 | struct platform_device * const pdev = to_platform_device(dev); | ||
165 | struct excite_nand_drvdata *drvdata; /* private driver data */ | 164 | struct excite_nand_drvdata *drvdata; /* private driver data */ |
166 | struct nand_chip *board_chip; /* private flash chip data */ | 165 | struct nand_chip *board_chip; /* private flash chip data */ |
167 | struct mtd_info *board_mtd; /* mtd info for this board */ | 166 | struct mtd_info *board_mtd; /* mtd info for this board */ |
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev) | |||
175 | } | 174 | } |
176 | 175 | ||
177 | /* bind private data into driver */ | 176 | /* bind private data into driver */ |
178 | dev_set_drvdata(dev, drvdata); | 177 | platform_set_drvdata(pdev, drvdata); |
179 | 178 | ||
180 | /* allocate and map the resource */ | 179 | /* allocate and map the resource */ |
181 | drvdata->regs = | 180 | drvdata->regs = |
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev) | |||
219 | return 0; | 218 | return 0; |
220 | } | 219 | } |
221 | 220 | ||
222 | static struct device_driver excite_nand_driver = { | 221 | static struct platform_driver excite_nand_driver = { |
223 | .name = "excite_nand", | 222 | .driver = { |
224 | .bus = &platform_bus_type, | 223 | .name = "excite_nand", |
224 | .owner = THIS_MODULE, | ||
225 | }, | ||
225 | .probe = excite_nand_probe, | 226 | .probe = excite_nand_probe, |
226 | .remove = __exit_p(excite_nand_remove) | 227 | .remove = __devexit_p(excite_nand_remove) |
227 | }; | 228 | }; |
228 | 229 | ||
229 | static int __init excite_nand_init(void) | 230 | static int __init excite_nand_init(void) |
230 | { | 231 | { |
231 | pr_info("Basler eXcite nand flash driver Version " | 232 | pr_info("Basler eXcite nand flash driver Version " |
232 | EXCITE_NANDFLASH_VERSION "\n"); | 233 | EXCITE_NANDFLASH_VERSION "\n"); |
233 | return driver_register(&excite_nand_driver); | 234 | return platform_driver_register(&excite_nand_driver); |
234 | } | 235 | } |
235 | 236 | ||
236 | static void __exit excite_nand_exit(void) | 237 | static void __exit excite_nand_exit(void) |
237 | { | 238 | { |
238 | driver_unregister(&excite_nand_driver); | 239 | platform_driver_unregister(&excite_nand_driver); |
239 | } | 240 | } |
240 | 241 | ||
241 | module_init(excite_nand_init); | 242 | module_init(excite_nand_init); |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index bfde74a9ba6b..f3548d048014 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -881,7 +881,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) | |||
881 | this->read_buf = mxc_nand_read_buf; | 881 | this->read_buf = mxc_nand_read_buf; |
882 | this->verify_buf = mxc_nand_verify_buf; | 882 | this->verify_buf = mxc_nand_verify_buf; |
883 | 883 | ||
884 | host->clk = clk_get(&pdev->dev, "nfc_clk"); | 884 | host->clk = clk_get(&pdev->dev, "nfc"); |
885 | if (IS_ERR(host->clk)) | 885 | if (IS_ERR(host->clk)) |
886 | goto eclk; | 886 | goto eclk; |
887 | 887 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index facee262b4ba..3d7ed432fa41 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2829,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
2829 | return chip->scan_bbt(mtd); | 2829 | return chip->scan_bbt(mtd); |
2830 | } | 2830 | } |
2831 | 2831 | ||
2832 | /* module_text_address() isn't exported, and it's mostly a pointless | 2832 | /* is_module_text_address() isn't exported, and it's mostly a pointless |
2833 | test if this is a module _anyway_ -- they'd have to try _really_ hard | 2833 | test if this is a module _anyway_ -- they'd have to try _really_ hard |
2834 | to call us from in-kernel code if the core NAND support is modular. */ | 2834 | to call us from in-kernel code if the core NAND support is modular. */ |
2835 | #ifdef MODULE | 2835 | #ifdef MODULE |
2836 | #define caller_is_module() (1) | 2836 | #define caller_is_module() (1) |
2837 | #else | 2837 | #else |
2838 | #define caller_is_module() \ | 2838 | #define caller_is_module() \ |
2839 | module_text_address((unsigned long)__builtin_return_address(0)) | 2839 | is_module_text_address((unsigned long)__builtin_return_address(0)) |
2840 | #endif | 2840 | #endif |
2841 | 2841 | ||
2842 | /** | 2842 | /** |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 2857a6a37b5c..30a8ce6d3e69 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | 23 | ||
24 | #include <mach/dma.h> | 24 | #include <mach/dma.h> |
25 | #include <mach/pxa-regs.h> | ||
26 | #include <mach/pxa3xx_nand.h> | 25 | #include <mach/pxa3xx_nand.h> |
27 | 26 | ||
28 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) | 27 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 5b69e7773c6c..3a496c33fb52 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
@@ -36,10 +36,9 @@ struct onenand_info { | |||
36 | struct onenand_chip onenand; | 36 | struct onenand_chip onenand; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static int __devinit generic_onenand_probe(struct device *dev) | 39 | static int __devinit generic_onenand_probe(struct platform_device *pdev) |
40 | { | 40 | { |
41 | struct onenand_info *info; | 41 | struct onenand_info *info; |
42 | struct platform_device *pdev = to_platform_device(dev); | ||
43 | struct flash_platform_data *pdata = pdev->dev.platform_data; | 42 | struct flash_platform_data *pdata = pdev->dev.platform_data; |
44 | struct resource *res = pdev->resource; | 43 | struct resource *res = pdev->resource; |
45 | unsigned long size = res->end - res->start + 1; | 44 | unsigned long size = res->end - res->start + 1; |
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
49 | if (!info) | 48 | if (!info) |
50 | return -ENOMEM; | 49 | return -ENOMEM; |
51 | 50 | ||
52 | if (!request_mem_region(res->start, size, dev->driver->name)) { | 51 | if (!request_mem_region(res->start, size, pdev->dev.driver->name)) { |
53 | err = -EBUSY; | 52 | err = -EBUSY; |
54 | goto out_free_info; | 53 | goto out_free_info; |
55 | } | 54 | } |
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
82 | #endif | 81 | #endif |
83 | err = add_mtd_device(&info->mtd); | 82 | err = add_mtd_device(&info->mtd); |
84 | 83 | ||
85 | dev_set_drvdata(&pdev->dev, info); | 84 | platform_set_drvdata(pdev, info); |
86 | 85 | ||
87 | return 0; | 86 | return 0; |
88 | 87 | ||
@@ -96,14 +95,13 @@ out_free_info: | |||
96 | return err; | 95 | return err; |
97 | } | 96 | } |
98 | 97 | ||
99 | static int __devexit generic_onenand_remove(struct device *dev) | 98 | static int __devexit generic_onenand_remove(struct platform_device *pdev) |
100 | { | 99 | { |
101 | struct platform_device *pdev = to_platform_device(dev); | 100 | struct onenand_info *info = platform_get_drvdata(pdev); |
102 | struct onenand_info *info = dev_get_drvdata(&pdev->dev); | ||
103 | struct resource *res = pdev->resource; | 101 | struct resource *res = pdev->resource; |
104 | unsigned long size = res->end - res->start + 1; | 102 | unsigned long size = res->end - res->start + 1; |
105 | 103 | ||
106 | dev_set_drvdata(&pdev->dev, NULL); | 104 | platform_set_drvdata(pdev, NULL); |
107 | 105 | ||
108 | if (info) { | 106 | if (info) { |
109 | if (info->parts) | 107 | if (info->parts) |
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev) | |||
120 | return 0; | 118 | return 0; |
121 | } | 119 | } |
122 | 120 | ||
123 | static struct device_driver generic_onenand_driver = { | 121 | static struct platform_driver generic_onenand_driver = { |
124 | .name = DRIVER_NAME, | 122 | .driver = { |
125 | .bus = &platform_bus_type, | 123 | .name = DRIVER_NAME, |
124 | .owner = THIS_MODULE, | ||
125 | }, | ||
126 | .probe = generic_onenand_probe, | 126 | .probe = generic_onenand_probe, |
127 | .remove = __devexit_p(generic_onenand_remove), | 127 | .remove = __devexit_p(generic_onenand_remove), |
128 | }; | 128 | }; |
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME); | |||
131 | 131 | ||
132 | static int __init generic_onenand_init(void) | 132 | static int __init generic_onenand_init(void) |
133 | { | 133 | { |
134 | return driver_register(&generic_onenand_driver); | 134 | return platform_driver_register(&generic_onenand_driver); |
135 | } | 135 | } |
136 | 136 | ||
137 | static void __exit generic_onenand_exit(void) | 137 | static void __exit generic_onenand_exit(void) |
138 | { | 138 | { |
139 | driver_unregister(&generic_onenand_driver); | 139 | platform_driver_unregister(&generic_onenand_driver); |
140 | } | 140 | } |
141 | 141 | ||
142 | module_init(generic_onenand_init); | 142 | module_init(generic_onenand_init); |
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index afbc3f8126db..a18e8d2f2557 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c | |||
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum) | |||
136 | ops.ooblen = use_len; | 136 | ops.ooblen = use_len; |
137 | ops.oobretlen = 0; | 137 | ops.oobretlen = 0; |
138 | ops.ooboffs = use_offset; | 138 | ops.ooboffs = use_offset; |
139 | ops.datbuf = 0; | 139 | ops.datbuf = NULL; |
140 | ops.oobbuf = writebuf; | 140 | ops.oobbuf = writebuf; |
141 | err = mtd->write_oob(mtd, addr, &ops); | 141 | err = mtd->write_oob(mtd, addr, &ops); |
142 | if (err || ops.oobretlen != use_len) { | 142 | if (err || ops.oobretlen != use_len) { |
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum) | |||
189 | ops.ooblen = use_len; | 189 | ops.ooblen = use_len; |
190 | ops.oobretlen = 0; | 190 | ops.oobretlen = 0; |
191 | ops.ooboffs = use_offset; | 191 | ops.ooboffs = use_offset; |
192 | ops.datbuf = 0; | 192 | ops.datbuf = NULL; |
193 | ops.oobbuf = readbuf; | 193 | ops.oobbuf = readbuf; |
194 | err = mtd->read_oob(mtd, addr, &ops); | 194 | err = mtd->read_oob(mtd, addr, &ops); |
195 | if (err || ops.oobretlen != use_len) { | 195 | if (err || ops.oobretlen != use_len) { |
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum) | |||
216 | ops.ooblen = mtd->ecclayout->oobavail; | 216 | ops.ooblen = mtd->ecclayout->oobavail; |
217 | ops.oobretlen = 0; | 217 | ops.oobretlen = 0; |
218 | ops.ooboffs = 0; | 218 | ops.ooboffs = 0; |
219 | ops.datbuf = 0; | 219 | ops.datbuf = NULL; |
220 | ops.oobbuf = readbuf; | 220 | ops.oobbuf = readbuf; |
221 | err = mtd->read_oob(mtd, addr, &ops); | 221 | err = mtd->read_oob(mtd, addr, &ops); |
222 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { | 222 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { |
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(int ebnum) | |||
281 | ops.ooblen = len; | 281 | ops.ooblen = len; |
282 | ops.oobretlen = 0; | 282 | ops.oobretlen = 0; |
283 | ops.ooboffs = 0; | 283 | ops.ooboffs = 0; |
284 | ops.datbuf = 0; | 284 | ops.datbuf = NULL; |
285 | ops.oobbuf = readbuf; | 285 | ops.oobbuf = readbuf; |
286 | err = mtd->read_oob(mtd, addr, &ops); | 286 | err = mtd->read_oob(mtd, addr, &ops); |
287 | if (err || ops.oobretlen != len) { | 287 | if (err || ops.oobretlen != len) { |
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void) | |||
522 | ops.ooblen = 1; | 522 | ops.ooblen = 1; |
523 | ops.oobretlen = 0; | 523 | ops.oobretlen = 0; |
524 | ops.ooboffs = mtd->ecclayout->oobavail; | 524 | ops.ooboffs = mtd->ecclayout->oobavail; |
525 | ops.datbuf = 0; | 525 | ops.datbuf = NULL; |
526 | ops.oobbuf = writebuf; | 526 | ops.oobbuf = writebuf; |
527 | printk(PRINT_PREF "attempting to start write past end of OOB\n"); | 527 | printk(PRINT_PREF "attempting to start write past end of OOB\n"); |
528 | printk(PRINT_PREF "an error is expected...\n"); | 528 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void) | |||
542 | ops.ooblen = 1; | 542 | ops.ooblen = 1; |
543 | ops.oobretlen = 0; | 543 | ops.oobretlen = 0; |
544 | ops.ooboffs = mtd->ecclayout->oobavail; | 544 | ops.ooboffs = mtd->ecclayout->oobavail; |
545 | ops.datbuf = 0; | 545 | ops.datbuf = NULL; |
546 | ops.oobbuf = readbuf; | 546 | ops.oobbuf = readbuf; |
547 | printk(PRINT_PREF "attempting to start read past end of OOB\n"); | 547 | printk(PRINT_PREF "attempting to start read past end of OOB\n"); |
548 | printk(PRINT_PREF "an error is expected...\n"); | 548 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void) | |||
566 | ops.ooblen = mtd->ecclayout->oobavail + 1; | 566 | ops.ooblen = mtd->ecclayout->oobavail + 1; |
567 | ops.oobretlen = 0; | 567 | ops.oobretlen = 0; |
568 | ops.ooboffs = 0; | 568 | ops.ooboffs = 0; |
569 | ops.datbuf = 0; | 569 | ops.datbuf = NULL; |
570 | ops.oobbuf = writebuf; | 570 | ops.oobbuf = writebuf; |
571 | printk(PRINT_PREF "attempting to write past end of device\n"); | 571 | printk(PRINT_PREF "attempting to write past end of device\n"); |
572 | printk(PRINT_PREF "an error is expected...\n"); | 572 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void) | |||
586 | ops.ooblen = mtd->ecclayout->oobavail + 1; | 586 | ops.ooblen = mtd->ecclayout->oobavail + 1; |
587 | ops.oobretlen = 0; | 587 | ops.oobretlen = 0; |
588 | ops.ooboffs = 0; | 588 | ops.ooboffs = 0; |
589 | ops.datbuf = 0; | 589 | ops.datbuf = NULL; |
590 | ops.oobbuf = readbuf; | 590 | ops.oobbuf = readbuf; |
591 | printk(PRINT_PREF "attempting to read past end of device\n"); | 591 | printk(PRINT_PREF "attempting to read past end of device\n"); |
592 | printk(PRINT_PREF "an error is expected...\n"); | 592 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void) | |||
610 | ops.ooblen = mtd->ecclayout->oobavail; | 610 | ops.ooblen = mtd->ecclayout->oobavail; |
611 | ops.oobretlen = 0; | 611 | ops.oobretlen = 0; |
612 | ops.ooboffs = 1; | 612 | ops.ooboffs = 1; |
613 | ops.datbuf = 0; | 613 | ops.datbuf = NULL; |
614 | ops.oobbuf = writebuf; | 614 | ops.oobbuf = writebuf; |
615 | printk(PRINT_PREF "attempting to write past end of device\n"); | 615 | printk(PRINT_PREF "attempting to write past end of device\n"); |
616 | printk(PRINT_PREF "an error is expected...\n"); | 616 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void) | |||
630 | ops.ooblen = mtd->ecclayout->oobavail; | 630 | ops.ooblen = mtd->ecclayout->oobavail; |
631 | ops.oobretlen = 0; | 631 | ops.oobretlen = 0; |
632 | ops.ooboffs = 1; | 632 | ops.ooboffs = 1; |
633 | ops.datbuf = 0; | 633 | ops.datbuf = NULL; |
634 | ops.oobbuf = readbuf; | 634 | ops.oobbuf = readbuf; |
635 | printk(PRINT_PREF "attempting to read past end of device\n"); | 635 | printk(PRINT_PREF "attempting to read past end of device\n"); |
636 | printk(PRINT_PREF "an error is expected...\n"); | 636 | printk(PRINT_PREF "an error is expected...\n"); |
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void) | |||
670 | ops.ooblen = sz; | 670 | ops.ooblen = sz; |
671 | ops.oobretlen = 0; | 671 | ops.oobretlen = 0; |
672 | ops.ooboffs = 0; | 672 | ops.ooboffs = 0; |
673 | ops.datbuf = 0; | 673 | ops.datbuf = NULL; |
674 | ops.oobbuf = writebuf; | 674 | ops.oobbuf = writebuf; |
675 | err = mtd->write_oob(mtd, addr, &ops); | 675 | err = mtd->write_oob(mtd, addr, &ops); |
676 | if (err) | 676 | if (err) |
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void) | |||
698 | ops.ooblen = mtd->ecclayout->oobavail * 2; | 698 | ops.ooblen = mtd->ecclayout->oobavail * 2; |
699 | ops.oobretlen = 0; | 699 | ops.oobretlen = 0; |
700 | ops.ooboffs = 0; | 700 | ops.ooboffs = 0; |
701 | ops.datbuf = 0; | 701 | ops.datbuf = NULL; |
702 | ops.oobbuf = readbuf; | 702 | ops.oobbuf = readbuf; |
703 | err = mtd->read_oob(mtd, addr, &ops); | 703 | err = mtd->read_oob(mtd, addr, &ops); |
704 | if (err) | 704 | if (err) |
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index 645e77fdc63d..79fc4530987b 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c | |||
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int ebnum) | |||
71 | ops.ooblen = mtd->oobsize; | 71 | ops.ooblen = mtd->oobsize; |
72 | ops.oobretlen = 0; | 72 | ops.oobretlen = 0; |
73 | ops.ooboffs = 0; | 73 | ops.ooboffs = 0; |
74 | ops.datbuf = 0; | 74 | ops.datbuf = NULL; |
75 | ops.oobbuf = oobbuf; | 75 | ops.oobbuf = oobbuf; |
76 | ret = mtd->read_oob(mtd, addr, &ops); | 76 | ret = mtd->read_oob(mtd, addr, &ops); |
77 | if (ret || ops.oobretlen != mtd->oobsize) { | 77 | if (ret || ops.oobretlen != mtd->oobsize) { |