aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2006-01-08 16:34:22 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-13 19:29:54 -0500
commit1d6432fe10c3e724e307dd7137cd293a0edcae80 (patch)
treee32ba2eaecff99b2b86455ed2df8365b082cd396 /drivers/mtd
parentffa458c1bd9b6f653008d450f337602f3d52a646 (diff)
[PATCH] spi: mtd dataflash driver
This is a conversion of the AT91rm9200 DataFlash MTD driver to use the lightweight SPI framework, and no longer be AT91-specific. It compiles down to less than 3KBytes on ARM. The driver allows board-specific init code to provide platform_data with the relevant MTD partitioning information, and hotplugs. This version has been lightly tested. Its parent at91_dataflash driver has been pretty well banged on, although kernel.org JFFS2 dataflash support was acting broken the last time I tried it. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/Kconfig8
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c623
3 files changed, 632 insertions, 0 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 9a2aa4033c6a..84f2eb1fae02 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -47,6 +47,14 @@ config MTD_MS02NV
47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a 47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a
48 DECsystem 5900 equipped with such a module. 48 DECsystem 5900 equipped with such a module.
49 49
50config MTD_DATAFLASH
51 tristate "Support for AT45xxx DataFlash"
52 depends on MTD && SPI_MASTER && EXPERIMENTAL
53 help
54 This enables access to AT45xxx DataFlash chips, using SPI.
55 Sometimes DataFlash chips are packaged inside MMC-format
56 cards; at this writing, the MMC stack won't handle those.
57
50config MTD_SLRAM 58config MTD_SLRAM
51 tristate "Uncached system RAM" 59 tristate "Uncached system RAM"
52 depends on MTD 60 depends on MTD
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index e38db348057d..cd8d8074b5b6 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
23obj-$(CONFIG_MTD_LART) += lart.o 23obj-$(CONFIG_MTD_LART) += lart.o
24obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o 24obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
25obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 25obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
26obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
new file mode 100644
index 000000000000..a39b3b6b266c
--- /dev/null
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -0,0 +1,623 @@
1/*
2 * Atmel AT45xxx DataFlash MTD driver for lightweight SPI framework
3 *
4 * Largely derived from at91_dataflash.c:
5 * Copyright (C) 2003-2005 SAN People (Pty) Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11*/
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/spi/spi.h>
19#include <linux/spi/flash.h>
20
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/partitions.h>
23
24
25/*
26 * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in
27 * each chip, which may be used for double buffered I/O; but this driver
28 * doesn't (yet) use these for any kind of i/o overlap or prefetching.
29 *
30 * Sometimes DataFlash is packaged in MMC-format cards, although the
31 * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash
32 * protocols during enumeration.
33 */
34
35#define CONFIG_DATAFLASH_WRITE_VERIFY
36
37/* reads can bypass the buffers */
38#define OP_READ_CONTINUOUS 0xE8
39#define OP_READ_PAGE 0xD2
40
41/* group B requests can run even while status reports "busy" */
42#define OP_READ_STATUS 0xD7 /* group B */
43
44/* move data between host and buffer */
45#define OP_READ_BUFFER1 0xD4 /* group B */
46#define OP_READ_BUFFER2 0xD6 /* group B */
47#define OP_WRITE_BUFFER1 0x84 /* group B */
48#define OP_WRITE_BUFFER2 0x87 /* group B */
49
50/* erasing flash */
51#define OP_ERASE_PAGE 0x81
52#define OP_ERASE_BLOCK 0x50
53
54/* move data between buffer and flash */
55#define OP_TRANSFER_BUF1 0x53
56#define OP_TRANSFER_BUF2 0x55
57#define OP_MREAD_BUFFER1 0xD4
58#define OP_MREAD_BUFFER2 0xD6
59#define OP_MWERASE_BUFFER1 0x83
60#define OP_MWERASE_BUFFER2 0x86
61#define OP_MWRITE_BUFFER1 0x88 /* sector must be pre-erased */
62#define OP_MWRITE_BUFFER2 0x89 /* sector must be pre-erased */
63
64/* write to buffer, then write-erase to flash */
65#define OP_PROGRAM_VIA_BUF1 0x82
66#define OP_PROGRAM_VIA_BUF2 0x85
67
68/* compare buffer to flash */
69#define OP_COMPARE_BUF1 0x60
70#define OP_COMPARE_BUF2 0x61
71
72/* read flash to buffer, then write-erase to flash */
73#define OP_REWRITE_VIA_BUF1 0x58
74#define OP_REWRITE_VIA_BUF2 0x59
75
76/* newer chips report JEDEC manufacturer and device IDs; chip
77 * serial number and OTP bits; and per-sector writeprotect.
78 */
79#define OP_READ_ID 0x9F
80#define OP_READ_SECURITY 0x77
81#define OP_WRITE_SECURITY 0x9A /* OTP bits */
82
83
84struct dataflash {
85 u8 command[4];
86 char name[24];
87
88 unsigned partitioned:1;
89
90 unsigned short page_offset; /* offset in flash address */
91 unsigned int page_size; /* of bytes per page */
92
93 struct semaphore lock;
94 struct spi_device *spi;
95
96 struct mtd_info mtd;
97};
98
99#ifdef CONFIG_MTD_PARTITIONS
100#define mtd_has_partitions() (1)
101#else
102#define mtd_has_partitions() (0)
103#endif
104
105/* ......................................................................... */
106
107/*
108 * Return the status of the DataFlash device.
109 */
110static inline int dataflash_status(struct spi_device *spi)
111{
112 /* NOTE: at45db321c over 25 MHz wants to write
113 * a dummy byte after the opcode...
114 */
115 return spi_w8r8(spi, OP_READ_STATUS);
116}
117
118/*
119 * Poll the DataFlash device until it is READY.
120 * This usually takes 5-20 msec or so; more for sector erase.
121 */
122static int dataflash_waitready(struct spi_device *spi)
123{
124 int status;
125
126 for (;;) {
127 status = dataflash_status(spi);
128 if (status < 0) {
129 DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n",
130 spi->dev.bus_id, status);
131 status = 0;
132 }
133
134 if (status & (1 << 7)) /* RDY/nBSY */
135 return status;
136
137 msleep(3);
138 }
139}
140
141/* ......................................................................... */
142
143/*
144 * Erase pages of flash.
145 */
146static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
147{
148 struct dataflash *priv = (struct dataflash *)mtd->priv;
149 struct spi_device *spi = priv->spi;
150 struct spi_transfer x[1] = { { .tx_dma = 0, }, };
151 struct spi_message msg;
152 unsigned blocksize = priv->page_size << 3;
153 u8 *command;
154
155 DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n",
156 spi->dev.bus_id,
157 instr->addr, instr->len);
158
159 /* Sanity checks */
160 if ((instr->addr + instr->len) > mtd->size
161 || (instr->len % priv->page_size) != 0
162 || (instr->addr % priv->page_size) != 0)
163 return -EINVAL;
164
165 x[0].tx_buf = command = priv->command;
166 x[0].len = 4;
167 msg.transfers = x;
168 msg.n_transfer = 1;
169
170 down(&priv->lock);
171 while (instr->len > 0) {
172 unsigned int pageaddr;
173 int status;
174 int do_block;
175
176 /* Calculate flash page address; use block erase (for speed) if
177 * we're at a block boundary and need to erase the whole block.
178 */
179 pageaddr = instr->addr / priv->page_size;
180 do_block = (pageaddr & 0x7) == 0 && instr->len <= blocksize;
181 pageaddr = pageaddr << priv->page_offset;
182
183 command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
184 command[1] = (u8)(pageaddr >> 16);
185 command[2] = (u8)(pageaddr >> 8);
186 command[3] = 0;
187
188 DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n",
189 do_block ? "block" : "page",
190 command[0], command[1], command[2], command[3],
191 pageaddr);
192
193 status = spi_sync(spi, &msg);
194 (void) dataflash_waitready(spi);
195
196 if (status < 0) {
197 printk(KERN_ERR "%s: erase %x, err %d\n",
198 spi->dev.bus_id, pageaddr, status);
199 /* REVISIT: can retry instr->retries times; or
200 * giveup and instr->fail_addr = instr->addr;
201 */
202 continue;
203 }
204
205 if (do_block) {
206 instr->addr += blocksize;
207 instr->len -= blocksize;
208 } else {
209 instr->addr += priv->page_size;
210 instr->len -= priv->page_size;
211 }
212 }
213 up(&priv->lock);
214
215 /* Inform MTD subsystem that erase is complete */
216 instr->state = MTD_ERASE_DONE;
217 mtd_erase_callback(instr);
218
219 return 0;
220}
221
222/*
223 * Read from the DataFlash device.
224 * from : Start offset in flash device
225 * len : Amount to read
226 * retlen : About of data actually read
227 * buf : Buffer containing the data
228 */
229static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
230 size_t *retlen, u_char *buf)
231{
232 struct dataflash *priv = (struct dataflash *)mtd->priv;
233 struct spi_transfer x[2] = { { .tx_dma = 0, }, };
234 struct spi_message msg;
235 unsigned int addr;
236 u8 *command;
237 int status;
238
239 DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n",
240 priv->spi->dev.bus_id, (unsigned)from, (unsigned)(from + len));
241
242 *retlen = 0;
243
244 /* Sanity checks */
245 if (!len)
246 return 0;
247 if (from + len > mtd->size)
248 return -EINVAL;
249
250 /* Calculate flash page/byte address */
251 addr = (((unsigned)from / priv->page_size) << priv->page_offset)
252 + ((unsigned)from % priv->page_size);
253
254 command = priv->command;
255
256 DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
257 command[0], command[1], command[2], command[3]);
258
259 x[0].tx_buf = command;
260 x[0].len = 8;
261 x[1].rx_buf = buf;
262 x[1].len = len;
263 msg.transfers = x;
264 msg.n_transfer = 2;
265
266 down(&priv->lock);
267
268 /* Continuous read, max clock = f(car) which may be less than
269 * the peak rate available. Some chips support commands with
270 * fewer "don't care" bytes. Both buffers stay unchanged.
271 */
272 command[0] = OP_READ_CONTINUOUS;
273 command[1] = (u8)(addr >> 16);
274 command[2] = (u8)(addr >> 8);
275 command[3] = (u8)(addr >> 0);
276 /* plus 4 "don't care" bytes */
277
278 status = spi_sync(priv->spi, &msg);
279 up(&priv->lock);
280
281 if (status >= 0) {
282 *retlen = msg.actual_length - 8;
283 status = 0;
284 } else
285 DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n",
286 priv->spi->dev.bus_id,
287 (unsigned)from, (unsigned)(from + len),
288 status);
289 return status;
290}
291
292/*
293 * Write to the DataFlash device.
294 * to : Start offset in flash device
295 * len : Amount to write
296 * retlen : Amount of data actually written
297 * buf : Buffer containing the data
298 */
299static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
300 size_t * retlen, const u_char * buf)
301{
302 struct dataflash *priv = (struct dataflash *)mtd->priv;
303 struct spi_device *spi = priv->spi;
304 struct spi_transfer x[2] = { { .tx_dma = 0, }, };
305 struct spi_message msg;
306 unsigned int pageaddr, addr, offset, writelen;
307 size_t remaining = len;
308 u_char *writebuf = (u_char *) buf;
309 int status = -EINVAL;
310 u8 *command;
311
312 DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n",
313 spi->dev.bus_id, (unsigned)to, (unsigned)(to + len));
314
315 *retlen = 0;
316
317 /* Sanity checks */
318 if (!len)
319 return 0;
320 if ((to + len) > mtd->size)
321 return -EINVAL;
322
323 x[0].tx_buf = command = priv->command;
324 x[0].len = 4;
325 msg.transfers = x;
326
327 pageaddr = ((unsigned)to / priv->page_size);
328 offset = ((unsigned)to % priv->page_size);
329 if (offset + len > priv->page_size)
330 writelen = priv->page_size - offset;
331 else
332 writelen = len;
333
334 down(&priv->lock);
335 while (remaining > 0) {
336 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
337 pageaddr, offset, writelen);
338
339 /* REVISIT:
340 * (a) each page in a sector must be rewritten at least
341 * once every 10K sibling erase/program operations.
342 * (b) for pages that are already erased, we could
343 * use WRITE+MWRITE not PROGRAM for ~30% speedup.
344 * (c) WRITE to buffer could be done while waiting for
345 * a previous MWRITE/MWERASE to complete ...
346 * (d) error handling here seems to be mostly missing.
347 *
348 * Two persistent bits per page, plus a per-sector counter,
349 * could support (a) and (b) ... we might consider using
350 * the second half of sector zero, which is just one block,
351 * to track that state. (On AT91, that sector should also
352 * support boot-from-DataFlash.)
353 */
354
355 addr = pageaddr << priv->page_offset;
356
357 /* (1) Maybe transfer partial page to Buffer1 */
358 if (writelen != priv->page_size) {
359 command[0] = OP_TRANSFER_BUF1;
360 command[1] = (addr & 0x00FF0000) >> 16;
361 command[2] = (addr & 0x0000FF00) >> 8;
362 command[3] = 0;
363
364 DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
365 command[0], command[1], command[2], command[3]);
366
367 msg.n_transfer = 1;
368 status = spi_sync(spi, &msg);
369 if (status < 0)
370 DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
371 spi->dev.bus_id, addr, status);
372
373 (void) dataflash_waitready(priv->spi);
374 }
375
376 /* (2) Program full page via Buffer1 */
377 addr += offset;
378 command[0] = OP_PROGRAM_VIA_BUF1;
379 command[1] = (addr & 0x00FF0000) >> 16;
380 command[2] = (addr & 0x0000FF00) >> 8;
381 command[3] = (addr & 0x000000FF);
382
383 DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n",
384 command[0], command[1], command[2], command[3]);
385
386 x[1].tx_buf = writebuf;
387 x[1].len = writelen;
388 msg.n_transfer = 2;
389 status = spi_sync(spi, &msg);
390 if (status < 0)
391 DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
392 spi->dev.bus_id, addr, writelen, status);
393
394 (void) dataflash_waitready(priv->spi);
395
396#ifdef CONFIG_DATAFLASH_WRITE_VERIFY
397
398 /* (3) Compare to Buffer1 */
399 addr = pageaddr << priv->page_offset;
400 command[0] = OP_COMPARE_BUF1;
401 command[1] = (addr & 0x00FF0000) >> 16;
402 command[2] = (addr & 0x0000FF00) >> 8;
403 command[3] = 0;
404
405 DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
406 command[0], command[1], command[2], command[3]);
407
408 msg.n_transfer = 1;
409 status = spi_sync(spi, &msg);
410 if (status < 0)
411 DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",
412 spi->dev.bus_id, addr, status);
413
414 status = dataflash_waitready(priv->spi);
415
416 /* Check result of the compare operation */
417 if ((status & (1 << 6)) == 1) {
418 printk(KERN_ERR "%s: compare page %u, err %d\n",
419 spi->dev.bus_id, pageaddr, status);
420 remaining = 0;
421 status = -EIO;
422 break;
423 } else
424 status = 0;
425
426#endif /* CONFIG_DATAFLASH_WRITE_VERIFY */
427
428 remaining = remaining - writelen;
429 pageaddr++;
430 offset = 0;
431 writebuf += writelen;
432 *retlen += writelen;
433
434 if (remaining > priv->page_size)
435 writelen = priv->page_size;
436 else
437 writelen = remaining;
438 }
439 up(&priv->lock);
440
441 return status;
442}
443
444/* ......................................................................... */
445
446/*
447 * Register DataFlash device with MTD subsystem.
448 */
449static int __devinit
450add_dataflash(struct spi_device *spi, char *name,
451 int nr_pages, int pagesize, int pageoffset)
452{
453 struct dataflash *priv;
454 struct mtd_info *device;
455 struct flash_platform_data *pdata = spi->dev.platform_data;
456
457 priv = (struct dataflash *) kzalloc(sizeof *priv, GFP_KERNEL);
458 if (!priv)
459 return -ENOMEM;
460
461 init_MUTEX(&priv->lock);
462 priv->spi = spi;
463 priv->page_size = pagesize;
464 priv->page_offset = pageoffset;
465
466 /* name must be usable with cmdlinepart */
467 sprintf(priv->name, "spi%d.%d-%s",
468 spi->master->bus_num, spi->chip_select,
469 name);
470
471 device = &priv->mtd;
472 device->name = (pdata && pdata->name) ? pdata->name : priv->name;
473 device->size = nr_pages * pagesize;
474 device->erasesize = pagesize;
475 device->owner = THIS_MODULE;
476 device->type = MTD_DATAFLASH;
477 device->flags = MTD_CAP_NORFLASH;
478 device->erase = dataflash_erase;
479 device->read = dataflash_read;
480 device->write = dataflash_write;
481 device->priv = priv;
482
483 dev_info(&spi->dev, "%s (%d KBytes)\n", name, device->size/1024);
484 dev_set_drvdata(&spi->dev, priv);
485
486 if (mtd_has_partitions()) {
487 struct mtd_partition *parts;
488 int nr_parts = 0;
489
490#ifdef CONFIG_MTD_CMDLINE_PARTS
491 static const char *part_probes[] = { "cmdlinepart", NULL, };
492
493 nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
494#endif
495
496 if (nr_parts <= 0 && pdata && pdata->parts) {
497 parts = pdata->parts;
498 nr_parts = pdata->nr_parts;
499 }
500
501 if (nr_parts > 0) {
502 priv->partitioned = 1;
503 return add_mtd_partitions(device, parts, nr_parts);
504 }
505 } else if (pdata->nr_parts)
506 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
507 pdata->nr_parts, device->name);
508
509 return add_mtd_device(device) == 1 ? -ENODEV : 0;
510}
511
512/*
513 * Detect and initialize DataFlash device:
514 *
515 * Device Density ID code #Pages PageSize Offset
516 * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9
517 * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1025 264 9
518 * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9
519 * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9
520 * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10
521 * AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10
522 * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11
523 * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11
524 */
525static int __devinit dataflash_probe(struct spi_device *spi)
526{
527 int status;
528
529 status = dataflash_status(spi);
530 if (status <= 0 || status == 0xff) {
531 DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
532 spi->dev.bus_id, status);
533 if (status == 0xff)
534 status = -ENODEV;
535 return status;
536 }
537
538 /* if there's a device there, assume it's dataflash.
539 * board setup should have set spi->max_speed_max to
540 * match f(car) for continuous reads, mode 0 or 3.
541 */
542 switch (status & 0x3c) {
543 case 0x0c: /* 0 0 1 1 x x */
544 status = add_dataflash(spi, "AT45DB011B", 512, 264, 9);
545 break;
546 case 0x14: /* 0 1 0 1 x x */
547 status = add_dataflash(spi, "AT45DB021B", 1025, 264, 9);
548 break;
549 case 0x1c: /* 0 1 1 1 x x */
550 status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9);
551 break;
552 case 0x24: /* 1 0 0 1 x x */
553 status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9);
554 break;
555 case 0x2c: /* 1 0 1 1 x x */
556 status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10);
557 break;
558 case 0x34: /* 1 1 0 1 x x */
559 status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10);
560 break;
561 case 0x38: /* 1 1 1 x x x */
562 case 0x3c:
563 status = add_dataflash(spi, "AT45DB642x", 8192, 1056, 11);
564 break;
565 /* obsolete AT45DB1282 not (yet?) supported */
566 default:
567 DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n",
568 spi->dev.bus_id, status & 0x3c);
569 status = -ENODEV;
570 }
571
572 if (status < 0)
573 DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n",
574 spi->dev.bus_id, status);
575
576 return status;
577}
578
579static int __devexit dataflash_remove(struct spi_device *spi)
580{
581 struct dataflash *flash = dev_get_drvdata(&spi->dev);
582 int status;
583
584 DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", spi->dev.bus_id);
585
586 if (mtd_has_partitions() && flash->partitioned)
587 status = del_mtd_partitions(&flash->mtd);
588 else
589 status = del_mtd_device(&flash->mtd);
590 if (status == 0)
591 kfree(flash);
592 return status;
593}
594
595static struct spi_driver dataflash_driver = {
596 .driver = {
597 .name = "mtd_dataflash",
598 .bus = &spi_bus_type,
599 .owner = THIS_MODULE,
600 },
601
602 .probe = dataflash_probe,
603 .remove = __devexit_p(dataflash_remove),
604
605 /* FIXME: investigate suspend and resume... */
606};
607
608static int __init dataflash_init(void)
609{
610 return spi_register_driver(&dataflash_driver);
611}
612module_init(dataflash_init);
613
614static void __exit dataflash_exit(void)
615{
616 spi_unregister_driver(&dataflash_driver);
617}
618module_exit(dataflash_exit);
619
620
621MODULE_LICENSE("GPL");
622MODULE_AUTHOR("Andrew Victor, David Brownell");
623MODULE_DESCRIPTION("MTD DataFlash driver");