2 #include <linux/module.h>
\r
3 #include <linux/kernel.h>
\r
4 #include <linux/slab.h>
\r
5 #include <linux/dma-mapping.h>
\r
6 #include <linux/irq.h>
\r
7 #include <linux/interrupt.h>
\r
8 #include <linux/bootmem.h>
\r
10 #include <linux/platform_device.h>
\r
11 #include <linux/semaphore.h>
\r
15 #include <linux/of.h>
\r
18 struct rknand_info {
\r
23 void (*rknand_suspend)(void);
\r
24 void (*rknand_resume)(void);
\r
25 void (*rknand_buffer_shutdown)(void);
\r
26 int (*rknand_exit)(void);
\r
28 int (*ftl_read) (int lun,int Index, int nSec, void *buf);
\r
29 int (*ftl_write) (int lun,int Index, int nSec, void *buf);
\r
30 void (*nand_timing_config)(unsigned long AHBnKHz);
\r
31 void (*rknand_dev_cache_flush)(void);
\r
36 struct rknand_info * gpNandInfo = NULL;
\r
37 static char *cmdline=NULL;
\r
38 int rknand_get_part_info(char **s)
\r
43 EXPORT_SYMBOL(rknand_get_part_info);
\r
45 static char sn_data[512];
\r
46 static char vendor0[512];
\r
48 char GetSNSectorInfo(char * pbuf)
\r
50 memcpy(pbuf,sn_data,0x200);
\r
54 char GetSNSectorInfoBeforeNandInit(char * pbuf)
\r
56 memcpy(pbuf,sn_data,0x200);
\r
60 char GetVendor0InfoBeforeNandInit(char * pbuf)
\r
62 memcpy(pbuf,vendor0 + 8,504);
\r
66 int GetParamterInfo(char * pbuf , int len)
\r
72 void rknand_spin_lock_init(spinlock_t * p_lock)
\r
74 spin_lock_init(p_lock);
\r
76 EXPORT_SYMBOL(rknand_spin_lock_init);
\r
78 void rknand_spin_lock(spinlock_t * p_lock)
\r
80 spin_lock_irq(p_lock);
\r
82 EXPORT_SYMBOL(rknand_spin_lock);
\r
84 void rknand_spin_unlock(spinlock_t * p_lock)
\r
86 spin_unlock_irq(p_lock);
\r
88 EXPORT_SYMBOL(rknand_spin_unlock);
\r
91 struct semaphore g_rk_nand_ops_mutex;
\r
92 void rknand_device_lock_init(void)
\r
94 sema_init(&g_rk_nand_ops_mutex, 1);
\r
96 EXPORT_SYMBOL(rknand_device_lock_init);
\r
97 void rknand_device_lock (void)
\r
99 down(&g_rk_nand_ops_mutex);
\r
101 EXPORT_SYMBOL(rknand_device_lock);
\r
103 int rknand_device_trylock (void)
\r
105 return down_trylock(&g_rk_nand_ops_mutex);
\r
107 EXPORT_SYMBOL(rknand_device_trylock);
\r
109 void rknand_device_unlock (void)
\r
111 up(&g_rk_nand_ops_mutex);
\r
113 EXPORT_SYMBOL(rknand_device_unlock);
\r
116 int rknand_get_device(struct rknand_info ** prknand_Info)
\r
118 *prknand_Info = gpNandInfo;
\r
121 EXPORT_SYMBOL(rknand_get_device);
\r
123 int rknand_dma_map_single(unsigned long ptr,int size,int dir)
\r
125 return dma_map_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);
\r
127 EXPORT_SYMBOL(rknand_dma_map_single);
\r
129 void rknand_dma_unmap_single(unsigned long ptr,int size,int dir)
\r
131 dma_unmap_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE);
\r
133 EXPORT_SYMBOL(rknand_dma_unmap_single);
\r
135 int rknand_flash_cs_init(void)
\r
139 EXPORT_SYMBOL(rknand_flash_cs_init);
\r
141 int rknand_get_reg_addr(int *pNandc0,int *pNandc1,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2)
\r
143 //*pNandc = ioremap(RK30_NANDC_PHYS,RK30_NANDC_SIZE);
\r
144 //*pSDMMC0 = ioremap(SDMMC0_BASE_ADDR, 0x4000);
\r
145 //*pSDMMC1 = ioremap(SDMMC1_BASE_ADDR, 0x4000);
\r
146 //*pSDMMC2 = ioremap(EMMC_BASE_ADDR, 0x4000);
\r
147 *pNandc0 = ioremap(0x10500000,0x4000);
\r
151 EXPORT_SYMBOL(rknand_get_reg_addr);
\r
153 static int g_nandc_irq = 59;
\r
154 int rknand_nandc_irq_init(int mode,void * pfun)
\r
159 ret = request_irq(g_nandc_irq, pfun, 0, "nandc", NULL);
\r
161 printk("request IRQ_NANDC irq , ret=%x.........\n", ret);
\r
165 free_irq(g_nandc_irq, NULL);
\r
169 EXPORT_SYMBOL(rknand_nandc_irq_init);
\r
170 static int rknand_probe(struct platform_device *pdev)
\r
172 g_nandc_irq = platform_get_irq(pdev, 0);
\r
173 printk("g_nandc_irq: %d\n",g_nandc_irq);
\r
174 if (g_nandc_irq < 0) {
\r
175 dev_err(&pdev->dev, "no irq resource?\n");
\r
176 return g_nandc_irq;
\r
181 static int rknand_suspend(struct platform_device *pdev, pm_message_t state)
\r
183 if(gpNandInfo->rknand_suspend)
\r
184 gpNandInfo->rknand_suspend();
\r
188 static int rknand_resume(struct platform_device *pdev)
\r
190 if(gpNandInfo->rknand_resume)
\r
191 gpNandInfo->rknand_resume();
\r
195 static void rknand_shutdown(struct platform_device *pdev)
\r
197 if(gpNandInfo->rknand_buffer_shutdown)
\r
198 gpNandInfo->rknand_buffer_shutdown();
\r
201 void rknand_dev_cache_flush(void)
\r
203 if(gpNandInfo->rknand_dev_cache_flush)
\r
204 gpNandInfo->rknand_dev_cache_flush();
\r
208 static const struct of_device_id of_rk_nandc_match[] = {
\r
209 { .compatible = "rockchip,rk-nandc" },
\r
214 static struct platform_driver rknand_driver = {
\r
215 .probe = rknand_probe,
\r
216 .suspend = rknand_suspend,
\r
217 .resume = rknand_resume,
\r
218 .shutdown = rknand_shutdown,
\r
222 .of_match_table = of_rk_nandc_match,
\r
224 .owner = THIS_MODULE,
\r
228 static void __exit rknand_part_exit(void)
\r
230 printk("rknand_part_exit: \n");
\r
231 platform_driver_unregister(&rknand_driver);
\r
232 if(gpNandInfo->rknand_exit)
\r
233 gpNandInfo->rknand_exit();
\r
238 MODULE_ALIAS(DRIVER_NAME);
\r
239 static int __init rknand_part_init(void)
\r
242 char * pbuf = ioremap(0x10501400,0x400);
\r
243 memcpy(vendor0,pbuf,0x200);
\r
244 memcpy(sn_data,pbuf+0x200,0x200);
\r
246 cmdline = strstr(saved_command_line, "mtdparts=") + 9;
\r
247 gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);
\r
250 memset(gpNandInfo,0,sizeof(struct rknand_info));
\r
251 ret = platform_driver_register(&rknand_driver);
\r
252 printk("rknand_driver:ret = %x \n",ret);
\r
256 module_init(rknand_part_init);
\r
257 module_exit(rknand_part_exit);
\r