2 * linux/drivers/mtd/rknand/rknand_base.c
\r
4 * Copyright (C) 2005-2009 Fuzhou Rockchip Electronics
\r
5 * ZYF <zyf@rock-chips.com>
\r
10 #include <linux/module.h>
\r
11 #include <linux/sched.h>
\r
12 #include <linux/delay.h>
\r
13 #include <linux/init.h>
\r
14 #include <linux/slab.h>
\r
15 #include <linux/platform_device.h>
\r
16 #include <linux/mtd/mtd.h>
\r
17 #include <linux/mtd/partitions.h>
\r
18 #include <linux/mutex.h>
\r
19 #include <linux/kthread.h>
\r
20 #include <linux/reboot.h>
\r
22 #include <asm/mach/flash.h>
\r
23 #include "api_flash.h"
\r
25 extern int rknand_queue_read(int Index, int nSec, void *buf);
\r
26 extern int rknand_queue_write(int Index, int nSec, void *buf,int mode);
\r
27 extern int rknand_buffer_init(void);
\r
28 extern void rknand_buffer_shutdown(void);
\r
29 extern void rknand_buffer_sync(void);
\r
31 #define DRIVER_NAME "rk29xxnand"
\r
32 const char rknand_base_version[] = "rknand_base.c version: 4.20 20110127";
\r
33 #define NAND_DEBUG_LEVEL0 0
\r
34 #define NAND_DEBUG_LEVEL1 1
\r
35 #define NAND_DEBUG_LEVEL2 2
\r
36 #define NAND_DEBUG_LEVEL3 3
\r
37 //#define PAGE_REMAP
\r
39 #ifndef CONFIG_RKFTL_PAGECACHE_SIZE
\r
40 #define CONFIG_RKFTL_PAGECACHE_SIZE 64 //¶¨ÒåpageÓ³ÉäÇø´óС£¬µ¥Î»ÎªMB,mount ÔÚ/data/dataÏ¡£
\r
43 unsigned long SysImageWriteEndAdd = 0;
\r
44 int g_num_partitions = 0;
\r
46 #ifdef CONFIG_MTD_NAND_RK29XX_DEBUG
\r
47 static int s_debug = CONFIG_MTD_NAND_RK29XX_DEBUG_VERBOSE;
\r
49 #define NAND_DEBUG(n, format, arg...) \
\r
50 if (n <= s_debug) { \
\r
51 printk(format,##arg); \
\r
55 #define NAND_DEBUG(n, arg...)
\r
56 static const int s_debug = 0;
\r
60 * RK28 LBA PARTITIONS,the size and offset value below is default value in this program,
\r
61 * when RK28 LBA FLASH init,the value will be modify to the value in the nand flash.
\r
63 static struct mtd_partition rk28_partition_info[] = {
\r
66 offset: 0x2000*0x200,
\r
67 size: 0x2000*0x200,//100MB
\r
72 offset: 0x4000*0x200,
\r
73 size: 0x4000*0x200,//200MB
\r
78 offset: 0x8000*0x200,
\r
79 size: 0x2000*0x200,//200MB
\r
84 offset: 0xE000*0x200,
\r
85 size: 0x38000*0x200,//200MB
\r
91 static struct mtd_partition rk28_page_part_info[] = {
\r
95 size: CONFIG_RKFTL_PAGECACHE_SIZE * 0x800*0x200,//32MB
\r
100 offset: (CONFIG_RKFTL_PAGECACHE_SIZE) * 0x800*0x200,
\r
101 size: 64 * 0x800*0x200,//64MB
\r
106 * onenand_state_t - chip states
\r
107 * Enumeration for OneNAND flash chip state
\r
118 struct rknand_chip {
\r
119 wait_queue_head_t wq;
\r
120 rknand_state_t state;
\r
121 int rknand_schedule_enable;//1 enable ,0 disable
\r
122 void (*pFlashCallBack)(void);//call back funtion
\r
125 struct rknand_info {
\r
126 struct mtd_info mtd;
\r
127 struct mtd_info page_mtd;
\r
128 struct mtd_partition *parts;
\r
129 struct rknand_chip rknand;
\r
130 struct task_struct *thread;
\r
133 struct rknand_info * gpNandInfo;
\r
135 #include <linux/proc_fs.h>
\r
136 #include <linux/version.h>
\r
137 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
\r
138 #define NANDPROC_ROOT (&proc_root)
\r
140 #define NANDPROC_ROOT NULL
\r
143 static struct proc_dir_entry *my_proc_entry;
\r
144 extern int rkNand_proc_ftlread(char *page);
\r
145 extern int rkNand_proc_bufread(char *page);
\r
146 static int rkNand_proc_read(char *page,
\r
148 off_t offset, int count, int *eof, void *data)
\r
155 buf += sprintf(buf, "%s\n", rknand_base_version);
\r
156 buf += rkNand_proc_ftlread(buf);
\r
157 #ifdef CONFIG_MTD_RKNAND_BUFFER
\r
158 buf += rkNand_proc_bufread(buf);
\r
161 return buf - page < count ? buf - page : count;
\r
164 static void rk28nand_create_procfs(void)
\r
166 /* Install the proc_fs entry */
\r
167 my_proc_entry = create_proc_entry("rk29xxnand",
\r
171 if (my_proc_entry) {
\r
172 my_proc_entry->write_proc = NULL;
\r
173 my_proc_entry->read_proc = rkNand_proc_read;
\r
174 my_proc_entry->data = NULL;
\r
178 void rkNand_cond_resched(void)
\r
180 if(gpNandInfo->rknand.rknand_schedule_enable == 1)
\r
188 #ifdef CONFIG_MTD_RKNAND_BUFFER
\r
189 static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len,
\r
190 size_t *retlen, u_char *buf)
\r
193 int sector = len>>9;
\r
194 int LBA = (int)(from>>9);
\r
195 //printk("rk28xxnand_read: from=%x,len=%x,\n",(int)from,len);
\r
198 ret = rknand_queue_read(LBA, sector, buf);
\r
204 static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len,
\r
205 size_t *retlen, const u_char *buf)
\r
208 int sector = len>>9;
\r
209 int LBA = (int)(from>>9);
\r
211 //printk(KERN_NOTICE "write: from=%lx,len=%x\n",(int)from,len);
\r
214 if(LBA < SysImageWriteEndAdd)//0x4E000)
\r
216 printk(">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector);
\r
217 ret = rknand_queue_write(LBA, sector, (void *)buf,1);
\r
221 ret = rknand_queue_write(LBA, sector, (void *)buf,0);
\r
229 void rknand_queue_cond_resched(void)
\r
234 static int rknand_get_device(int new_state)
\r
236 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
237 DECLARE_WAITQUEUE(wait, current);
\r
239 if (nand_info->state == FL_READY) {
\r
240 nand_info->state = new_state;
\r
243 NAND_DEBUG(NAND_DEBUG_LEVEL1,"FLASH not ready\n");
\r
244 set_current_state(TASK_UNINTERRUPTIBLE);
\r
245 add_wait_queue(&nand_info->wq, &wait);
\r
247 remove_wait_queue(&nand_info->wq, &wait);
\r
252 static void rknand_release_device(void)
\r
254 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
255 if(nand_info->pFlashCallBack)
\r
256 nand_info->pFlashCallBack();//call back
\r
257 nand_info->pFlashCallBack = NULL;
\r
258 nand_info->state = FL_READY;
\r
259 wake_up(&nand_info->wq);
\r
262 static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len,
\r
263 size_t *retlen, u_char *buf)
\r
266 int sector = len>>9;
\r
267 int LBA = (int)(from>>9);
\r
268 rknand_get_device(FL_READING);
\r
272 ret = NandRead(LBA, sector, buf);
\r
275 rknand_release_device();
\r
280 static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len,
\r
281 size_t *retlen, const u_char *buf)
\r
284 int sector = len>>9;
\r
285 int LBA = (int)(from>>9);
\r
286 //NAND_DEBUG(NAND_DEBUG_LEVEL0,"+");
\r
287 //printk(KERN_NOTICE "write: from=%lx,len=%x\n",(int)from,len);
\r
288 rknand_get_device(FL_WRITING);
\r
291 if(LBA < SysImageWriteEndAdd)//0x4E000)
\r
293 printk(">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector);
\r
294 ret = NandWriteImage(LBA&0xFFFFFFE0, sector, (void *)buf);// LBA align to 32
\r
298 ret = NandWrite(LBA, sector, (void *)buf);
\r
301 rknand_release_device();
\r
308 static int rk28xxnand_page_write(struct mtd_info *mtd, loff_t from, size_t len,
\r
309 size_t *retlen, const u_char *buf)
\r
313 int LBA = (int)(from);
\r
314 NAND_DEBUG(NAND_DEBUG_LEVEL1,"*");
\r
316 //printk(KERN_NOTICE "pagewrite: from=%lx,len=%x\n",(int)from,len);
\r
317 rknand_get_device(FL_WRITING);
\r
320 ret = FtlPageWrite(LBA, sector, (void *)buf);
\r
322 rknand_release_device();
\r
327 static int rk28xxnand_page_read(struct mtd_info *mtd, loff_t from, size_t len,
\r
328 size_t *retlen, u_char *buf)
\r
332 int LBA = (int)(from);
\r
333 NAND_DEBUG(NAND_DEBUG_LEVEL2,"-");
\r
336 // printk("rk28xxnand_read: from=%x,len=%x,\n",(int)from,len);
\r
337 rknand_get_device(FL_READING);
\r
340 ret = FtlPageRead(LBA, sector,(void *) buf);
\r
342 rknand_release_device();
\r
348 static int rk28xxnand_erase(struct mtd_info *mtd, struct erase_info *instr)
\r
351 if (instr->callback)
\r
352 instr->callback(instr);
\r
353 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_erase,add:0x%012llx,len:0x%012llx\n",instr->addr,instr->len);
\r
357 static void rk28xxnand_sync(struct mtd_info *mtd)
\r
359 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_sync: \n");
\r
360 #ifdef CONFIG_MTD_RKNAND_BUFFER
\r
361 rknand_buffer_sync();
\r
365 extern void FtlWriteCacheEn(int);
\r
366 static int rk28xxnand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
\r
368 int sector = len >> 9;
\r
369 int LBA = (int)(to >> 9);
\r
372 FtlWriteCacheEn(0);
\r
373 NandWrite(LBA, sector, (void *)buf);
\r
374 FtlWriteCacheEn(1);
\r
380 static int rk28xxnand_block_isbad(struct mtd_info *mtd, loff_t ofs)
\r
385 static int rk28xxnand_block_markbad(struct mtd_info *mtd, loff_t ofs)
\r
390 static int rk28xxnand_init(struct rknand_info *nand_info)
\r
392 struct mtd_info *mtd = &nand_info->mtd;
\r
393 struct rknand_chip *rknand = &nand_info->rknand;
\r
395 struct mtd_info *page_mtd = &nand_info->page_mtd;
\r
398 rknand->state = FL_READY;
\r
399 rknand->rknand_schedule_enable = 1;
\r
400 rknand->pFlashCallBack = NULL;
\r
401 init_waitqueue_head(&rknand->wq);
\r
402 NAND_DEBUG(NAND_DEBUG_LEVEL0,"FTLInit ...: \n");
\r
405 NAND_DEBUG(NAND_DEBUG_LEVEL0,"FTLInit Error: \n");
\r
408 NAND_DEBUG(NAND_DEBUG_LEVEL0,"FTLInit OK: \n");
\r
409 mtd->size = (uint64_t)NandGetCapacity()*0x200;
\r
410 //readflash modify rk28_partition_info
\r
412 NAND_DEBUG(NAND_DEBUG_LEVEL0,"mtd->size: 0x%012llx\n",mtd->size);
\r
415 mtd->ecclayout = 0;
\r
416 mtd->erasesize = 8*0x200; //sectorFlashGetPageSize()
\r
417 mtd->writesize = 8*0x200; //FlashGetPageSize()
\r
419 // Fill in remaining MTD driver data
\r
420 mtd->type = MTD_NANDFLASH;//MTD_RAM;//
\r
421 mtd->flags = (MTD_WRITEABLE|MTD_NO_ERASE);//
\r
422 mtd->erase = rk28xxnand_erase;
\r
424 mtd->unpoint = NULL;
\r
425 mtd->read = rk28xxnand_read;
\r
426 mtd->write = rk28xxnand_write;
\r
427 mtd->read_oob = NULL;
\r
428 mtd->write_oob = NULL;
\r
429 mtd->panic_write = rk28xxnand_panic_write;
\r
431 mtd->sync = rk28xxnand_sync;
\r
433 mtd->unlock = NULL;
\r
434 mtd->suspend = NULL;
\r
435 mtd->resume = NULL;
\r
436 mtd->block_isbad = rk28xxnand_block_isbad;
\r
437 mtd->block_markbad = rk28xxnand_block_markbad;
\r
438 mtd->owner = THIS_MODULE;
\r
441 page_mtd->size = FtlGetPageZoneCapacity()*0x200;
\r
442 //readflash modify rk28_partition_info
\r
443 NAND_DEBUG(NAND_DEBUG_LEVEL0,"page_mtd->size: 0x%012llx\n",page_mtd->size);
\r
444 page_mtd->oobsize = 0;
\r
445 page_mtd->oobavail = 0;
\r
446 page_mtd->ecclayout = 0;
\r
447 page_mtd->erasesize = FlashGetPageSize()*0x200; //sector
\r
448 page_mtd->writesize = FlashGetPageSize()*0x200;
\r
450 // Fill in remaining MTD driver data
\r
451 page_mtd->type = MTD_NANDFLASH;//MTD_RAM;//
\r
452 page_mtd->flags = (MTD_WRITEABLE|MTD_NO_ERASE);//
\r
453 page_mtd->erase = rk28xxnand_erase;
\r
454 page_mtd->point = NULL;
\r
455 page_mtd->unpoint = NULL;
\r
456 page_mtd->read = rk28xxnand_page_read;
\r
457 page_mtd->write = rk28xxnand_page_write;
\r
458 page_mtd->read_oob = NULL;
\r
459 page_mtd->write_oob = NULL;
\r
460 page_mtd->panic_write = NULL;
\r
462 page_mtd->sync = rk28xxnand_sync;
\r
463 page_mtd->lock = NULL;
\r
464 page_mtd->unlock = NULL;
\r
465 page_mtd->suspend = NULL;
\r
466 page_mtd->resume = NULL;
\r
467 page_mtd->block_isbad = NULL;
\r
468 page_mtd->block_markbad = NULL;
\r
469 page_mtd->owner = THIS_MODULE;
\r
477 * CMY: Ôö¼ÓÁ˶ÔÃüÁîÐзÖÇøÐÅÏ¢µÄÖ§³Ö
\r
478 * ÈôcmdlineÓÐÌṩ·ÖÇøÐÅÏ¢£¬ÔòʹÓÃcmdlineµÄ·ÖÇøÐÅÏ¢½øÐзÖÇø
\r
479 * ÈôcmdlineûÓÐÌṩ·ÖÇøÐÅÏ¢£¬ÔòʹÓÃĬÈϵķÖÇøÐÅÏ¢(rk28_partition_info)½øÐзÖÇø
\r
482 #ifdef CONFIG_MTD_CMDLINE_PARTS
\r
483 const char *part_probes[] = { "cmdlinepart", NULL };
\r
486 static int rk28xxnand_add_partitions(struct rknand_info *nand_info)
\r
488 #ifdef CONFIG_MTD_CMDLINE_PARTS
\r
489 int num_partitions = 0;
\r
491 // ´ÓÃüÁîÐнâÎö·ÖÇøµÄÐÅÏ¢
\r
492 num_partitions = parse_mtd_partitions(&(nand_info->mtd), part_probes, &nand_info->parts, 0);
\r
493 printk("num_partitions = %d\n",num_partitions);
\r
494 if(num_partitions > 0) {
\r
496 for (i = 0; i < num_partitions; i++)
\r
498 nand_info->parts[i].offset *= 0x200;
\r
499 nand_info->parts[i].size *=0x200;
\r
500 //printk(KERN_ERR"offset 0x%012llx size :0x%012llx\n",nand_info->parts[i].offset, nand_info->parts[i].size);
\r
502 nand_info->parts[num_partitions - 1].size = nand_info->mtd.size - nand_info->parts[num_partitions - 1].offset;
\r
504 g_num_partitions = num_partitions;
\r
505 return add_mtd_partitions(&nand_info->mtd, nand_info->parts, num_partitions);
\r
508 // Èç¹ûÃüÁîÐÐûÓÐÌṩ·ÖÇøÐÅÏ¢£¬ÔòʹÓÃĬÈϵķÖÇøÐÅÏ¢
\r
509 printk("parse_mtd_partitions\n");
\r
511 // rk28_partition_info[1].size = nand_info->mtd.size - ((ROOTFS_PART_SIZE + PARA_PART_SIZE + KERNEL_PART_SIZE)*0x100000);
\r
512 // rk28_partition_info[2].offset = rk28_partition_info[1].size + rk28_partition_info[1].offset;
\r
513 g_num_partitions = sizeof(rk28_partition_info)/sizeof(struct mtd_partition);
\r
514 return add_mtd_partitions(&nand_info->mtd, rk28_partition_info, sizeof(rk28_partition_info)/sizeof(struct mtd_partition));//MAX_FLASH_PARTITION);
\r
517 static int rknand_probe(struct platform_device *pdev)
\r
519 struct rknand_info *nand_info;
\r
520 struct mtd_partition *parts;
\r
522 //struct resource *res = pdev->resource;
\r
524 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_probe: \n");
\r
525 gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);
\r
529 nand_info = gpNandInfo;
\r
531 nand_info->mtd.name = dev_name(&pdev->dev);//pdev->dev.bus_id
\r
532 nand_info->mtd.priv = &nand_info->rknand;
\r
533 nand_info->mtd.owner = THIS_MODULE;
\r
535 nand_info->page_mtd.name = dev_name(&pdev->dev);//pdev->dev.bus_id
\r
536 nand_info->page_mtd.priv = &nand_info->rknand;
\r
537 nand_info->page_mtd.owner = THIS_MODULE;
\r
539 if(rk28xxnand_init(nand_info))
\r
544 #ifdef CONFIG_MTD_RKNAND_BUFFER
\r
545 if(rknand_buffer_init())
\r
551 rk28nand_create_procfs();
\r
554 GetSNSectorInfo(pbuf);
\r
555 printk("SN: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x",pbuf[2],pbuf[3],pbuf[4],pbuf[5],pbuf[6],pbuf[7],pbuf[8],pbuf[9],
\r
556 pbuf[10],pbuf[11],pbuf[12],pbuf[13],pbuf[14],pbuf[15],pbuf[16],pbuf[17]);
\r
559 rk28xxnand_add_partitions(nand_info);
\r
562 rk28_page_part_info[1].size = nand_info->page_mtd.size - rk28_page_part_info[0].size;
\r
563 add_mtd_partitions(&nand_info->page_mtd, rk28_page_part_info, 2);
\r
566 parts = nand_info->parts;
\r
567 for(i=0;i<g_num_partitions;i++)
\r
569 printk(">>> part[%d]: name=%s offset=0x%012llx\n", i, parts[i].name, parts[i].offset);
\r
570 if(strcmp(parts[i].name,"cache") == 0)
\r
572 SysImageWriteEndAdd = (unsigned long)parts[i].offset>>9;//sector
\r
573 printk(">>> SysImageWriteEndAdd=0x%lx\n", SysImageWriteEndAdd);
\r
578 NandSetSysProtAddr(SysImageWriteEndAdd);
\r
579 dev_set_drvdata(&pdev->dev, nand_info);
\r
590 static int rknand_remove(struct device *dev)
\r
592 struct platform_device *pdev = to_platform_device(dev);
\r
593 struct rknand_info *nand_info = dev_get_drvdata(&pdev->dev);
\r
594 struct resource *res = pdev->resource;
\r
595 unsigned long size = res->end - res->start + 1;
\r
596 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xx_rknand_remove: \n");
\r
597 dev_set_drvdata(&pdev->dev, NULL);
\r
600 if (nand_info->parts)
\r
601 del_mtd_partitions(&nand_info->mtd);
\r
603 del_mtd_device(&nand_info->mtd);
\r
605 //rknand_release(&nand_info->mtd);
\r
606 release_mem_region(res->start, size);
\r
612 static int rknand_suspend(struct platform_device *pdev, pm_message_t state)
\r
614 gpNandInfo->rknand.rknand_schedule_enable = 0;
\r
615 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_suspend: \n");
\r
619 static int rknand_resume(struct platform_device *pdev)
\r
621 gpNandInfo->rknand.rknand_schedule_enable = 1;
\r
622 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_resume: \n");
\r
626 void rknand_shutdown(struct platform_device *pdev)
\r
628 #ifdef CONFIG_MTD_RKNAND_BUFFER
\r
629 //NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_shutdown...\n");
\r
630 printk("rknand_shutdown...\n");
\r
631 gpNandInfo->rknand.rknand_schedule_enable = 0;
\r
632 rknand_buffer_shutdown();
\r
634 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
635 nand_info->rknand_schedule_enable = 0;
\r
636 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_shutdown...\n");
\r
637 if (nand_info->state == FL_READY)
\r
639 nand_info->state = FL_UNVALID;
\r
641 rknand_release_device();
\r
645 nand_info->pFlashCallBack = NandDeInit;
\r
650 static struct platform_driver rknand_driver = {
\r
651 .probe = rknand_probe,
\r
652 //.remove = rknand_remove,
\r
653 .suspend = rknand_suspend,
\r
654 .resume = rknand_resume,
\r
655 .shutdown = rknand_shutdown,
\r
657 .name = DRIVER_NAME,
\r
658 .owner = THIS_MODULE,
\r
659 //.bus = &platform_bus_type,
\r
664 MODULE_ALIAS(DRIVER_NAME);
\r
666 static int __init rknand_init(void)
\r
669 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_init: \n");
\r
670 ret = platform_driver_register(&rknand_driver);
\r
671 NAND_DEBUG(NAND_DEBUG_LEVEL0,"platform_driver_register:ret = %x \n",ret);
\r
675 static void __exit rknand_exit(void)
\r
677 //NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_exit: \n");
\r
678 //rknand_get_device(FL_UNVALID);
\r
680 //rknand_release_device();
\r
681 platform_driver_unregister(&rknand_driver);
\r
684 module_init(rknand_init);
\r
685 module_exit(rknand_exit);
\r
687 #if 0//def CONFIG_rknand
\r
689 ×¢²áÒ»¸ösys dev £¬ÔڹػúºÍ¸´Î»Ê±»Øµ÷£¬°Ñflash¹Ø¼üÐÅϢдµ½nand flashÖУ¬Ï´οª»úʱ¿ÉÒÔ¿ìËÙ¿ª»ú¡£
\r
692 #include <linux/sysdev.h>
\r
693 #include <linux/timer.h>
\r
695 static int rknand_sys_suspend(struct sys_device *dev, pm_message_t state)
\r
697 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
698 extern void FtlCacheWriteBack(void);
\r
699 NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_suspend...\n");
\r
700 nand_info->rknand_schedule_enable = 0;
\r
701 if (nand_info->state == FL_READY)
\r
703 nand_info->state = FL_WRITING;
\r
704 FtlCacheWriteBack();
\r
705 rknand_release_device();
\r
709 nand_info->pFlashCallBack = FtlCacheWriteBack;
\r
711 NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_suspend done...\n");
\r
716 static int rknand_sys_resume(struct sys_device *dev)
\r
718 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
719 nand_info->rknand_schedule_enable = 1;
\r
720 NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_resume...\n");
\r
724 static int rknand_sys_shutdown(struct sys_device *dev)
\r
726 struct rknand_chip *nand_info = &gpNandInfo->rknand;
\r
727 NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_shutdown...\n");
\r
728 nand_info->rknand_schedule_enable = 0;
\r
730 if (nand_info->state == FL_READY)
\r
732 //rknand_get_device(FL_UNVALID);
\r
733 nand_info->state = FL_UNVALID;
\r
735 rknand_release_device();
\r
738 {//flash not ready,use call back
\r
739 nand_info->pFlashCallBack = NandDeInit;
\r
744 static struct sysdev_class rknand_sysclass = {
\r
745 .name = "rknand_sysdev",
\r
746 .shutdown = rknand_sys_shutdown,
\r
747 .suspend = rknand_sys_suspend,
\r
748 .resume = rknand_sys_resume,
\r
751 static struct sys_device rknand_sysdevice = {
\r
753 .cls = &rknand_sysclass,
\r
756 static int __init rknand_sys_init(void)
\r
759 NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_sys_init!!!!!!!!!!!!!!\n");
\r
760 ret = sysdev_class_register(&rknand_sysclass);
\r
762 ret = sysdev_register(&rknand_sysdevice);
\r
766 device_initcall(rknand_sys_init);
\r
770 MODULE_LICENSE("");
\r
771 MODULE_AUTHOR("ZYF <zyf@rock-chips.com>");
\r
772 MODULE_DESCRIPTION("FTL layer for SLC and MlC nand flash on RK28xx SDK boards");
\r