--- /dev/null
+\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/slab.h>\r
+#include <linux/dma-mapping.h>\r
+#include <linux/irq.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/bootmem.h>\r
+#include <asm/io.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/semaphore.h>\r
+\r
+\r
+#ifdef CONFIG_OF\r
+#include <linux/of.h>\r
+#endif\r
+\r
+struct rknand_info {\r
+ int tag;\r
+ int enable;\r
+ int reserved0[6];\r
+ \r
+ void (*rknand_suspend)(void);\r
+ void (*rknand_resume)(void);\r
+ void (*rknand_buffer_shutdown)(void);\r
+ int (*rknand_exit)(void);\r
+ \r
+ int (*ftl_read) (int lun,int Index, int nSec, void *buf); \r
+ int (*ftl_write) (int lun,int Index, int nSec, void *buf);\r
+ void (*nand_timing_config)(unsigned long AHBnKHz);\r
+ void (*rknand_dev_cache_flush)(void);\r
+ \r
+ int reserved1[16];\r
+};\r
+\r
+struct rknand_info * gpNandInfo = NULL;\r
+static char *cmdline=NULL;\r
+int rknand_get_part_info(char **s)\r
+{\r
+ *s = cmdline;\r
+ return 0;\r
+}\r
+EXPORT_SYMBOL(rknand_get_part_info); \r
+\r
+static char sn_data[512];\r
+static char vendor0[512];\r
+\r
+char GetSNSectorInfo(char * pbuf)\r
+{\r
+ memcpy(pbuf,sn_data,0x200);\r
+ return 0;\r
+}\r
+\r
+char GetSNSectorInfoBeforeNandInit(char * pbuf)\r
+{\r
+ memcpy(pbuf,sn_data,0x200);\r
+ return 0;\r
+} \r
+\r
+char GetVendor0InfoBeforeNandInit(char * pbuf)\r
+{\r
+ memcpy(pbuf,vendor0 + 8,504);\r
+ return 0;\r
+}\r
+\r
+int GetParamterInfo(char * pbuf , int len)\r
+{\r
+ int ret = -1;\r
+ return ret;\r
+}\r
+\r
+void rknand_spin_lock_init(spinlock_t * p_lock)\r
+{\r
+ spin_lock_init(p_lock);\r
+}\r
+EXPORT_SYMBOL(rknand_spin_lock_init);\r
+\r
+void rknand_spin_lock(spinlock_t * p_lock)\r
+{\r
+ spin_lock_irq(p_lock);\r
+}\r
+EXPORT_SYMBOL(rknand_spin_lock);\r
+\r
+void rknand_spin_unlock(spinlock_t * p_lock)\r
+{\r
+ spin_unlock_irq(p_lock);\r
+}\r
+EXPORT_SYMBOL(rknand_spin_unlock);\r
+\r
+\r
+struct semaphore g_rk_nand_ops_mutex;\r
+void rknand_device_lock_init(void)\r
+{\r
+ sema_init(&g_rk_nand_ops_mutex, 1);\r
+}\r
+EXPORT_SYMBOL(rknand_device_lock_init);\r
+void rknand_device_lock (void)\r
+{\r
+ down(&g_rk_nand_ops_mutex);\r
+}\r
+EXPORT_SYMBOL(rknand_device_lock);\r
+\r
+int rknand_device_trylock (void)\r
+{\r
+ return down_trylock(&g_rk_nand_ops_mutex);\r
+}\r
+EXPORT_SYMBOL(rknand_device_trylock);\r
+\r
+void rknand_device_unlock (void)\r
+{\r
+ up(&g_rk_nand_ops_mutex);\r
+}\r
+EXPORT_SYMBOL(rknand_device_unlock);\r
+\r
+\r
+int rknand_get_device(struct rknand_info ** prknand_Info)\r
+{\r
+ *prknand_Info = gpNandInfo;\r
+ return 0; \r
+}\r
+EXPORT_SYMBOL(rknand_get_device);\r
+\r
+int rknand_dma_map_single(unsigned long ptr,int size,int dir)\r
+{\r
+ return dma_map_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
+}\r
+EXPORT_SYMBOL(rknand_dma_map_single);\r
+\r
+void rknand_dma_unmap_single(unsigned long ptr,int size,int dir)\r
+{\r
+ dma_unmap_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);\r
+}\r
+EXPORT_SYMBOL(rknand_dma_unmap_single);\r
+\r
+int rknand_flash_cs_init(void)\r
+{\r
+\r
+}\r
+EXPORT_SYMBOL(rknand_flash_cs_init);\r
+\r
+int rknand_get_reg_addr(int *pNandc0,int *pNandc1,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2)\r
+{\r
+ //*pNandc = ioremap(RK30_NANDC_PHYS,RK30_NANDC_SIZE);\r
+ //*pSDMMC0 = ioremap(SDMMC0_BASE_ADDR, 0x4000);\r
+ //*pSDMMC1 = ioremap(SDMMC1_BASE_ADDR, 0x4000);\r
+ //*pSDMMC2 = ioremap(EMMC_BASE_ADDR, 0x4000);\r
+ *pNandc0 = ioremap(0x10500000,0x4000);\r
+ //*pNandc1 = NULL;\r
+}\r
+\r
+EXPORT_SYMBOL(rknand_get_reg_addr);\r
+\r
+static int g_nandc_irq = 59;\r
+int rknand_nandc_irq_init(int mode,void * pfun)\r
+{\r
+ int ret = 0;\r
+ if(mode) //init\r
+ {\r
+ ret = request_irq(g_nandc_irq, pfun, 0, "nandc", NULL);\r
+ if(ret)\r
+ printk("request IRQ_NANDC irq , ret=%x.........\n", ret);\r
+ }\r
+ else //deinit\r
+ {\r
+ free_irq(g_nandc_irq, NULL);\r
+ }\r
+ return ret;\r
+}\r
+EXPORT_SYMBOL(rknand_nandc_irq_init);\r
+static int rknand_probe(struct platform_device *pdev)\r
+{\r
+ g_nandc_irq = platform_get_irq(pdev, 0);\r
+ printk("g_nandc_irq: %d\n",g_nandc_irq);\r
+ if (g_nandc_irq < 0) {\r
+ dev_err(&pdev->dev, "no irq resource?\n");\r
+ return g_nandc_irq;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int rknand_suspend(struct platform_device *pdev, pm_message_t state)\r
+{\r
+ if(gpNandInfo->rknand_suspend)\r
+ gpNandInfo->rknand_suspend(); \r
+ return 0;\r
+}\r
+\r
+static int rknand_resume(struct platform_device *pdev)\r
+{\r
+ if(gpNandInfo->rknand_resume)\r
+ gpNandInfo->rknand_resume(); \r
+ return 0;\r
+}\r
+\r
+static void rknand_shutdown(struct platform_device *pdev)\r
+{\r
+ if(gpNandInfo->rknand_buffer_shutdown)\r
+ gpNandInfo->rknand_buffer_shutdown(); \r
+}\r
+\r
+void rknand_dev_cache_flush(void)\r
+{\r
+ if(gpNandInfo->rknand_dev_cache_flush)\r
+ gpNandInfo->rknand_dev_cache_flush();\r
+}\r
+\r
+#ifdef CONFIG_OF\r
+static const struct of_device_id of_rk_nandc_match[] = {\r
+ { .compatible = "rockchip,rk-nandc" },\r
+ { /* Sentinel */ }\r
+};\r
+#endif\r
+\r
+static struct platform_driver rknand_driver = {\r
+ .probe = rknand_probe,\r
+ .suspend = rknand_suspend,\r
+ .resume = rknand_resume,\r
+ .shutdown = rknand_shutdown,\r
+ .driver = {\r
+ .name = "rknand",\r
+#ifdef CONFIG_OF\r
+ .of_match_table = of_rk_nandc_match,\r
+#endif\r
+ .owner = THIS_MODULE,\r
+ },\r
+};\r
+\r
+static void __exit rknand_part_exit(void)\r
+{\r
+ printk("rknand_part_exit: \n");\r
+ platform_driver_unregister(&rknand_driver);\r
+ if(gpNandInfo->rknand_exit)\r
+ gpNandInfo->rknand_exit(); \r
+ if (gpNandInfo)\r
+ kfree(gpNandInfo);\r
+}\r
+\r
+MODULE_ALIAS(DRIVER_NAME);\r
+static int __init rknand_part_init(void)\r
+{\r
+ int ret = 0;\r
+ char * pbuf = ioremap(0x10501400,0x400);\r
+ memcpy(vendor0,pbuf,0x200);\r
+ memcpy(sn_data,pbuf+0x200,0x200);\r
+ iounmap(pbuf);\r
+ cmdline = strstr(saved_command_line, "mtdparts=") + 9;\r
+ gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);\r
+ if (!gpNandInfo)\r
+ return -ENOMEM;\r
+ memset(gpNandInfo,0,sizeof(struct rknand_info));\r
+ ret = platform_driver_register(&rknand_driver);\r
+ printk("rknand_driver:ret = %x \n",ret);\r
+ return ret;\r
+}\r
+\r
+module_init(rknand_part_init);\r
+module_exit(rknand_part_exit);\r