static int __init rknand_init(void) { int ret; NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_init: \n"); ret = platform_driver_register(&rknand_driver); NAND_DEBUG(NAND_DEBUG_LEVEL0,"platform_driver_register:ret = %x \n",ret); return ret; }
static int rknand_add_partitions(struct rknand_info *nand_info) { #ifdef CONFIG_MTD_CMDLINE_PARTS int num_partitions = 0; // 从命令行解析分区的信息 num_partitions = parse_mtd_partitions(&(rknand_mtd), part_probes, &rknand_parts, 0); NAND_DEBUG(NAND_DEBUG_LEVEL0,"num_partitions = %d\n",num_partitions); if(num_partitions > 0) { int i; for (i = 0; i < num_partitions; i++) { rknand_parts[i].offset *= 0x200; rknand_parts[i].size *=0x200; } rknand_parts[num_partitions - 1].size = rknand_mtd.size - rknand_parts[num_partitions - 1].offset; g_num_partitions = num_partitions; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) return mtd_device_register(&rknand_mtd, rknand_parts, num_partitions); #else return add_mtd_partitions(&(rknand_mtd), rknand_parts, num_partitions); #endif } #endif g_num_partitions = 0; return 0; }
int add_rknand_device(struct rknand_info * prknand_Info) { struct mtd_partition *parts; int i; NAND_DEBUG(NAND_DEBUG_LEVEL0,"add_rknand_device: \n"); rknand_mtd.size = (uint64_t)gpNandInfo->nandCapacity; rk29xxnand_add_partitions(prknand_Info); parts = rknand_parts; for(i=0;i<g_num_partitions;i++) { //printk(">>> part[%d]: name=%s offset=0x%012llx\n", i, parts[i].name, parts[i].offset); if(strcmp(parts[i].name,"backup") == 0) { SysImageWriteEndAdd = (unsigned long)(parts[i].offset + parts[i].size);//sector //printk(">>> SysImageWriteEndAdd=0x%lx\n", SysImageWriteEndAdd); break; } } gpNandInfo->SysImageWriteEndAdd = SysImageWriteEndAdd; return 0; }
static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, const u_char *buf) { int ret = 0; int sector = len; int LBA = (int)(from); //printk("*"); //if(rknand_debug) // printk(KERN_NOTICE "write: from=%lx,sector=%x\n",(int)LBA,sector); //printk_write_log(LBA,sector,buf); if(sector && gpNandInfo->ftl_write)// cmy { if(LBA < SysImageWriteEndAdd)//0x4E000) { NAND_DEBUG(NAND_DEBUG_LEVEL0,">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector); ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,1); } else { ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,0); } } *retlen = len; return 0; }
static int rk29xxnand_add_partitions(struct rknand_info *nand_info) { #ifdef CONFIG_MTD_CMDLINE_PARTS int num_partitions = 0; // 从命令行解析分区的信息 num_partitions = parse_mtd_partitions(&(rknand_mtd), part_probes, &rknand_parts, 0); NAND_DEBUG(NAND_DEBUG_LEVEL0,"num_partitions = %d\n",num_partitions); if(num_partitions > 0) { int i; g_num_partitions = num_partitions; return add_mtd_partitions(&(rknand_mtd), rknand_parts, num_partitions); } #endif return 0; }
static int rknand_probe(struct platform_device *pdev) { struct rknand_info *nand_info; int err = 0; NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_probe: \n"); gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL); if (!gpNandInfo) return -ENOMEM; nand_info = gpNandInfo; memset(gpNandInfo,0,sizeof(struct rknand_info)); gpNandInfo->bufSize = MAX_BUFFER_SIZE * 512; gpNandInfo->pbuf = (char *)grknand_buf; gpNandInfo->pdmaBuf = (char *)grknand_dma_buf; //printk(" gpNandInfo->pdmaBuf=0x%x\n", gpNandInfo->pdmaBuf); #ifdef CONFIG_MTD_EMMC_CLK_POWER_SAVE gpNandInfo->emmc_clk_power_save_en = 1; #endif rknand_mtd.name = pdev->dev.bus_id;//dev_name(&pdev->dev); rknand_mtd.priv = &nand_info->rknand; rknand_mtd.owner = THIS_MODULE; if(rk28xxnand_init(nand_info)) { err = -ENXIO; goto exit_free; } nand_info->add_rknand_device = add_rknand_device; nand_info->get_rknand_device = get_rknand_device; rk28nand_create_procfs(); return 0; exit_free: if(nand_info) kfree(nand_info); return err; }
static void rknand_sync(struct mtd_info *mtd) { NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk_nand_sync: \n"); if(gpNandInfo->ftl_sync) gpNandInfo->ftl_sync(); }
static int rknand_resume(struct platform_device *pdev) { gpNandInfo->rknand.rknand_schedule_enable = 1; NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_resume: \n"); return 0; }
static int rknand_suspend(struct platform_device *pdev, pm_message_t state) { gpNandInfo->rknand.rknand_schedule_enable = 0; NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_suspend: \n"); return 0; }