aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorIan Molton <spyro@f2s.com>2008-07-15 11:04:22 -0400
committerSamuel Ortiz <sameo@openedhand.com>2008-08-10 17:30:09 -0400
commitec43b8161bd82535fa8099ee6e98cc554de48614 (patch)
treeda8e3e5203d93b26ab5d497e4d9cb0e87c1784d2 /drivers/mtd/nand
parent8a4fbe013fb6a2a65a4eddcddb888ebe38d0270d (diff)
mfd: driver for the TMIO NAND controller
This patch adds support for the NAND controller commonly found in TMIO based MFDs. Signed-off-by: Ian Molton <spyro@f2s.com> Acked-By: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/Kconfig7
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/tmio_nand.c556
3 files changed, 564 insertions, 0 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 02f9cc30d77b..fd6debb24252 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -351,6 +351,13 @@ config MTD_NAND_PASEMI
351 Enables support for NAND Flash interface on PA Semi PWRficient 351 Enables support for NAND Flash interface on PA Semi PWRficient
352 based boards 352 based boards
353 353
354config MTD_NAND_TMIO
355 tristate "NAND Flash device on Toshiba Mobile IO Controller"
356 depends on MTD_NAND && MFD_CORE
357 help
358 Support for NAND flash connected to a Toshiba Mobile IO
359 Controller in some PDAs, including the Sharp SL6000x.
360
354config MTD_NAND_NANDSIM 361config MTD_NAND_NANDSIM
355 tristate "Support for NAND Flash Simulator" 362 tristate "Support for NAND Flash Simulator"
356 depends on MTD_PARTITIONS 363 depends on MTD_PARTITIONS
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d772581de573..b786c5da82da 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o
27obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o 27obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
28obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o 28obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
29obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o 29obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
30obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
30obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o 31obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
31obj-$(CONFIG_MTD_ALAUDA) += alauda.o 32obj-$(CONFIG_MTD_ALAUDA) += alauda.o
32obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o 33obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
new file mode 100644
index 000000000000..cbab654b03c8
--- /dev/null
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -0,0 +1,556 @@
1/*
2 * Toshiba TMIO NAND flash controller driver
3 *
4 * Slightly murky pre-git history of the driver:
5 *
6 * Copyright (c) Ian Molton 2004, 2005, 2008
7 * Original work, independant of sharps code. Included hardware ECC support.
8 * Hard ECC did not work for writes in the early revisions.
9 * Copyright (c) Dirk Opfer 2005.
10 * Modifications developed from sharps code but
11 * NOT containing any, ported onto Ians base.
12 * Copyright (c) Chris Humbert 2005
13 * Copyright (c) Dmitry Baryshkov 2008
14 * Minor fixes
15 *
16 * Parts copyright Sebastian Carlier
17 *
18 * This file is licensed under
19 * the terms of the GNU General Public License version 2. This program
20 * is licensed "as is" without any warranty of any kind, whether express
21 * or implied.
22 *
23 */
24
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
30#include <linux/mfd/tmio.h>
31#include <linux/delay.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34#include <linux/interrupt.h>
35#include <linux/ioport.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/nand.h>
38#include <linux/mtd/nand_ecc.h>
39#include <linux/mtd/partitions.h>
40
41/*--------------------------------------------------------------------------*/
42
43/*
44 * NAND Flash Host Controller Configuration Register
45 */
46#define CCR_COMMAND 0x04 /* w Command */
47#define CCR_BASE 0x10 /* l NAND Flash Control Reg Base Addr */
48#define CCR_INTP 0x3d /* b Interrupt Pin */
49#define CCR_INTE 0x48 /* b Interrupt Enable */
50#define CCR_EC 0x4a /* b Event Control */
51#define CCR_ICC 0x4c /* b Internal Clock Control */
52#define CCR_ECCC 0x5b /* b ECC Control */
53#define CCR_NFTC 0x60 /* b NAND Flash Transaction Control */
54#define CCR_NFM 0x61 /* b NAND Flash Monitor */
55#define CCR_NFPSC 0x62 /* b NAND Flash Power Supply Control */
56#define CCR_NFDC 0x63 /* b NAND Flash Detect Control */
57
58/*
59 * NAND Flash Control Register
60 */
61#define FCR_DATA 0x00 /* bwl Data Register */
62#define FCR_MODE 0x04 /* b Mode Register */
63#define FCR_STATUS 0x05 /* b Status Register */
64#define FCR_ISR 0x06 /* b Interrupt Status Register */
65#define FCR_IMR 0x07 /* b Interrupt Mask Register */
66
67/* FCR_MODE Register Command List */
68#define FCR_MODE_DATA 0x94 /* Data Data_Mode */
69#define FCR_MODE_COMMAND 0x95 /* Data Command_Mode */
70#define FCR_MODE_ADDRESS 0x96 /* Data Address_Mode */
71
72#define FCR_MODE_HWECC_CALC 0xB4 /* HW-ECC Data */
73#define FCR_MODE_HWECC_RESULT 0xD4 /* HW-ECC Calc result Read_Mode */
74#define FCR_MODE_HWECC_RESET 0xF4 /* HW-ECC Reset */
75
76#define FCR_MODE_POWER_ON 0x0C /* Power Supply ON to SSFDC card */
77#define FCR_MODE_POWER_OFF 0x08 /* Power Supply OFF to SSFDC card */
78
79#define FCR_MODE_LED_OFF 0x00 /* LED OFF */
80#define FCR_MODE_LED_ON 0x04 /* LED ON */
81
82#define FCR_MODE_EJECT_ON 0x68 /* Ejection events active */
83#define FCR_MODE_EJECT_OFF 0x08 /* Ejection events ignored */
84
85#define FCR_MODE_LOCK 0x6C /* Lock_Mode. Eject Switch Invalid */
86#define FCR_MODE_UNLOCK 0x0C /* UnLock_Mode. Eject Switch is valid */
87
88#define FCR_MODE_CONTROLLER_ID 0x40 /* Controller ID Read */
89#define FCR_MODE_STANDBY 0x00 /* SSFDC card Changes Standby State */
90
91#define FCR_MODE_WE 0x80
92#define FCR_MODE_ECC1 0x40
93#define FCR_MODE_ECC0 0x20
94#define FCR_MODE_CE 0x10
95#define FCR_MODE_PCNT1 0x08
96#define FCR_MODE_PCNT0 0x04
97#define FCR_MODE_ALE 0x02
98#define FCR_MODE_CLE 0x01
99
100#define FCR_STATUS_BUSY 0x80
101
102/*--------------------------------------------------------------------------*/
103
104struct tmio_nand {
105 struct mtd_info mtd;
106 struct nand_chip chip;
107
108 struct platform_device *dev;
109
110 void __iomem *ccr;
111 void __iomem *fcr;
112 unsigned long fcr_phys;
113
114 unsigned int irq;
115
116 /* for tmio_nand_read_byte */
117 u8 read;
118 unsigned read_good:1;
119};
120
121#define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd)
122
123#ifdef CONFIG_MTD_CMDLINE_PARTS
124static const char *part_probes[] = { "cmdlinepart", NULL };
125#endif
126
127/*--------------------------------------------------------------------------*/
128
129static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
130 unsigned int ctrl)
131{
132 struct tmio_nand *tmio = mtd_to_tmio(mtd);
133 struct nand_chip *chip = mtd->priv;
134
135 if (ctrl & NAND_CTRL_CHANGE) {
136 u8 mode;
137
138 if (ctrl & NAND_NCE) {
139 mode = FCR_MODE_DATA;
140
141 if (ctrl & NAND_CLE)
142 mode |= FCR_MODE_CLE;
143 else
144 mode &= ~FCR_MODE_CLE;
145
146 if (ctrl & NAND_ALE)
147 mode |= FCR_MODE_ALE;
148 else
149 mode &= ~FCR_MODE_ALE;
150 } else {
151 mode = FCR_MODE_STANDBY;
152 }
153
154 tmio_iowrite8(mode, tmio->fcr + FCR_MODE);
155 tmio->read_good = 0;
156 }
157
158 if (cmd != NAND_CMD_NONE)
159 tmio_iowrite8(cmd, chip->IO_ADDR_W);
160}
161
162static int tmio_nand_dev_ready(struct mtd_info *mtd)
163{
164 struct tmio_nand *tmio = mtd_to_tmio(mtd);
165
166 return !(tmio_ioread8(tmio->fcr + FCR_STATUS) & FCR_STATUS_BUSY);
167}
168
169static irqreturn_t tmio_irq(int irq, void *__tmio)
170{
171 struct tmio_nand *tmio = __tmio;
172 struct nand_chip *nand_chip = &tmio->chip;
173
174 /* disable RDYREQ interrupt */
175 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
176
177 if (unlikely(!waitqueue_active(&nand_chip->controller->wq)))
178 dev_warn(&tmio->dev->dev, "spurious interrupt\n");
179
180 wake_up(&nand_chip->controller->wq);
181 return IRQ_HANDLED;
182}
183
184/*
185 *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
186 *This interrupt is normally disabled, but for long operations like
187 *erase and write, we enable it to wake us up. The irq handler
188 *disables the interrupt.
189 */
190static int
191tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
192{
193 struct tmio_nand *tmio = mtd_to_tmio(mtd);
194 long timeout;
195
196 /* enable RDYREQ interrupt */
197 tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
198 tmio_iowrite8(0x81, tmio->fcr + FCR_IMR);
199
200 timeout = wait_event_timeout(nand_chip->controller->wq,
201 tmio_nand_dev_ready(mtd),
202 msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));
203
204 if (unlikely(!tmio_nand_dev_ready(mtd))) {
205 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
206 dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
207 nand_chip->state == FL_ERASING ? "erase" : "program",
208 nand_chip->state == FL_ERASING ? 400 : 20);
209
210 } else if (unlikely(!timeout)) {
211 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
212 dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
213 }
214
215 nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
216 return nand_chip->read_byte(mtd);
217}
218
219/*
220 *The TMIO controller combines two 8-bit data bytes into one 16-bit
221 *word. This function separates them so nand_base.c works as expected,
222 *especially its NAND_CMD_READID routines.
223 *
224 *To prevent stale data from being read, tmio_nand_hwcontrol() clears
225 *tmio->read_good.
226 */
227static u_char tmio_nand_read_byte(struct mtd_info *mtd)
228{
229 struct tmio_nand *tmio = mtd_to_tmio(mtd);
230 unsigned int data;
231
232 if (tmio->read_good--)
233 return tmio->read;
234
235 data = tmio_ioread16(tmio->fcr + FCR_DATA);
236 tmio->read = data >> 8;
237 return data;
238}
239
240/*
241 *The TMIO controller converts an 8-bit NAND interface to a 16-bit
242 *bus interface, so all data reads and writes must be 16-bit wide.
243 *Thus, we implement 16-bit versions of the read, write, and verify
244 *buffer functions.
245 */
246static void
247tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
248{
249 struct tmio_nand *tmio = mtd_to_tmio(mtd);
250
251 tmio_iowrite16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
252}
253
254static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
255{
256 struct tmio_nand *tmio = mtd_to_tmio(mtd);
257
258 tmio_ioread16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
259}
260
261static int
262tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
263{
264 struct tmio_nand *tmio = mtd_to_tmio(mtd);
265 u16 *p = (u16 *) buf;
266
267 for (len >>= 1; len; len--)
268 if (*(p++) != tmio_ioread16(tmio->fcr + FCR_DATA))
269 return -EFAULT;
270 return 0;
271}
272
273static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
274{
275 struct tmio_nand *tmio = mtd_to_tmio(mtd);
276
277 tmio_iowrite8(FCR_MODE_HWECC_RESET, tmio->fcr + FCR_MODE);
278 tmio_ioread8(tmio->fcr + FCR_DATA); /* dummy read */
279 tmio_iowrite8(FCR_MODE_HWECC_CALC, tmio->fcr + FCR_MODE);
280}
281
282static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
283 u_char *ecc_code)
284{
285 struct tmio_nand *tmio = mtd_to_tmio(mtd);
286 unsigned int ecc;
287
288 tmio_iowrite8(FCR_MODE_HWECC_RESULT, tmio->fcr + FCR_MODE);
289
290 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
291 ecc_code[1] = ecc; /* 000-255 LP7-0 */
292 ecc_code[0] = ecc >> 8; /* 000-255 LP15-8 */
293 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
294 ecc_code[2] = ecc; /* 000-255 CP5-0,11b */
295 ecc_code[4] = ecc >> 8; /* 256-511 LP7-0 */
296 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
297 ecc_code[3] = ecc; /* 256-511 LP15-8 */
298 ecc_code[5] = ecc >> 8; /* 256-511 CP5-0,11b */
299
300 tmio_iowrite8(FCR_MODE_DATA, tmio->fcr + FCR_MODE);
301 return 0;
302}
303
304static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
305{
306 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
307 int ret;
308
309 if (cell->enable) {
310 ret = cell->enable(dev);
311 if (ret)
312 return ret;
313 }
314
315 /* (4Ch) CLKRUN Enable 1st spcrunc */
316 tmio_iowrite8(0x81, tmio->ccr + CCR_ICC);
317
318 /* (10h)BaseAddress 0x1000 spba.spba2 */
319 tmio_iowrite16(tmio->fcr_phys, tmio->ccr + CCR_BASE);
320 tmio_iowrite16(tmio->fcr_phys >> 16, tmio->ccr + CCR_BASE + 16);
321
322 /* (04h)Command Register I/O spcmd */
323 tmio_iowrite8(0x02, tmio->ccr + CCR_COMMAND);
324
325 /* (62h) Power Supply Control ssmpwc */
326 /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
327 tmio_iowrite8(0x02, tmio->ccr + CCR_NFPSC);
328
329 /* (63h) Detect Control ssmdtc */
330 tmio_iowrite8(0x02, tmio->ccr + CCR_NFDC);
331
332 /* Interrupt status register clear sintst */
333 tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
334
335 /* After power supply, Media are reset smode */
336 tmio_iowrite8(FCR_MODE_POWER_ON, tmio->fcr + FCR_MODE);
337 tmio_iowrite8(FCR_MODE_COMMAND, tmio->fcr + FCR_MODE);
338 tmio_iowrite8(NAND_CMD_RESET, tmio->fcr + FCR_DATA);
339
340 /* Standby Mode smode */
341 tmio_iowrite8(FCR_MODE_STANDBY, tmio->fcr + FCR_MODE);
342
343 mdelay(5);
344
345 return 0;
346}
347
348static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
349{
350 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
351
352 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
353 if (cell->disable)
354 cell->disable(dev);
355}
356
357static int tmio_probe(struct platform_device *dev)
358{
359 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
360 struct tmio_nand_data *data = cell->driver_data;
361 struct resource *fcr = platform_get_resource(dev,
362 IORESOURCE_MEM, 0);
363 struct resource *ccr = platform_get_resource(dev,
364 IORESOURCE_MEM, 1);
365 int irq = platform_get_irq(dev, 0);
366 struct tmio_nand *tmio;
367 struct mtd_info *mtd;
368 struct nand_chip *nand_chip;
369#ifdef CONFIG_MTD_PARTITIONS
370 struct mtd_partition *parts;
371 int nbparts = 0;
372#endif
373 int retval;
374
375 if (data == NULL)
376 dev_warn(&dev->dev, "NULL platform data!\n");
377
378 tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
379 if (!tmio) {
380 retval = -ENOMEM;
381 goto err_kzalloc;
382 }
383
384 tmio->dev = dev;
385
386 platform_set_drvdata(dev, tmio);
387 mtd = &tmio->mtd;
388 nand_chip = &tmio->chip;
389 mtd->priv = nand_chip;
390 mtd->name = "tmio-nand";
391
392 tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
393 if (!tmio->ccr) {
394 retval = -EIO;
395 goto err_iomap_ccr;
396 }
397
398 tmio->fcr_phys = (unsigned long)fcr->start;
399 tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
400 if (!tmio->fcr) {
401 retval = -EIO;
402 goto err_iomap_fcr;
403 }
404
405 retval = tmio_hw_init(dev, tmio);
406 if (retval)
407 goto err_hwinit;
408
409 /* Set address of NAND IO lines */
410 nand_chip->IO_ADDR_R = tmio->fcr;
411 nand_chip->IO_ADDR_W = tmio->fcr;
412
413 /* Set address of hardware control function */
414 nand_chip->cmd_ctrl = tmio_nand_hwcontrol;
415 nand_chip->dev_ready = tmio_nand_dev_ready;
416 nand_chip->read_byte = tmio_nand_read_byte;
417 nand_chip->write_buf = tmio_nand_write_buf;
418 nand_chip->read_buf = tmio_nand_read_buf;
419 nand_chip->verify_buf = tmio_nand_verify_buf;
420
421 /* set eccmode using hardware ECC */
422 nand_chip->ecc.mode = NAND_ECC_HW;
423 nand_chip->ecc.size = 512;
424 nand_chip->ecc.bytes = 6;
425 nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
426 nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
427 nand_chip->ecc.correct = nand_correct_data;
428
429 if (data)
430 nand_chip->badblock_pattern = data->badblock_pattern;
431
432 /* 15 us command delay time */
433 nand_chip->chip_delay = 15;
434
435 retval = request_irq(irq, &tmio_irq,
436 IRQF_DISABLED, dev->dev.bus_id, tmio);
437 if (retval) {
438 dev_err(&dev->dev, "request_irq error %d\n", retval);
439 goto err_irq;
440 }
441
442 tmio->irq = irq;
443 nand_chip->waitfunc = tmio_nand_wait;
444
445 /* Scan to find existence of the device */
446 if (nand_scan(mtd, 1)) {
447 retval = -ENODEV;
448 goto err_scan;
449 }
450 /* Register the partitions */
451#ifdef CONFIG_MTD_PARTITIONS
452#ifdef CONFIG_MTD_CMDLINE_PARTS
453 nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
454#endif
455 if (nbparts <= 0 && data) {
456 parts = data->partition;
457 nbparts = data->num_partitions;
458 }
459
460 if (nbparts)
461 retval = add_mtd_partitions(mtd, parts, nbparts);
462 else
463#endif
464 retval = add_mtd_device(mtd);
465
466 if (!retval)
467 return retval;
468
469 nand_release(mtd);
470
471err_scan:
472 if (tmio->irq)
473 free_irq(tmio->irq, tmio);
474err_irq:
475 tmio_hw_stop(dev, tmio);
476err_hwinit:
477 iounmap(tmio->fcr);
478err_iomap_fcr:
479 iounmap(tmio->ccr);
480err_iomap_ccr:
481 kfree(tmio);
482err_kzalloc:
483 return retval;
484}
485
486static int tmio_remove(struct platform_device *dev)
487{
488 struct tmio_nand *tmio = platform_get_drvdata(dev);
489
490 nand_release(&tmio->mtd);
491 if (tmio->irq)
492 free_irq(tmio->irq, tmio);
493 tmio_hw_stop(dev, tmio);
494 iounmap(tmio->fcr);
495 iounmap(tmio->ccr);
496 kfree(tmio);
497 return 0;
498}
499
500#ifdef CONFIG_PM
501static int tmio_suspend(struct platform_device *dev, pm_message_t state)
502{
503 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
504
505 if (cell->suspend)
506 cell->suspend(dev);
507
508 tmio_hw_stop(dev, platform_get_drvdata(dev));
509 return 0;
510}
511
512static int tmio_resume(struct platform_device *dev)
513{
514 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
515
516 /* FIXME - is this required or merely another attack of the broken
517 * SHARP platform? Looks suspicious.
518 */
519 tmio_hw_init(dev, platform_get_drvdata(dev));
520
521 if (cell->resume)
522 cell->resume(dev);
523
524 return 0;
525}
526#else
527#define tmio_suspend NULL
528#define tmio_resume NULL
529#endif
530
531static struct platform_driver tmio_driver = {
532 .driver.name = "tmio-nand",
533 .driver.owner = THIS_MODULE,
534 .probe = tmio_probe,
535 .remove = tmio_remove,
536 .suspend = tmio_suspend,
537 .resume = tmio_resume,
538};
539
540static int __init tmio_init(void)
541{
542 return platform_driver_register(&tmio_driver);
543}
544
545static void __exit tmio_exit(void)
546{
547 platform_driver_unregister(&tmio_driver);
548}
549
550module_init(tmio_init);
551module_exit(tmio_exit);
552
553MODULE_LICENSE("GPL v2");
554MODULE_AUTHOR("Ian Molton, Dirk Opfer, Chris Humbert, Dmitry Baryshkov");
555MODULE_DESCRIPTION("NAND flash driver on Toshiba Mobile IO controller");
556MODULE_ALIAS("platform:tmio-nand");