merge of '178eac00dc5aa8338d42e8e203633bec7817bbf6'
[vuplus_openembedded] / packages / linux / linux-rp-2.6.24 / tosa / 0008-Nand-driver-for-TMIO-devices.patch
1 From 917b3997a39396f5f51418930de7b933ad053bad Mon Sep 17 00:00:00 2001
2 From: Ian Molton <spyro@f2s.com>
3 Date: Sat, 29 Dec 2007 15:14:23 +0000
4 Subject: [PATCH 08/64] Nand driver for TMIO devices
5
6 ---
7  drivers/mtd/nand/Kconfig     |    7 +
8  drivers/mtd/nand/Makefile    |    1 +
9  drivers/mtd/nand/tmio_nand.c |  557 ++++++++++++++++++++++++++++++++++++++++++
10  3 files changed, 565 insertions(+), 0 deletions(-)
11  create mode 100644 drivers/mtd/nand/tmio_nand.c
12
13 diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
14 index 246d451..43e489a 100644
15 --- a/drivers/mtd/nand/Kconfig
16 +++ b/drivers/mtd/nand/Kconfig
17 @@ -284,6 +284,13 @@ config MTD_NAND_CM_X270
18         depends on MTD_NAND && MACH_ARMCORE
19  
20  
21 +config MTD_NAND_TMIO
22 +       tristate "NAND Flash device on Toshiba Mobile IO Controller"
23 +       depends on MTD_NAND && MFD_CORE
24 +       help
25 +         Support for NAND flash connected to a Toshiba Mobile IO
26 +         Controller in some PDAs, including the Sharp SL6000x.
27 +
28  config MTD_NAND_NANDSIM
29         tristate "Support for NAND Flash Simulator"
30         depends on MTD_PARTITIONS
31 diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
32 index 3ad6c01..d839ebd 100644
33 --- a/drivers/mtd/nand/Makefile
34 +++ b/drivers/mtd/nand/Makefile
35 @@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_NDFC)           += ndfc.o
36  obj-$(CONFIG_MTD_NAND_AT91)            += at91_nand.o
37  obj-$(CONFIG_MTD_NAND_CM_X270)         += cmx270_nand.o
38  obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)   += excite_nandflash.o
39 +obj-$(CONFIG_MTD_NAND_TMIO)            += tmio_nand.o
40  obj-$(CONFIG_MTD_NAND_PLATFORM)                += plat_nand.o
41  obj-$(CONFIG_MTD_ALAUDA)               += alauda.o
42  
43 diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
44 new file mode 100644
45 index 0000000..450b4ec
46 --- /dev/null
47 +++ b/drivers/mtd/nand/tmio_nand.c
48 @@ -0,0 +1,557 @@
49 +#include <linux/kernel.h>
50 +#include <linux/module.h>
51 +#include <linux/platform_device.h>
52 +#include <linux/mfd-core.h>
53 +#include <linux/mfd/tmio.h>
54 +#include <linux/delay.h>
55 +#include <linux/io.h>
56 +#include <linux/irq.h>
57 +#include <linux/interrupt.h>
58 +#include <linux/ioport.h>
59 +#include <linux/mtd/mtd.h>
60 +#include <linux/mtd/nand.h>
61 +#include <linux/mtd/nand_ecc.h>
62 +#include <linux/mtd/partitions.h>
63 +
64 +/*--------------------------------------------------------------------------*/
65 +
66 +/* tmio_nfcr.mode Register Command List */
67 +#define FCR_MODE_DATA          0x94    /* Data Data_Mode */
68 +#define FCR_MODE_COMMAND       0x95    /* Data Command_Mode */
69 +#define FCR_MODE_ADDRESS       0x96    /* Data Address_Mode */
70 +
71 +#define FCR_MODE_HWECC_CALC    0xB4    /* HW-ECC Data */
72 +#define FCR_MODE_HWECC_RESULT  0xD4    /* HW-ECC Calculation Result Read_Mode */
73 +#define FCR_MODE_HWECC_RESET   0xF4    /* HW-ECC Reset */
74 +
75 +#define FCR_MODE_POWER_ON      0x0C    /* Power Supply ON  to SSFDC card */
76 +#define FCR_MODE_POWER_OFF     0x08    /* Power Supply OFF to SSFDC card */
77 +
78 +#define FCR_MODE_LED_OFF       0x00    /* LED OFF */
79 +#define FCR_MODE_LED_ON                0x04    /* LED ON */
80 +
81 +#define FCR_MODE_EJECT_ON      0x68    /* Ejection Demand from Penguin is Advanced */
82 +#define FCR_MODE_EJECT_OFF     0x08    /* Ejection Demand from Penguin is Not Advanced */
83 +
84 +#define FCR_MODE_LOCK          0x6C    /* Operates By Lock_Mode. Ejection Switch is Invalid */
85 +#define FCR_MODE_UNLOCK                0x0C    /* Operates By UnLock_Mode.Ejection Switch is Effective */
86 +
87 +#define FCR_MODE_CONTROLLER_ID 0x40    /* Controller ID Read */
88 +#define FCR_MODE_STANDBY       0x00    /* SSFDC card Changes Standby State */
89 +
90 +#define FCR_MODE_WE            0x80
91 +#define FCR_MODE_ECC1          0x40
92 +#define FCR_MODE_ECC0          0x20
93 +#define FCR_MODE_CE            0x10
94 +#define FCR_MODE_PCNT1         0x08
95 +#define FCR_MODE_PCNT0         0x04
96 +#define FCR_MODE_ALE           0x02
97 +#define FCR_MODE_CLE           0x01
98 +
99 +#define FCR_STATUS_BUSY                0x80
100 +
101 +/*
102 +  *NAND Flash Host Controller Configuration Register
103 + */
104 +struct tmio_nfhccr {
105 +       u8 x00[4];
106 +       u16     command;        /* 0x04 Command                         */
107 +       u8 x01[0x0a];
108 +       u16     base[2];        /* 0x10 NAND Flash Control Reg Base Addr*/
109 +       u8 x02[0x29];
110 +       u8      intp;           /* 0x3d Interrupt Pin                   */
111 +       u8 x03[0x0a];
112 +       u8      inte;           /* 0x48 Interrupt Enable                */
113 +       u8 x04;
114 +       u8      ec;             /* 0x4a Event Control                   */
115 +       u8 x05;
116 +       u8      icc;            /* 0x4c Internal Clock Control          */
117 +       u8 x06[0x0e];
118 +       u8      eccc;           /* 0x5b ECC Control                     */
119 +       u8 x07[4];
120 +       u8      nftc;           /* 0x60 NAND Flash Transaction Control  */
121 +       u8      nfm;            /* 0x61 NAND Flash Monitor              */
122 +       u8      nfpsc;          /* 0x62 NAND Flash Power Supply Control */
123 +       u8      nfdc;           /* 0x63 NAND Flash Detect Control       */
124 +       u8 x08[0x9c];
125 +} __attribute__ ((packed));
126 +
127 +/*
128 +  *NAND Flash Control Register
129 + */
130 +struct tmio_nfcr {
131 +union {
132 +       u8      u8;             /* 0x00 Data Register                   */
133 +       u16     u16;
134 +       u32     u32;
135 +} __attribute__ ((packed));
136 +       u8      mode;           /* 0x04 Mode Register                   */
137 +       u8      status;         /* 0x05 Status Register                 */
138 +       u8      isr;            /* 0x06 Interrupt Status Register       */
139 +       u8      imr;            /* 0x07 Interrupt Mask Register         */
140 +} __attribute__ ((packed));
141 +
142 +struct tmio_nand {
143 +       struct mtd_info                 mtd;
144 +       struct nand_chip                chip;
145 +
146 +       struct platform_device          *dev;
147 +
148 +       struct tmio_nfhccr __iomem      *ccr;
149 +       struct tmio_nfcr __iomem        *fcr;
150 +
151 +       unsigned int                    irq;
152 +
153 +       /* for tmio_nand_read_byte */
154 +       u8                              read;
155 +       unsigned                        read_good:1;
156 +};
157 +
158 +#define mtd_to_tmio(m)                 container_of(m, struct tmio_nand, mtd)
159 +
160 +#ifdef CONFIG_MTD_CMDLINE_PARTS
161 +static const char *part_probes[] = { "cmdlinepart", NULL };
162 +#endif
163 +
164 +/*--------------------------------------------------------------------------*/
165 +
166 +static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
167 +                                  unsigned int ctrl)
168 +{
169 +       struct tmio_nand *tmio = mtd_to_tmio(mtd);
170 +       struct tmio_nfcr __iomem *fcr = tmio->fcr;
171 +       struct nand_chip *chip = mtd->priv;
172 +
173 +       if (ctrl & NAND_CTRL_CHANGE) {
174 +               u8 mode;
175 +
176 +               if (ctrl & NAND_NCE) {
177 +                       mode = FCR_MODE_DATA;
178 +
179 +                       if (ctrl & NAND_CLE)
180 +                               mode |=  FCR_MODE_CLE;
181 +                       else
182 +                               mode &= ~FCR_MODE_CLE;
183 +
184 +                       if (ctrl & NAND_ALE)
185 +                               mode |=  FCR_MODE_ALE;
186 +                       else
187 +                               mode &= ~FCR_MODE_ALE;
188 +               } else {
189 +                       mode = FCR_MODE_STANDBY;
190 +               }
191 +
192 +               iowrite8(mode, &fcr->mode);
193 +               tmio->read_good = 0;
194 +       }
195 +
196 +       if (cmd != NAND_CMD_NONE)
197 +               writeb(cmd, chip->IO_ADDR_W);
198 +}
199 +
200 +static int tmio_nand_dev_ready(struct mtd_info *mtd)
201 +{
202 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
203 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
204 +
205 +       return !(ioread8(&fcr->status) & FCR_STATUS_BUSY);
206 +}
207 +
208 +static irqreturn_t tmio_irq(int irq, void *__dev)
209 +{
210 +       struct platform_device          *dev    = __dev;
211 +       struct tmio_nand                *tmio   = platform_get_drvdata(dev);
212 +       struct nand_chip                *nand_chip      = &tmio->chip;
213 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
214 +
215 +       /* disable RDYREQ interrupt */
216 +       iowrite8(0x00,  &fcr->imr);
217 +
218 +       if (unlikely(!waitqueue_active(&nand_chip->controller->wq)))
219 +               dev_warn(&dev->dev, "spurious interrupt\n");
220 +
221 +       wake_up(&nand_chip->controller->wq);
222 +       return IRQ_HANDLED;
223 +}
224 +
225 +/*
226 +  *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
227 +  *This interrupt is normally disabled, but for long operations like
228 +  *erase and write, we enable it to wake us up.  The irq handler
229 +  *disables the interrupt.
230 + */
231 +static int
232 +tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
233 +{
234 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
235 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
236 +       long                            timeout;
237 +
238 +       /* enable RDYREQ interrupt */
239 +       iowrite8(0x0f,  &fcr->isr);
240 +       iowrite8(0x81,  &fcr->imr);
241 +
242 +       timeout = wait_event_timeout(nand_chip->controller->wq, tmio_nand_dev_ready(mtd),
243 +                       msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));
244 +
245 +       if (unlikely(!tmio_nand_dev_ready(mtd))) {
246 +               iowrite8(0x00,  &fcr->imr);
247 +               dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
248 +                               nand_chip->state == FL_ERASING ? "erase" : "program",
249 +                               nand_chip->state == FL_ERASING ? 400 : 20);
250 +
251 +       } else if (unlikely(!timeout)) {
252 +               iowrite8(0x00,  &fcr->imr);
253 +               dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
254 +       }
255 +
256 +       nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
257 +       return nand_chip->read_byte(mtd);
258 +}
259 +
260 +/*
261 +  *The TMIO controller combines two 8-bit data bytes into one 16-bit
262 +  *word. This function separates them so nand_base.c works as expected,
263 +  *especially its NAND_CMD_READID routines.
264 + *
265 +  *To prevent stale data from being read, tmio_nand_hwcontrol() clears
266 +  *tmio->read_good.
267 + */
268 +static u_char tmio_nand_read_byte(struct mtd_info *mtd)
269 +{
270 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
271 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
272 +       unsigned int                    data;
273 +
274 +       if (tmio->read_good--)
275 +               return tmio->read;
276 +
277 +       data            = ioread16(&fcr->u16);
278 +       tmio->read      = data >> 8;
279 +       return data;
280 +}
281 +
282 +/*
283 +  *The TMIO controller converts an 8-bit NAND interface to a 16-bit
284 +  *bus interface, so all data reads and writes must be 16-bit wide.
285 +  *Thus, we implement 16-bit versions of the read, write, and verify
286 +  *buffer functions.
287 + */
288 +static void
289 +tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
290 +{
291 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
292 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
293 +
294 +       iowrite16_rep(&fcr->u16, buf, len >> 1);
295 +}
296 +
297 +static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
298 +{
299 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
300 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
301 +
302 +       ioread16_rep(&fcr->u16, buf, len >> 1);
303 +}
304 +
305 +static int
306 +tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
307 +{
308 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
309 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
310 +       u16                             *p      = (u16 *) buf;
311 +
312 +       for (len >>= 1; len; len--)
313 +               if (*(p++) != ioread16(&fcr->u16))
314 +                       return -EFAULT;
315 +       return 0;
316 +}
317 +
318 +static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
319 +{
320 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
321 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
322 +
323 +       iowrite8(FCR_MODE_HWECC_RESET, &fcr->mode);
324 +       ioread8(&fcr->u8);      /* dummy read */
325 +       iowrite8(FCR_MODE_HWECC_CALC, &fcr->mode);
326 +}
327 +
328 +static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
329 +                                                       u_char *ecc_code)
330 +{
331 +       struct tmio_nand                *tmio   = mtd_to_tmio(mtd);
332 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
333 +       unsigned int                    ecc;
334 +
335 +       iowrite8(FCR_MODE_HWECC_RESULT, &fcr->mode);
336 +
337 +       ecc = ioread16(&fcr->u16);
338 +       ecc_code[1] = ecc;      /* 000-255 LP7-0 */
339 +       ecc_code[0] = ecc >> 8; /* 000-255 LP15-8 */
340 +       ecc = ioread16(&fcr->u16);
341 +       ecc_code[2] = ecc;      /* 000-255 CP5-0,11b */
342 +       ecc_code[4] = ecc >> 8; /* 256-511 LP7-0 */
343 +       ecc = ioread16(&fcr->u16);
344 +       ecc_code[3] = ecc;      /* 256-511 LP15-8 */
345 +       ecc_code[5] = ecc >> 8; /* 256-511 CP5-0,11b */
346 +
347 +       iowrite8(FCR_MODE_DATA, &fcr->mode);
348 +       return 0;
349 +}
350 +
351 +static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
352 +{
353 +       struct mfd_cell                 *cell   = mfd_get_cell(dev);
354 +       const struct resource           *nfcr   = NULL;
355 +       struct tmio_nfhccr __iomem      *ccr    = tmio->ccr;
356 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
357 +       unsigned long                   base;
358 +       int                             i;
359 +
360 +       for (i = 0; i < cell->num_resources; i++)
361 +               if (!strcmp((cell->resources+i)->name, TMIO_NAND_CONTROL))
362 +                       nfcr = &cell->resources[i];
363 +
364 +       if (nfcr == NULL)
365 +               return -ENOMEM;
366 +
367 +       if (!cell->enable) {
368 +               printk(KERN_ERR "null cell enable!");
369 +               return -EINVAL;
370 +       }
371 +
372 +       cell->enable(dev);
373 +
374 +       /* (4Ch) CLKRUN Enable    1st spcrunc */
375 +       iowrite8(0x81,                  &ccr->icc);
376 +
377 +       /* (10h)BaseAddress    0x1000 spba.spba2 */
378 +       base = nfcr->start;
379 +       iowrite16(base,                 ccr->base + 0);
380 +       iowrite16(base >> 16,           ccr->base + 1);
381 +
382 +       /* (04h)Command Register I/O spcmd */
383 +       iowrite8(0x02,                  &ccr->command);
384 +
385 +       /* (62h) Power Supply Control ssmpwc */
386 +       /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
387 +       iowrite8(0x02,                  &ccr->nfpsc);
388 +
389 +       /* (63h) Detect Control ssmdtc */
390 +       iowrite8(0x02,                  &ccr->nfdc);
391 +
392 +       /* Interrupt status register clear sintst */
393 +       iowrite8(0x0f,                  &fcr->isr);
394 +
395 +       /* After power supply, Media are reset smode */
396 +       iowrite8(FCR_MODE_POWER_ON,     &fcr->mode);
397 +       iowrite8(FCR_MODE_COMMAND,      &fcr->mode);
398 +       iowrite8(NAND_CMD_RESET,        &fcr->u8);
399 +
400 +       /* Standby Mode smode */
401 +       iowrite8(FCR_MODE_STANDBY,      &fcr->mode);
402 +
403 +       mdelay(5);
404 +
405 +       return 0;
406 +}
407 +
408 +static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
409 +{
410 +       struct mfd_cell                 *cell   = mfd_get_cell(dev);
411 +       struct tmio_nfcr __iomem        *fcr    = tmio->fcr;
412 +
413 +       iowrite8(FCR_MODE_POWER_OFF,    &fcr->mode);
414 +       cell->disable(dev);
415 +}
416 +
417 +static int tmio_probe(struct platform_device *dev)
418 +{
419 +       struct mfd_cell                 *cell   = mfd_get_cell(dev);
420 +       struct tmio_nand_data           *data   = cell->driver_data;
421 +       struct resource                 *ccr    = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONFIG);
422 +       struct resource                 *fcr    = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONTROL);
423 +       int                             irq     = platform_get_irq(dev, 0);
424 +       struct tmio_nand                *tmio;
425 +       struct mtd_info                 *mtd;
426 +       struct nand_chip                *nand_chip;
427 +       struct mtd_partition            *parts;
428 +       int                             nbparts = 0;
429 +       int                             retval;
430 +
431 +       if (data == NULL) {
432 +               dev_err(&dev->dev, "NULL platform data!\n");
433 +               return -EINVAL;
434 +       }
435 +
436 +       tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
437 +       if (!tmio) {
438 +               retval = -ENOMEM;
439 +               goto err_kzalloc;
440 +       }
441 +
442 +       tmio->dev       = dev;
443 +
444 +       platform_set_drvdata(dev, tmio);
445 +       mtd             = &tmio->mtd;
446 +       nand_chip       = &tmio->chip;
447 +       mtd->priv       = nand_chip;
448 +       mtd->name       = "tmio-nand";
449 +
450 +       tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
451 +       if (!tmio->ccr) {
452 +               retval = -EIO;
453 +               goto err_iomap_ccr;
454 +       }
455 +
456 +       tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
457 +       if (!tmio->fcr) {
458 +               retval = -EIO;
459 +               goto err_iomap_fcr;
460 +       }
461 +
462 +       retval = tmio_hw_init(dev, tmio);
463 +       if (retval)
464 +               goto err_hwinit;
465 +
466 +       /* Set address of NAND IO lines */
467 +       nand_chip->IO_ADDR_R            = tmio->fcr;
468 +       nand_chip->IO_ADDR_W            = tmio->fcr;
469 +
470 +       /* Set address of hardware control function */
471 +       nand_chip->cmd_ctrl             = tmio_nand_hwcontrol;
472 +       nand_chip->dev_ready            = tmio_nand_dev_ready;
473 +       nand_chip->read_byte            = tmio_nand_read_byte;
474 +       nand_chip->write_buf            = tmio_nand_write_buf;
475 +       nand_chip->read_buf             = tmio_nand_read_buf;
476 +       nand_chip->verify_buf           = tmio_nand_verify_buf;
477 +
478 +       /* set eccmode using hardware ECC */
479 +       nand_chip->ecc.mode             = NAND_ECC_HW;
480 +       nand_chip->ecc.size             = 512;
481 +       nand_chip->ecc.bytes            = 6;
482 +       nand_chip->ecc.hwctl            = tmio_nand_enable_hwecc;
483 +       nand_chip->ecc.calculate        = tmio_nand_calculate_ecc;
484 +       nand_chip->ecc.correct          = nand_correct_data;
485 +       nand_chip->badblock_pattern     = data->badblock_pattern;
486 +
487 +       /* 15 us command delay time */
488 +       nand_chip->chip_delay   = 15;
489 +
490 +       retval = request_irq(irq, &tmio_irq,
491 +                               IRQF_DISABLED, dev->dev.bus_id, dev);
492 +       if (retval) {
493 +               dev_err(&dev->dev, "request_irq error %d\n", retval);
494 +               goto err_irq;
495 +       }
496 +
497 +       tmio->irq               = irq;
498 +       nand_chip->waitfunc     = tmio_nand_wait;
499 +
500 +       /* Scan to find existence of the device */
501 +       if (nand_scan(mtd, 1)) {
502 +               retval = -ENODEV;
503 +               goto err_scan;
504 +       }
505 +       /* Register the partitions */
506 +#ifdef CONFIG_MTD_PARTITIONS
507 +#ifdef CONFIG_MTD_CMDLINE_PARTS
508 +       nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
509 +#endif
510 +       if (nbparts <= 0) {
511 +               parts   = data->partition;
512 +               nbparts = data->num_partitions;
513 +       }
514 +
515 +       retval = add_mtd_partitions(mtd, parts, nbparts);
516 +#else
517 +       retval = add_mtd_device(mtd);
518 +#endif
519 +
520 +       if (!retval)
521 +               return retval;
522 +
523 +       nand_release(mtd);
524 +
525 +err_scan:
526 +       if (tmio->irq)
527 +               free_irq(tmio->irq, dev);
528 +err_irq:
529 +       tmio_hw_stop(dev, tmio);
530 +err_hwinit:
531 +       iounmap(tmio->fcr);
532 +err_iomap_fcr:
533 +       iounmap(tmio->ccr);
534 +err_iomap_ccr:
535 +       kfree(tmio);
536 +err_kzalloc:
537 +       return retval;
538 +}
539 +
540 +static int tmio_remove(struct platform_device *dev)
541 +{
542 +       struct tmio_nand                *tmio   = platform_get_drvdata(dev);
543 +
544 +       nand_release(&tmio->mtd);
545 +       if (tmio->irq)
546 +               free_irq(tmio->irq, tmio);
547 +       tmio_hw_stop(dev, tmio);
548 +       iounmap(tmio->fcr);
549 +       iounmap(tmio->ccr);
550 +       kfree(tmio);
551 +       return 0;
552 +}
553 +
554 +#ifdef CONFIG_PM
555 +static int tmio_suspend(struct platform_device *dev, pm_message_t state)
556 +{
557 +       struct mfd_cell                 *cell   = mfd_get_cell(dev);
558 +
559 +       if (cell->suspend)
560 +               cell->suspend(dev);
561 +
562 +       tmio_hw_stop(dev, platform_get_drvdata(dev));
563 +       return 0;
564 +}
565 +
566 +static int tmio_resume(struct platform_device *dev)
567 +{
568 +       struct mfd_cell                 *cell   = mfd_get_cell(dev);
569 +
570 +       tmio_hw_init(dev, platform_get_drvdata(dev));
571 +
572 +       if (cell->resume)
573 +               cell->resume(dev);
574 +
575 +       return 0;
576 +}
577 +#endif
578 +
579 +static struct platform_driver tmio_driver = {
580 +       .driver.name    = "tmio-nand",
581 +       .driver.owner   = THIS_MODULE,
582 +       .probe          = tmio_probe,
583 +       .remove         = tmio_remove,
584 +#ifdef CONFIG_PM
585 +       .suspend        = tmio_suspend,
586 +       .resume         = tmio_resume,
587 +#endif
588 +};
589 +
590 +static int __init tmio_init(void)
591 +{
592 +       return platform_driver_register(&tmio_driver);
593 +}
594 +
595 +static void __exit tmio_exit(void)
596 +{
597 +       platform_driver_unregister(&tmio_driver);
598 +}
599 +
600 +module_init(tmio_init);
601 +module_exit(tmio_exit);
602 +
603 +MODULE_LICENSE("GPL");
604 +MODULE_AUTHOR("Dirk Opfer, Chris Humbert, Dmitry Baryshkov");
605 +MODULE_DESCRIPTION("NAND flash driver on Toshiba Mobile IO controller");
606 -- 
607 1.5.3.8
608