bf5xx_nand.c revision b37bde147890c8fea8369a5a4e230dabdea4ebfb
1/* linux/drivers/mtd/nand/bf5xx_nand.c
2 *
3 * Copyright 2006-2007 Analog Devices Inc.
4 *	http://blackfin.uclinux.org/
5 *	Bryan Wu <bryan.wu@analog.com>
6 *
7 * Blackfin BF5xx on-chip NAND flash controler driver
8 *
9 * Derived from drivers/mtd/nand/s3c2410.c
10 * Copyright (c) 2007 Ben Dooks <ben@simtec.co.uk>
11 *
12 * Derived from drivers/mtd/nand/cafe.c
13 * Copyright © 2006 Red Hat, Inc.
14 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
15 *
16 * Changelog:
17 *	12-Jun-2007  Bryan Wu:  Initial version
18 *	18-Jul-2007  Bryan Wu:
19 *		- ECC_HW and ECC_SW supported
20 *		- DMA supported in ECC_HW
21 *		- YAFFS tested as rootfs in both ECC_HW and ECC_SW
22 *
23 * TODO:
24 * 	Enable JFFS2 over NAND as rootfs
25 *
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
30 *
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34 * GNU General Public License for more details.
35 *
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
39*/
40
41#include <linux/module.h>
42#include <linux/types.h>
43#include <linux/init.h>
44#include <linux/kernel.h>
45#include <linux/string.h>
46#include <linux/ioport.h>
47#include <linux/platform_device.h>
48#include <linux/delay.h>
49#include <linux/dma-mapping.h>
50#include <linux/err.h>
51#include <linux/slab.h>
52#include <linux/io.h>
53#include <linux/bitops.h>
54
55#include <linux/mtd/mtd.h>
56#include <linux/mtd/nand.h>
57#include <linux/mtd/nand_ecc.h>
58#include <linux/mtd/partitions.h>
59
60#include <asm/blackfin.h>
61#include <asm/dma.h>
62#include <asm/cacheflush.h>
63#include <asm/nand.h>
64#include <asm/portmux.h>
65
66#define DRV_NAME	"bf5xx-nand"
67#define DRV_VERSION	"1.2"
68#define DRV_AUTHOR	"Bryan Wu <bryan.wu@analog.com>"
69#define DRV_DESC	"BF5xx on-chip NAND FLash Controller Driver"
70
71#ifdef CONFIG_MTD_NAND_BF5XX_HWECC
72static int hardware_ecc = 1;
73#else
74static int hardware_ecc;
75#endif
76
77static unsigned short bfin_nfc_pin_req[] = {P_NAND_CE, P_NAND_RB, 0};
78
79/*
80 * Data structures for bf5xx nand flash controller driver
81 */
82
83/* bf5xx nand info */
84struct bf5xx_nand_info {
85	/* mtd info */
86	struct nand_hw_control		controller;
87	struct mtd_info			mtd;
88	struct nand_chip		chip;
89
90	/* platform info */
91	struct bf5xx_nand_platform	*platform;
92
93	/* device info */
94	struct device			*device;
95
96	/* DMA stuff */
97	struct completion		dma_completion;
98};
99
100/*
101 * Conversion functions
102 */
103static struct bf5xx_nand_info *mtd_to_nand_info(struct mtd_info *mtd)
104{
105	return container_of(mtd, struct bf5xx_nand_info, mtd);
106}
107
108static struct bf5xx_nand_info *to_nand_info(struct platform_device *pdev)
109{
110	return platform_get_drvdata(pdev);
111}
112
113static struct bf5xx_nand_platform *to_nand_plat(struct platform_device *pdev)
114{
115	return pdev->dev.platform_data;
116}
117
118/*
119 * struct nand_chip interface function pointers
120 */
121
122/*
123 * bf5xx_nand_hwcontrol
124 *
125 * Issue command and address cycles to the chip
126 */
127static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
128				   unsigned int ctrl)
129{
130	if (cmd == NAND_CMD_NONE)
131		return;
132
133	while (bfin_read_NFC_STAT() & WB_FULL)
134		cpu_relax();
135
136	if (ctrl & NAND_CLE)
137		bfin_write_NFC_CMD(cmd);
138	else
139		bfin_write_NFC_ADDR(cmd);
140	SSYNC();
141}
142
143/*
144 * bf5xx_nand_devready()
145 *
146 * returns 0 if the nand is busy, 1 if it is ready
147 */
148static int bf5xx_nand_devready(struct mtd_info *mtd)
149{
150	unsigned short val = bfin_read_NFC_IRQSTAT();
151
152	if ((val & NBUSYIRQ) == NBUSYIRQ)
153		return 1;
154	else
155		return 0;
156}
157
158/*
159 * ECC functions
160 * These allow the bf5xx to use the controller's ECC
161 * generator block to ECC the data as it passes through
162 */
163
164/*
165 * ECC error correction function
166 */
167static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
168					u_char *read_ecc, u_char *calc_ecc)
169{
170	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
171	u32 syndrome[5];
172	u32 calced, stored;
173	int i;
174	unsigned short failing_bit, failing_byte;
175	u_char data;
176
177	calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16);
178	stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16);
179
180	syndrome[0] = (calced ^ stored);
181
182	/*
183	 * syndrome 0: all zero
184	 * No error in data
185	 * No action
186	 */
187	if (!syndrome[0] || !calced || !stored)
188		return 0;
189
190	/*
191	 * sysdrome 0: only one bit is one
192	 * ECC data was incorrect
193	 * No action
194	 */
195	if (hweight32(syndrome[0]) == 1) {
196		dev_err(info->device, "ECC data was incorrect!\n");
197		return 1;
198	}
199
200	syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
201	syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF);
202	syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF);
203	syndrome[4] = syndrome[2] ^ syndrome[3];
204
205	for (i = 0; i < 5; i++)
206		dev_info(info->device, "syndrome[%d] 0x%08x\n", i, syndrome[i]);
207
208	dev_info(info->device,
209		"calced[0x%08x], stored[0x%08x]\n",
210		calced, stored);
211
212	/*
213	 * sysdrome 0: exactly 11 bits are one, each parity
214	 * and parity' pair is 1 & 0 or 0 & 1.
215	 * 1-bit correctable error
216	 * Correct the error
217	 */
218	if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) {
219		dev_info(info->device,
220			"1-bit correctable error, correct it.\n");
221		dev_info(info->device,
222			"syndrome[1] 0x%08x\n", syndrome[1]);
223
224		failing_bit = syndrome[1] & 0x7;
225		failing_byte = syndrome[1] >> 0x3;
226		data = *(dat + failing_byte);
227		data = data ^ (0x1 << failing_bit);
228		*(dat + failing_byte) = data;
229
230		return 0;
231	}
232
233	/*
234	 * sysdrome 0: random data
235	 * More than 1-bit error, non-correctable error
236	 * Discard data, mark bad block
237	 */
238	dev_err(info->device,
239		"More than 1-bit error, non-correctable error.\n");
240	dev_err(info->device,
241		"Please discard data, mark bad block\n");
242
243	return 1;
244}
245
246static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
247					u_char *read_ecc, u_char *calc_ecc)
248{
249	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
250	struct bf5xx_nand_platform *plat = info->platform;
251	unsigned short page_size = (plat->page_size ? 512 : 256);
252	int ret;
253
254	ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
255
256	/* If page size is 512, correct second 256 bytes */
257	if (page_size == 512) {
258		dat += 256;
259		read_ecc += 8;
260		calc_ecc += 8;
261		ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
262	}
263
264	return ret;
265}
266
267static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode)
268{
269	return;
270}
271
272static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
273		const u_char *dat, u_char *ecc_code)
274{
275	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
276	struct bf5xx_nand_platform *plat = info->platform;
277	u16 page_size = (plat->page_size ? 512 : 256);
278	u16 ecc0, ecc1;
279	u32 code[2];
280	u8 *p;
281	int bytes = 3, i;
282
283	/* first 4 bytes ECC code for 256 page size */
284	ecc0 = bfin_read_NFC_ECC0();
285	ecc1 = bfin_read_NFC_ECC1();
286
287	code[0] = (ecc0 & 0x3FF) | ((ecc1 & 0x3FF) << 11);
288
289	dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);
290
291	/* second 4 bytes ECC code for 512 page size */
292	if (page_size == 512) {
293		ecc0 = bfin_read_NFC_ECC2();
294		ecc1 = bfin_read_NFC_ECC3();
295		code[1] = (ecc0 & 0x3FF) | ((ecc1 & 0x3FF) << 11);
296		bytes = 6;
297		dev_dbg(info->device, "returning ecc 0x%08x\n", code[1]);
298	}
299
300	p = (u8 *)code;
301	for (i = 0; i < bytes; i++)
302		ecc_code[i] = p[i];
303
304	return 0;
305}
306
307/*
308 * PIO mode for buffer writing and reading
309 */
310static void bf5xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
311{
312	int i;
313	unsigned short val;
314
315	/*
316	 * Data reads are requested by first writing to NFC_DATA_RD
317	 * and then reading back from NFC_READ.
318	 */
319	for (i = 0; i < len; i++) {
320		while (bfin_read_NFC_STAT() & WB_FULL)
321			cpu_relax();
322
323		/* Contents do not matter */
324		bfin_write_NFC_DATA_RD(0x0000);
325		SSYNC();
326
327		while ((bfin_read_NFC_IRQSTAT() & RD_RDY) != RD_RDY)
328			cpu_relax();
329
330		buf[i] = bfin_read_NFC_READ();
331
332		val = bfin_read_NFC_IRQSTAT();
333		val |= RD_RDY;
334		bfin_write_NFC_IRQSTAT(val);
335		SSYNC();
336	}
337}
338
339static uint8_t bf5xx_nand_read_byte(struct mtd_info *mtd)
340{
341	uint8_t val;
342
343	bf5xx_nand_read_buf(mtd, &val, 1);
344
345	return val;
346}
347
348static void bf5xx_nand_write_buf(struct mtd_info *mtd,
349				const uint8_t *buf, int len)
350{
351	int i;
352
353	for (i = 0; i < len; i++) {
354		while (bfin_read_NFC_STAT() & WB_FULL)
355			cpu_relax();
356
357		bfin_write_NFC_DATA_WR(buf[i]);
358		SSYNC();
359	}
360}
361
362static void bf5xx_nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
363{
364	int i;
365	u16 *p = (u16 *) buf;
366	len >>= 1;
367
368	/*
369	 * Data reads are requested by first writing to NFC_DATA_RD
370	 * and then reading back from NFC_READ.
371	 */
372	bfin_write_NFC_DATA_RD(0x5555);
373
374	SSYNC();
375
376	for (i = 0; i < len; i++)
377		p[i] = bfin_read_NFC_READ();
378}
379
380static void bf5xx_nand_write_buf16(struct mtd_info *mtd,
381				const uint8_t *buf, int len)
382{
383	int i;
384	u16 *p = (u16 *) buf;
385	len >>= 1;
386
387	for (i = 0; i < len; i++)
388		bfin_write_NFC_DATA_WR(p[i]);
389
390	SSYNC();
391}
392
393/*
394 * DMA functions for buffer writing and reading
395 */
396static irqreturn_t bf5xx_nand_dma_irq(int irq, void *dev_id)
397{
398	struct bf5xx_nand_info *info = dev_id;
399
400	clear_dma_irqstat(CH_NFC);
401	disable_dma(CH_NFC);
402	complete(&info->dma_completion);
403
404	return IRQ_HANDLED;
405}
406
407static int bf5xx_nand_dma_rw(struct mtd_info *mtd,
408				uint8_t *buf, int is_read)
409{
410	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
411	struct bf5xx_nand_platform *plat = info->platform;
412	unsigned short page_size = (plat->page_size ? 512 : 256);
413	unsigned short val;
414
415	dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
416			mtd, buf, is_read);
417
418	/*
419	 * Before starting a dma transfer, be sure to invalidate/flush
420	 * the cache over the address range of your DMA buffer to
421	 * prevent cache coherency problems. Otherwise very subtle bugs
422	 * can be introduced to your driver.
423	 */
424	if (is_read)
425		invalidate_dcache_range((unsigned int)buf,
426				(unsigned int)(buf + page_size));
427	else
428		flush_dcache_range((unsigned int)buf,
429				(unsigned int)(buf + page_size));
430
431	/*
432	 * This register must be written before each page is
433	 * transferred to generate the correct ECC register
434	 * values.
435	 */
436	bfin_write_NFC_RST(0x1);
437	SSYNC();
438
439	disable_dma(CH_NFC);
440	clear_dma_irqstat(CH_NFC);
441
442	/* setup DMA register with Blackfin DMA API */
443	set_dma_config(CH_NFC, 0x0);
444	set_dma_start_addr(CH_NFC, (unsigned long) buf);
445	set_dma_x_count(CH_NFC, (page_size >> 2));
446	set_dma_x_modify(CH_NFC, 4);
447
448	/* setup write or read operation */
449	val = DI_EN | WDSIZE_32;
450	if (is_read)
451		val |= WNR;
452	set_dma_config(CH_NFC, val);
453	enable_dma(CH_NFC);
454
455	/* Start PAGE read/write operation */
456	if (is_read)
457		bfin_write_NFC_PGCTL(0x1);
458	else
459		bfin_write_NFC_PGCTL(0x2);
460	wait_for_completion(&info->dma_completion);
461
462	return 0;
463}
464
465static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
466					uint8_t *buf, int len)
467{
468	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
469	struct bf5xx_nand_platform *plat = info->platform;
470	unsigned short page_size = (plat->page_size ? 512 : 256);
471
472	dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len);
473
474	if (len == page_size)
475		bf5xx_nand_dma_rw(mtd, buf, 1);
476	else
477		bf5xx_nand_read_buf(mtd, buf, len);
478}
479
480static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
481				const uint8_t *buf, int len)
482{
483	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
484	struct bf5xx_nand_platform *plat = info->platform;
485	unsigned short page_size = (plat->page_size ? 512 : 256);
486
487	dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);
488
489	if (len == page_size)
490		bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
491	else
492		bf5xx_nand_write_buf(mtd, buf, len);
493}
494
495/*
496 * System initialization functions
497 */
498
499static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
500{
501	int ret;
502	unsigned short val;
503
504	/* Do not use dma */
505	if (!hardware_ecc)
506		return 0;
507
508	init_completion(&info->dma_completion);
509
510	/* Setup DMAC1 channel mux for NFC which shared with SDH */
511	val = bfin_read_DMAC1_PERIMUX();
512	val &= 0xFFFE;
513	bfin_write_DMAC1_PERIMUX(val);
514	SSYNC();
515
516	/* Request NFC DMA channel */
517	ret = request_dma(CH_NFC, "BF5XX NFC driver");
518	if (ret < 0) {
519		dev_err(info->device, " unable to get DMA channel\n");
520		return ret;
521	}
522
523	set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info);
524
525	/* Turn off the DMA channel first */
526	disable_dma(CH_NFC);
527	return 0;
528}
529
530/*
531 * BF5XX NFC hardware initialization
532 *  - pin mux setup
533 *  - clear interrupt status
534 */
535static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
536{
537	int err = 0;
538	unsigned short val;
539	struct bf5xx_nand_platform *plat = info->platform;
540
541	/* setup NFC_CTL register */
542	dev_info(info->device,
543		"page_size=%d, data_width=%d, wr_dly=%d, rd_dly=%d\n",
544		(plat->page_size ? 512 : 256),
545		(plat->data_width ? 16 : 8),
546		plat->wr_dly, plat->rd_dly);
547
548	val = (plat->page_size << NFC_PG_SIZE_OFFSET) |
549		(plat->data_width << NFC_NWIDTH_OFFSET) |
550		(plat->rd_dly << NFC_RDDLY_OFFSET) |
551		(plat->rd_dly << NFC_WRDLY_OFFSET);
552	dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val);
553
554	bfin_write_NFC_CTL(val);
555	SSYNC();
556
557	/* clear interrupt status */
558	bfin_write_NFC_IRQMASK(0x0);
559	SSYNC();
560	val = bfin_read_NFC_IRQSTAT();
561	bfin_write_NFC_IRQSTAT(val);
562	SSYNC();
563
564	if (peripheral_request_list(bfin_nfc_pin_req, DRV_NAME)) {
565		printk(KERN_ERR DRV_NAME
566		": Requesting Peripherals failed\n");
567		return -EFAULT;
568	}
569
570	/* DMA initialization  */
571	if (bf5xx_nand_dma_init(info))
572		err = -ENXIO;
573
574	return err;
575}
576
577/*
578 * Device management interface
579 */
580static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
581{
582	struct mtd_info *mtd = &info->mtd;
583
584#ifdef CONFIG_MTD_PARTITIONS
585	struct mtd_partition *parts = info->platform->partitions;
586	int nr = info->platform->nr_partitions;
587
588	return add_mtd_partitions(mtd, parts, nr);
589#else
590	return add_mtd_device(mtd);
591#endif
592}
593
594static int bf5xx_nand_remove(struct platform_device *pdev)
595{
596	struct bf5xx_nand_info *info = to_nand_info(pdev);
597	struct mtd_info *mtd = NULL;
598
599	platform_set_drvdata(pdev, NULL);
600
601	/* first thing we need to do is release all our mtds
602	 * and their partitions, then go through freeing the
603	 * resources used
604	 */
605	mtd = &info->mtd;
606	if (mtd) {
607		nand_release(mtd);
608		kfree(mtd);
609	}
610
611	peripheral_free_list(bfin_nfc_pin_req);
612
613	/* free the common resources */
614	kfree(info);
615
616	return 0;
617}
618
619/*
620 * bf5xx_nand_probe
621 *
622 * called by device layer when it finds a device matching
623 * one our driver can handled. This code checks to see if
624 * it can allocate all necessary resources then calls the
625 * nand layer to look for devices
626 */
627static int bf5xx_nand_probe(struct platform_device *pdev)
628{
629	struct bf5xx_nand_platform *plat = to_nand_plat(pdev);
630	struct bf5xx_nand_info *info = NULL;
631	struct nand_chip *chip = NULL;
632	struct mtd_info *mtd = NULL;
633	int err = 0;
634
635	dev_dbg(&pdev->dev, "(%p)\n", pdev);
636
637	if (!plat) {
638		dev_err(&pdev->dev, "no platform specific information\n");
639		goto exit_error;
640	}
641
642	info = kzalloc(sizeof(*info), GFP_KERNEL);
643	if (info == NULL) {
644		dev_err(&pdev->dev, "no memory for flash info\n");
645		err = -ENOMEM;
646		goto exit_error;
647	}
648
649	platform_set_drvdata(pdev, info);
650
651	spin_lock_init(&info->controller.lock);
652	init_waitqueue_head(&info->controller.wq);
653
654	info->device     = &pdev->dev;
655	info->platform   = plat;
656
657	/* initialise chip data struct */
658	chip = &info->chip;
659
660	if (plat->data_width)
661		chip->options |= NAND_BUSWIDTH_16;
662
663	chip->options |= NAND_CACHEPRG | NAND_SKIP_BBTSCAN;
664
665	chip->read_buf = (plat->data_width) ?
666		bf5xx_nand_read_buf16 : bf5xx_nand_read_buf;
667	chip->write_buf = (plat->data_width) ?
668		bf5xx_nand_write_buf16 : bf5xx_nand_write_buf;
669
670	chip->read_byte    = bf5xx_nand_read_byte;
671
672	chip->cmd_ctrl     = bf5xx_nand_hwcontrol;
673	chip->dev_ready    = bf5xx_nand_devready;
674
675	chip->priv	   = &info->mtd;
676	chip->controller   = &info->controller;
677
678	chip->IO_ADDR_R    = (void __iomem *) NFC_READ;
679	chip->IO_ADDR_W    = (void __iomem *) NFC_DATA_WR;
680
681	chip->chip_delay   = 0;
682
683	/* initialise mtd info data struct */
684	mtd 		= &info->mtd;
685	mtd->priv	= chip;
686	mtd->owner	= THIS_MODULE;
687
688	/* initialise the hardware */
689	err = bf5xx_nand_hw_init(info);
690	if (err != 0)
691		goto exit_error;
692
693	/* setup hardware ECC data struct */
694	if (hardware_ecc) {
695		if (plat->page_size == NFC_PG_SIZE_256) {
696			chip->ecc.bytes = 3;
697			chip->ecc.size = 256;
698		} else if (plat->page_size == NFC_PG_SIZE_512) {
699			chip->ecc.bytes = 6;
700			chip->ecc.size = 512;
701		}
702
703		chip->read_buf      = bf5xx_nand_dma_read_buf;
704		chip->write_buf     = bf5xx_nand_dma_write_buf;
705		chip->ecc.calculate = bf5xx_nand_calculate_ecc;
706		chip->ecc.correct   = bf5xx_nand_correct_data;
707		chip->ecc.mode	    = NAND_ECC_HW;
708		chip->ecc.hwctl	    = bf5xx_nand_enable_hwecc;
709	} else {
710		chip->ecc.mode	    = NAND_ECC_SOFT;
711	}
712
713	/* scan hardware nand chip and setup mtd info data struct */
714	if (nand_scan(mtd, 1)) {
715		err = -ENXIO;
716		goto exit_error;
717	}
718
719	/* add NAND partition */
720	bf5xx_nand_add_partition(info);
721
722	dev_dbg(&pdev->dev, "initialised ok\n");
723	return 0;
724
725exit_error:
726	bf5xx_nand_remove(pdev);
727
728	if (err == 0)
729		err = -EINVAL;
730	return err;
731}
732
733/* PM Support */
734#ifdef CONFIG_PM
735
736static int bf5xx_nand_suspend(struct platform_device *dev, pm_message_t pm)
737{
738	struct bf5xx_nand_info *info = platform_get_drvdata(dev);
739
740	return 0;
741}
742
743static int bf5xx_nand_resume(struct platform_device *dev)
744{
745	struct bf5xx_nand_info *info = platform_get_drvdata(dev);
746
747	if (info)
748		bf5xx_nand_hw_init(info);
749
750	return 0;
751}
752
753#else
754#define bf5xx_nand_suspend NULL
755#define bf5xx_nand_resume NULL
756#endif
757
758/* driver device registration */
759static struct platform_driver bf5xx_nand_driver = {
760	.probe		= bf5xx_nand_probe,
761	.remove		= bf5xx_nand_remove,
762	.suspend	= bf5xx_nand_suspend,
763	.resume		= bf5xx_nand_resume,
764	.driver		= {
765		.name	= DRV_NAME,
766		.owner	= THIS_MODULE,
767	},
768};
769
770static int __init bf5xx_nand_init(void)
771{
772	printk(KERN_INFO "%s, Version %s (c) 2007 Analog Devices, Inc.\n",
773		DRV_DESC, DRV_VERSION);
774
775	return platform_driver_register(&bf5xx_nand_driver);
776}
777
778static void __exit bf5xx_nand_exit(void)
779{
780	platform_driver_unregister(&bf5xx_nand_driver);
781}
782
783module_init(bf5xx_nand_init);
784module_exit(bf5xx_nand_exit);
785
786MODULE_LICENSE("GPL");
787MODULE_AUTHOR(DRV_AUTHOR);
788MODULE_DESCRIPTION(DRV_DESC);
789