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