add rknand base file for ko.
authorZhaoyifeng <zyf@rock-chips.com>
Tue, 18 Mar 2014 13:23:10 +0000 (21:23 +0800)
committerZhaoyifeng <zyf@rock-chips.com>
Tue, 18 Mar 2014 13:23:10 +0000 (21:23 +0800)
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-rockchip/Makefile
arch/arm/mach-rockchip/rknandbase.c [new file with mode: 0755]

index a0c4d82fe7ae9e88abc6a678e3dd634acea2e1bf..6bc3917fbcb1a7d36d112dd44b1a358f41c01d33 100755 (executable)
@@ -39,6 +39,12 @@ config RK_CONSOLE_THREAD
        help
          Normal kernel printk will write out to UART by "kconsole" kthread
 
+config BLOCK_RKNAND
+       tristate "RK NAND Device Support"
+       default n
+       help
+         RK NAND Device Support.
+
 config RK_FPGA
        bool "FPGA Board"
 
index b65e808d30d7d8c1e26fec2b493224409b397f5d..5a0fae27464b04d108d91cc5e8265f1cc62f79b2 100755 (executable)
@@ -14,3 +14,5 @@ obj-$(CONFIG_RK_VCODEC) += vcodec_service.o
 obj-$(CONFIG_RK_VPU) += vpu_service.o
 obj-$(CONFIG_RK_PL330_DMA_TEST) += dma_memcpy_test.o
 obj-$(CONFIG_DDR_FREQ) += ddr_freq.o
+obj-$(CONFIG_BLOCK_RKNAND) += rknandbase.o
+
diff --git a/arch/arm/mach-rockchip/rknandbase.c b/arch/arm/mach-rockchip/rknandbase.c
new file mode 100755 (executable)
index 0000000..7db78f1
--- /dev/null
@@ -0,0 +1,257 @@
+\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