aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 18:34:57 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 18:34:57 -0400
commitf00546363fff1576ceddc2690d47e5f9c1dd2e05 (patch)
treef6cb8965b6754fc6ce7570cf1471ebe9874e509a /drivers/mtd/devices
parent50f732ee63b91eb08a29974b36bd63e1150bb642 (diff)
parent28b57cddb3ed4f7999e4b76ef36ebaaf6e2e0c37 (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (46 commits) [MTD] [MAPS] drivers/mtd/maps/ck804xrom.c: convert pci_module_init() [MTD] [NAND] CM-x270 MTD driver [MTD] [NAND] Wrong calculation of page number in nand_block_bad() [MTD] [MAPS] fix plat-ram printk format [JFFS2] Fix compr_rubin.c build after include file elimination. [JFFS2] Handle inodes with only a single metadata node with non-zero isize [JFFS2] Tidy up licensing/copyright boilerplate. [MTD] [OneNAND] Exit loop only when column start with 0 [MTD] [OneNAND] Fix access the past of the real oobfree array [MTD] [OneNAND] Update Samsung OneNAND official URL [JFFS2] Better fix for all-zero node headers [JFFS2] Improve read_inode memory usage, v2. [JFFS2] Improve failure mode if inode checking leaves unchecked space. [JFFS2] Fix cross-endian build. [MTD] Finish conversion mtd_blkdevs to use the kthread API [JFFS2] Obsolete dirent nodes immediately on unlink, where possible. Use menuconfig objects: MTD [MTD] mtd_blkdevs: Convert to use the kthread API [MTD] Fix fwh_lock locking [JFFS2] Speed up mount for directly-mapped NOR flash ...
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r--drivers/mtd/devices/Kconfig26
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/at91_dataflash26.c485
-rw-r--r--drivers/mtd/devices/block2mtd.c67
4 files changed, 509 insertions, 70 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 440f6851da69..690c94236d7f 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -6,7 +6,7 @@ menu "Self-contained MTD device drivers"
6 6
7config MTD_PMC551 7config MTD_PMC551
8 tristate "Ramix PMC551 PCI Mezzanine RAM card support" 8 tristate "Ramix PMC551 PCI Mezzanine RAM card support"
9 depends on MTD && PCI 9 depends on PCI
10 ---help--- 10 ---help---
11 This provides a MTD device driver for the Ramix PMC551 RAM PCI card 11 This provides a MTD device driver for the Ramix PMC551 RAM PCI card
12 from Ramix Inc. <http://www.ramix.com/products/memory/pmc551.html>. 12 from Ramix Inc. <http://www.ramix.com/products/memory/pmc551.html>.
@@ -40,7 +40,7 @@ config MTD_PMC551_DEBUG
40 40
41config MTD_MS02NV 41config MTD_MS02NV
42 tristate "DEC MS02-NV NVRAM module support" 42 tristate "DEC MS02-NV NVRAM module support"
43 depends on MTD && MACH_DECSTATION 43 depends on MACH_DECSTATION
44 help 44 help
45 This is an MTD driver for the DEC's MS02-NV (54-20948-01) battery 45 This is an MTD driver for the DEC's MS02-NV (54-20948-01) battery
46 backed-up NVRAM module. The module was originally meant as an NFS 46 backed-up NVRAM module. The module was originally meant as an NFS
@@ -54,15 +54,23 @@ config MTD_MS02NV
54 54
55config MTD_DATAFLASH 55config MTD_DATAFLASH
56 tristate "Support for AT45xxx DataFlash" 56 tristate "Support for AT45xxx DataFlash"
57 depends on MTD && SPI_MASTER && EXPERIMENTAL 57 depends on SPI_MASTER && EXPERIMENTAL
58 help 58 help
59 This enables access to AT45xxx DataFlash chips, using SPI. 59 This enables access to AT45xxx DataFlash chips, using SPI.
60 Sometimes DataFlash chips are packaged inside MMC-format 60 Sometimes DataFlash chips are packaged inside MMC-format
61 cards; at this writing, the MMC stack won't handle those. 61 cards; at this writing, the MMC stack won't handle those.
62 62
63config MTD_DATAFLASH26
64 tristate "AT91RM9200 DataFlash AT26xxx"
65 depends on MTD && ARCH_AT91RM9200 && AT91_SPI
66 help
67 This enables access to the DataFlash chip (AT26xxx) on an
68 AT91RM9200-based board.
69 If you have such a board and such a DataFlash, say 'Y'.
70
63config MTD_M25P80 71config MTD_M25P80
64 tristate "Support for M25 SPI Flash" 72 tristate "Support for M25 SPI Flash"
65 depends on MTD && SPI_MASTER && EXPERIMENTAL 73 depends on SPI_MASTER && EXPERIMENTAL
66 help 74 help
67 This enables access to ST M25P80 and similar SPI flash chips, 75 This enables access to ST M25P80 and similar SPI flash chips,
68 used for program and data storage. Set up your spi devices 76 used for program and data storage. Set up your spi devices
@@ -70,7 +78,6 @@ config MTD_M25P80
70 78
71config MTD_SLRAM 79config MTD_SLRAM
72 tristate "Uncached system RAM" 80 tristate "Uncached system RAM"
73 depends on MTD
74 help 81 help
75 If your CPU cannot cache all of the physical memory in your machine, 82 If your CPU cannot cache all of the physical memory in your machine,
76 you can still use it for storage or swap by using this driver to 83 you can still use it for storage or swap by using this driver to
@@ -78,7 +85,6 @@ config MTD_SLRAM
78 85
79config MTD_PHRAM 86config MTD_PHRAM
80 tristate "Physical system RAM" 87 tristate "Physical system RAM"
81 depends on MTD
82 help 88 help
83 This is a re-implementation of the slram driver above. 89 This is a re-implementation of the slram driver above.
84 90
@@ -88,7 +94,7 @@ config MTD_PHRAM
88 94
89config MTD_LART 95config MTD_LART
90 tristate "28F160xx flash driver for LART" 96 tristate "28F160xx flash driver for LART"
91 depends on SA1100_LART && MTD 97 depends on SA1100_LART
92 help 98 help
93 This enables the flash driver for LART. Please note that you do 99 This enables the flash driver for LART. Please note that you do
94 not need any mapping/chip driver for LART. This one does it all 100 not need any mapping/chip driver for LART. This one does it all
@@ -96,7 +102,6 @@ config MTD_LART
96 102
97config MTD_MTDRAM 103config MTD_MTDRAM
98 tristate "Test driver using RAM" 104 tristate "Test driver using RAM"
99 depends on MTD
100 help 105 help
101 This enables a test MTD device driver which uses vmalloc() to 106 This enables a test MTD device driver which uses vmalloc() to
102 provide storage. You probably want to say 'N' unless you're 107 provide storage. You probably want to say 'N' unless you're
@@ -136,7 +141,7 @@ config MTDRAM_ABS_POS
136 141
137config MTD_BLOCK2MTD 142config MTD_BLOCK2MTD
138 tristate "MTD using block device" 143 tristate "MTD using block device"
139 depends on MTD && BLOCK 144 depends on BLOCK
140 help 145 help
141 This driver allows a block device to appear as an MTD. It would 146 This driver allows a block device to appear as an MTD. It would
142 generally be used in the following cases: 147 generally be used in the following cases:
@@ -150,7 +155,6 @@ comment "Disk-On-Chip Device Drivers"
150 155
151config MTD_DOC2000 156config MTD_DOC2000
152 tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)" 157 tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
153 depends on MTD
154 select MTD_DOCPROBE 158 select MTD_DOCPROBE
155 select MTD_NAND_IDS 159 select MTD_NAND_IDS
156 ---help--- 160 ---help---
@@ -173,7 +177,6 @@ config MTD_DOC2000
173 177
174config MTD_DOC2001 178config MTD_DOC2001
175 tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)" 179 tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
176 depends on MTD
177 select MTD_DOCPROBE 180 select MTD_DOCPROBE
178 select MTD_NAND_IDS 181 select MTD_NAND_IDS
179 ---help--- 182 ---help---
@@ -195,7 +198,6 @@ config MTD_DOC2001
195 198
196config MTD_DOC2001PLUS 199config MTD_DOC2001PLUS
197 tristate "M-Systems Disk-On-Chip Millennium Plus" 200 tristate "M-Systems Disk-On-Chip Millennium Plus"
198 depends on MTD
199 select MTD_DOCPROBE 201 select MTD_DOCPROBE
200 select MTD_NAND_IDS 202 select MTD_NAND_IDS
201 ---help--- 203 ---help---
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 0f788d5c4bf8..8ab568b3f533 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
16obj-$(CONFIG_MTD_LART) += lart.o 16obj-$(CONFIG_MTD_LART) += lart.o
17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
19obj-$(CONFIG_MTD_DATAFLASH26) += at91_dataflash26.o
19obj-$(CONFIG_MTD_M25P80) += m25p80.o 20obj-$(CONFIG_MTD_M25P80) += m25p80.o
diff --git a/drivers/mtd/devices/at91_dataflash26.c b/drivers/mtd/devices/at91_dataflash26.c
new file mode 100644
index 000000000000..64ce37f986fc
--- /dev/null
+++ b/drivers/mtd/devices/at91_dataflash26.c
@@ -0,0 +1,485 @@
1/*
2 * Atmel DataFlash driver for Atmel AT91RM9200 (Thunder)
3 * This is a largely modified version of at91_dataflash.c that
4 * supports AT26xxx dataflash chips. The original driver supports
5 * AT45xxx chips.
6 *
7 * Note: This driver was only tested with an AT26F004. It should be
8 * easy to make it work with other AT26xxx dataflash devices, though.
9 *
10 * Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de>
11 * original Copyright (C) SAN People (Pty) Ltd
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16*/
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/mtd/mtd.h>
22
23#include <asm/arch/at91_spi.h>
24
25#define DATAFLASH_MAX_DEVICES 4 /* max number of dataflash devices */
26
27#define MANUFACTURER_ID_ATMEL 0x1F
28
29/* command codes */
30
31#define AT26_OP_READ_STATUS 0x05
32#define AT26_OP_READ_DEV_ID 0x9F
33#define AT26_OP_ERASE_PAGE_4K 0x20
34#define AT26_OP_READ_ARRAY_FAST 0x0B
35#define AT26_OP_SEQUENTIAL_WRITE 0xAF
36#define AT26_OP_WRITE_ENABLE 0x06
37#define AT26_OP_WRITE_DISABLE 0x04
38#define AT26_OP_SECTOR_PROTECT 0x36
39#define AT26_OP_SECTOR_UNPROTECT 0x39
40
41/* status register bits */
42
43#define AT26_STATUS_BUSY 0x01
44#define AT26_STATUS_WRITE_ENABLE 0x02
45
46struct dataflash_local
47{
48 int spi; /* SPI chip-select number */
49 unsigned int page_size; /* number of bytes per page */
50};
51
52
53/* Detected DataFlash devices */
54static struct mtd_info* mtd_devices[DATAFLASH_MAX_DEVICES];
55static int nr_devices = 0;
56
57/* Allocate a single SPI transfer descriptor. We're assuming that if multiple
58 SPI transfers occur at the same time, spi_access_bus() will serialize them.
59 If this is not valid, then either (i) each dataflash 'priv' structure
60 needs it's own transfer descriptor, (ii) we lock this one, or (iii) use
61 another mechanism. */
62static struct spi_transfer_list* spi_transfer_desc;
63
64/*
65 * Perform a SPI transfer to access the DataFlash device.
66 */
67static int do_spi_transfer(int nr, char* tx, int tx_len, char* rx, int rx_len,
68 char* txnext, int txnext_len, char* rxnext, int rxnext_len)
69{
70 struct spi_transfer_list* list = spi_transfer_desc;
71
72 list->tx[0] = tx; list->txlen[0] = tx_len;
73 list->rx[0] = rx; list->rxlen[0] = rx_len;
74
75 list->tx[1] = txnext; list->txlen[1] = txnext_len;
76 list->rx[1] = rxnext; list->rxlen[1] = rxnext_len;
77
78 list->nr_transfers = nr;
79 /* Note: spi_transfer() always returns 0, there are no error checks */
80 return spi_transfer(list);
81}
82
83/*
84 * Return the status of the DataFlash device.
85 */
86static unsigned char at91_dataflash26_status(void)
87{
88 unsigned char command[2];
89
90 command[0] = AT26_OP_READ_STATUS;
91 command[1] = 0;
92
93 do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
94
95 return command[1];
96}
97
98/*
99 * Poll the DataFlash device until it is READY.
100 */
101static unsigned char at91_dataflash26_waitready(void)
102{
103 unsigned char status;
104
105 while (1) {
106 status = at91_dataflash26_status();
107 if (!(status & AT26_STATUS_BUSY))
108 return status;
109 }
110}
111
112/*
113 * Enable/disable write access
114 */
115 static void at91_dataflash26_write_enable(int enable)
116{
117 unsigned char cmd[2];
118
119 DEBUG(MTD_DEBUG_LEVEL3, "write_enable: enable=%i\n", enable);
120
121 if (enable)
122 cmd[0] = AT26_OP_WRITE_ENABLE;
123 else
124 cmd[0] = AT26_OP_WRITE_DISABLE;
125 cmd[1] = 0;
126
127 do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0);
128}
129
130/*
131 * Protect/unprotect sector
132 */
133 static void at91_dataflash26_sector_protect(loff_t addr, int protect)
134{
135 unsigned char cmd[4];
136
137 DEBUG(MTD_DEBUG_LEVEL3, "sector_protect: addr=0x%06x prot=%d\n",
138 addr, protect);
139
140 if (protect)
141 cmd[0] = AT26_OP_SECTOR_PROTECT;
142 else
143 cmd[0] = AT26_OP_SECTOR_UNPROTECT;
144 cmd[1] = (addr & 0x00FF0000) >> 16;
145 cmd[2] = (addr & 0x0000FF00) >> 8;
146 cmd[3] = (addr & 0x000000FF);
147
148 do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0);
149}
150
151/*
152 * Erase blocks of flash.
153 */
154static int at91_dataflash26_erase(struct mtd_info *mtd,
155 struct erase_info *instr)
156{
157 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
158 unsigned char cmd[4];
159
160 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_erase: addr=0x%06x len=%i\n",
161 instr->addr, instr->len);
162
163 /* Sanity checks */
164 if (priv->page_size != 4096)
165 return -EINVAL; /* Can't handle other sizes at the moment */
166
167 if ( ((instr->len % mtd->erasesize) != 0)
168 || ((instr->len % priv->page_size) != 0)
169 || ((instr->addr % priv->page_size) != 0)
170 || ((instr->addr + instr->len) > mtd->size))
171 return -EINVAL;
172
173 spi_access_bus(priv->spi);
174
175 while (instr->len > 0) {
176 at91_dataflash26_write_enable(1);
177 at91_dataflash26_sector_protect(instr->addr, 0);
178 at91_dataflash26_write_enable(1);
179 cmd[0] = AT26_OP_ERASE_PAGE_4K;
180 cmd[1] = (instr->addr & 0x00FF0000) >> 16;
181 cmd[2] = (instr->addr & 0x0000FF00) >> 8;
182 cmd[3] = (instr->addr & 0x000000FF);
183
184 DEBUG(MTD_DEBUG_LEVEL3, "ERASE: (0x%02x) 0x%02x 0x%02x"
185 "0x%02x\n",
186 cmd[0], cmd[1], cmd[2], cmd[3]);
187
188 do_spi_transfer(1, cmd, 4, cmd, 4, NULL, 0, NULL, 0);
189 at91_dataflash26_waitready();
190
191 instr->addr += priv->page_size; /* next page */
192 instr->len -= priv->page_size;
193 }
194
195 at91_dataflash26_write_enable(0);
196 spi_release_bus(priv->spi);
197
198 /* Inform MTD subsystem that erase is complete */
199 instr->state = MTD_ERASE_DONE;
200 if (instr->callback)
201 instr->callback(instr);
202
203 return 0;
204}
205
206/*
207 * Read from the DataFlash device.
208 * from : Start offset in flash device
209 * len : Number of bytes to read
210 * retlen : Number of bytes actually read
211 * buf : Buffer that will receive data
212 */
213static int at91_dataflash26_read(struct mtd_info *mtd, loff_t from, size_t len,
214 size_t *retlen, u_char *buf)
215{
216 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
217 unsigned char cmd[5];
218
219 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_read: %lli .. %lli\n",
220 from, from+len);
221
222 *retlen = 0;
223
224 /* Sanity checks */
225 if (!len)
226 return 0;
227 if (from + len > mtd->size)
228 return -EINVAL;
229
230 cmd[0] = AT26_OP_READ_ARRAY_FAST;
231 cmd[1] = (from & 0x00FF0000) >> 16;
232 cmd[2] = (from & 0x0000FF00) >> 8;
233 cmd[3] = (from & 0x000000FF);
234 /* cmd[4] is a "Don't care" byte */
235
236 DEBUG(MTD_DEBUG_LEVEL3, "READ: (0x%02x) 0x%02x 0x%02x 0x%02x\n",
237 cmd[0], cmd[1], cmd[2], cmd[3]);
238
239 spi_access_bus(priv->spi);
240 do_spi_transfer(2, cmd, 5, cmd, 5, buf, len, buf, len);
241 spi_release_bus(priv->spi);
242
243 *retlen = len;
244 return 0;
245}
246
247/*
248 * Write to the DataFlash device.
249 * to : Start offset in flash device
250 * len : Number of bytes to write
251 * retlen : Number of bytes actually written
252 * buf : Buffer containing the data
253 */
254static int at91_dataflash26_write(struct mtd_info *mtd, loff_t to, size_t len,
255 size_t *retlen, const u_char *buf)
256{
257 struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
258 unsigned int addr, buf_index = 0;
259 int ret = -EIO, sector, last_sector;
260 unsigned char status, cmd[5];
261
262 DEBUG(MTD_DEBUG_LEVEL1, "dataflash_write: %lli .. %lli\n", to, to+len);
263
264 *retlen = 0;
265
266 /* Sanity checks */
267 if (!len)
268 return 0;
269 if (to + len > mtd->size)
270 return -EINVAL;
271
272 spi_access_bus(priv->spi);
273
274 addr = to;
275 last_sector = -1;
276
277 while (buf_index < len) {
278 sector = addr / priv->page_size;
279 /* Write first byte if a new sector begins */
280 if (sector != last_sector) {
281 at91_dataflash26_write_enable(1);
282 at91_dataflash26_sector_protect(addr, 0);
283 at91_dataflash26_write_enable(1);
284
285 /* Program first byte of a new sector */
286 cmd[0] = AT26_OP_SEQUENTIAL_WRITE;
287 cmd[1] = (addr & 0x00FF0000) >> 16;
288 cmd[2] = (addr & 0x0000FF00) >> 8;
289 cmd[3] = (addr & 0x000000FF);
290 cmd[4] = buf[buf_index++];
291 do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0);
292 status = at91_dataflash26_waitready();
293 addr++;
294 /* On write errors, the chip resets the write enable
295 flag. This also happens after the last byte of a
296 sector is successfully programmed. */
297 if ( ( !(status & AT26_STATUS_WRITE_ENABLE))
298 && ((addr % priv->page_size) != 0) ) {
299 DEBUG(MTD_DEBUG_LEVEL1,
300 "write error1: addr=0x%06x, "
301 "status=0x%02x\n", addr, status);
302 goto write_err;
303 }
304 (*retlen)++;
305 last_sector = sector;
306 }
307
308 /* Write subsequent bytes in the same sector */
309 cmd[0] = AT26_OP_SEQUENTIAL_WRITE;
310 cmd[1] = buf[buf_index++];
311 do_spi_transfer(1, cmd, 2, cmd, 2, NULL, 0, NULL, 0);
312 status = at91_dataflash26_waitready();
313 addr++;
314
315 if ( ( !(status & AT26_STATUS_WRITE_ENABLE))
316 && ((addr % priv->page_size) != 0) ) {
317 DEBUG(MTD_DEBUG_LEVEL1, "write error2: addr=0x%06x, "
318 "status=0x%02x\n", addr, status);
319 goto write_err;
320 }
321
322 (*retlen)++;
323 }
324
325 ret = 0;
326 at91_dataflash26_write_enable(0);
327write_err:
328 spi_release_bus(priv->spi);
329 return ret;
330}
331
332/*
333 * Initialize and register DataFlash device with MTD subsystem.
334 */
335static int __init add_dataflash(int channel, char *name, int nr_pages,
336 int pagesize)
337{
338 struct mtd_info *device;
339 struct dataflash_local *priv;
340
341 if (nr_devices >= DATAFLASH_MAX_DEVICES) {
342 printk(KERN_ERR "at91_dataflash26: Too many devices "
343 "detected\n");
344 return 0;
345 }
346
347 device = kzalloc(sizeof(struct mtd_info) + strlen(name) + 8,
348 GFP_KERNEL);
349 if (!device)
350 return -ENOMEM;
351
352 device->name = (char *)&device[1];
353 sprintf(device->name, "%s.spi%d", name, channel);
354 device->size = nr_pages * pagesize;
355 device->erasesize = pagesize;
356 device->owner = THIS_MODULE;
357 device->type = MTD_DATAFLASH;
358 device->flags = MTD_CAP_NORFLASH;
359 device->erase = at91_dataflash26_erase;
360 device->read = at91_dataflash26_read;
361 device->write = at91_dataflash26_write;
362
363 priv = (struct dataflash_local *)kzalloc(sizeof(struct dataflash_local),
364 GFP_KERNEL);
365 if (!priv) {
366 kfree(device);
367 return -ENOMEM;
368 }
369
370 priv->spi = channel;
371 priv->page_size = pagesize;
372 device->priv = priv;
373
374 mtd_devices[nr_devices] = device;
375 nr_devices++;
376 printk(KERN_INFO "at91_dataflash26: %s detected [spi%i] (%i bytes)\n",
377 name, channel, device->size);
378
379 return add_mtd_device(device);
380}
381
382/*
383 * Detect and initialize DataFlash device connected to specified SPI channel.
384 *
385 */
386
387struct dataflash26_types {
388 unsigned char id0;
389 unsigned char id1;
390 char *name;
391 int pagesize;
392 int nr_pages;
393};
394
395struct dataflash26_types df26_types[] = {
396 {
397 .id0 = 0x04,
398 .id1 = 0x00,
399 .name = "AT26F004",
400 .pagesize = 4096,
401 .nr_pages = 128,
402 },
403 {
404 .id0 = 0x45,
405 .id1 = 0x01,
406 .name = "AT26DF081A", /* Not tested ! */
407 .pagesize = 4096,
408 .nr_pages = 256,
409 },
410};
411
412static int __init at91_dataflash26_detect(int channel)
413{
414 unsigned char status, cmd[5];
415 int i;
416
417 spi_access_bus(channel);
418 status = at91_dataflash26_status();
419
420 if (status == 0 || status == 0xff) {
421 printk(KERN_ERR "at91_dataflash26_detect: status error %d\n",
422 status);
423 spi_release_bus(channel);
424 return -ENODEV;
425 }
426
427 cmd[0] = AT26_OP_READ_DEV_ID;
428 do_spi_transfer(1, cmd, 5, cmd, 5, NULL, 0, NULL, 0);
429 spi_release_bus(channel);
430
431 if (cmd[1] != MANUFACTURER_ID_ATMEL)
432 return -ENODEV;
433
434 for (i = 0; i < ARRAY_SIZE(df26_types); i++) {
435 if ( cmd[2] == df26_types[i].id0
436 && cmd[3] == df26_types[i].id1)
437 return add_dataflash(channel,
438 df26_types[i].name,
439 df26_types[i].nr_pages,
440 df26_types[i].pagesize);
441 }
442
443 printk(KERN_ERR "at91_dataflash26_detect: Unsupported device "
444 "(0x%02x/0x%02x)\n", cmd[2], cmd[3]);
445 return -ENODEV;
446}
447
448static int __init at91_dataflash26_init(void)
449{
450 spi_transfer_desc = kmalloc(sizeof(struct spi_transfer_list),
451 GFP_KERNEL);
452 if (!spi_transfer_desc)
453 return -ENOMEM;
454
455 /* DataFlash (SPI chip select 0) */
456 at91_dataflash26_detect(0);
457
458#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
459 /* DataFlash card (SPI chip select 3) */
460 at91_dataflash26_detect(3);
461#endif
462 return 0;
463}
464
465static void __exit at91_dataflash26_exit(void)
466{
467 int i;
468
469 for (i = 0; i < DATAFLASH_MAX_DEVICES; i++) {
470 if (mtd_devices[i]) {
471 del_mtd_device(mtd_devices[i]);
472 kfree(mtd_devices[i]->priv);
473 kfree(mtd_devices[i]);
474 }
475 }
476 nr_devices = 0;
477 kfree(spi_transfer_desc);
478}
479
480module_init(at91_dataflash26_init);
481module_exit(at91_dataflash26_exit);
482
483MODULE_LICENSE("GPL");
484MODULE_AUTHOR("Hans J. Koch");
485MODULE_DESCRIPTION("DataFlash AT26xxx driver for Atmel AT91RM9200");
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index f9f2ce7806b0..ce47544dc120 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -40,56 +40,9 @@ struct block2mtd_dev {
40static LIST_HEAD(blkmtd_device_list); 40static LIST_HEAD(blkmtd_device_list);
41 41
42 42
43#define PAGE_READAHEAD 64 43static struct page* page_read(struct address_space *mapping, int index)
44static void cache_readahead(struct address_space *mapping, int index)
45{ 44{
46 filler_t *filler = (filler_t*)mapping->a_ops->readpage; 45 filler_t *filler = (filler_t*)mapping->a_ops->readpage;
47 int i, pagei;
48 unsigned ret = 0;
49 unsigned long end_index;
50 struct page *page;
51 LIST_HEAD(page_pool);
52 struct inode *inode = mapping->host;
53 loff_t isize = i_size_read(inode);
54
55 if (!isize) {
56 INFO("iSize=0 in cache_readahead\n");
57 return;
58 }
59
60 end_index = ((isize - 1) >> PAGE_CACHE_SHIFT);
61
62 read_lock_irq(&mapping->tree_lock);
63 for (i = 0; i < PAGE_READAHEAD; i++) {
64 pagei = index + i;
65 if (pagei > end_index) {
66 INFO("Overrun end of disk in cache readahead\n");
67 break;
68 }
69 page = radix_tree_lookup(&mapping->page_tree, pagei);
70 if (page && (!i))
71 break;
72 if (page)
73 continue;
74 read_unlock_irq(&mapping->tree_lock);
75 page = page_cache_alloc_cold(mapping);
76 read_lock_irq(&mapping->tree_lock);
77 if (!page)
78 break;
79 page->index = pagei;
80 list_add(&page->lru, &page_pool);
81 ret++;
82 }
83 read_unlock_irq(&mapping->tree_lock);
84 if (ret)
85 read_cache_pages(mapping, &page_pool, filler, NULL);
86}
87
88
89static struct page* page_readahead(struct address_space *mapping, int index)
90{
91 filler_t *filler = (filler_t*)mapping->a_ops->readpage;
92 cache_readahead(mapping, index);
93 return read_cache_page(mapping, index, filler, NULL); 46 return read_cache_page(mapping, index, filler, NULL);
94} 47}
95 48
@@ -105,14 +58,14 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
105 u_long *max; 58 u_long *max;
106 59
107 while (pages) { 60 while (pages) {
108 page = page_readahead(mapping, index); 61 page = page_read(mapping, index);
109 if (!page) 62 if (!page)
110 return -ENOMEM; 63 return -ENOMEM;
111 if (IS_ERR(page)) 64 if (IS_ERR(page))
112 return PTR_ERR(page); 65 return PTR_ERR(page);
113 66
114 max = (u_long*)page_address(page) + PAGE_SIZE; 67 max = page_address(page) + PAGE_SIZE;
115 for (p=(u_long*)page_address(page); p<max; p++) 68 for (p=page_address(page); p<max; p++)
116 if (*p != -1UL) { 69 if (*p != -1UL) {
117 lock_page(page); 70 lock_page(page);
118 memset(page_address(page), 0xff, PAGE_SIZE); 71 memset(page_address(page), 0xff, PAGE_SIZE);
@@ -174,8 +127,7 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
174 cpylen = len; // this page 127 cpylen = len; // this page
175 len = len - cpylen; 128 len = len - cpylen;
176 129
177 // Get page 130 page = page_read(dev->blkdev->bd_inode->i_mapping, index);
178 page = page_readahead(dev->blkdev->bd_inode->i_mapping, index);
179 if (!page) 131 if (!page)
180 return -ENOMEM; 132 return -ENOMEM;
181 if (IS_ERR(page)) 133 if (IS_ERR(page))
@@ -213,8 +165,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
213 cpylen = len; // this page 165 cpylen = len; // this page
214 len = len - cpylen; 166 len = len - cpylen;
215 167
216 // Get page 168 page = page_read(mapping, index);
217 page = page_readahead(mapping, index);
218 if (!page) 169 if (!page)
219 return -ENOMEM; 170 return -ENOMEM;
220 if (IS_ERR(page)) 171 if (IS_ERR(page))
@@ -308,9 +259,9 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
308 /* We might not have rootfs mounted at this point. Try 259 /* We might not have rootfs mounted at this point. Try
309 to resolve the device name by other means. */ 260 to resolve the device name by other means. */
310 261
311 dev_t dev = name_to_dev_t(devname); 262 dev_t devt = name_to_dev_t(devname);
312 if (dev != 0) { 263 if (devt) {
313 bdev = open_by_devnum(dev, FMODE_WRITE | FMODE_READ); 264 bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
314 } 265 }
315 } 266 }
316#endif 267#endif