static int __devinit generic_onenand_probe(struct device *dev) { struct onenand_info *info; struct platform_device *pdev = to_platform_device(dev); struct flash_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = res->end - res->start + 1; int err; info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(struct onenand_info)); if (!request_mem_region(res->start, size, dev->driver->name)) { err = -EBUSY; goto out_free_info; } info->onenand.base = ioremap(res->start, size); if (!info->onenand.base) { err = -ENOMEM; goto out_release_mem_region; } info->onenand.mmcontrol = pdata->mmcontrol; info->mtd.name = pdev->dev.bus_id; info->mtd.priv = &info->onenand; info->mtd.owner = THIS_MODULE; if (onenand_scan(&info->mtd, 1)) { err = -ENXIO; goto out_iounmap; } #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) add_mtd_partitions(&info->mtd, info->parts, err); else if (err < 0 && pdata->parts) add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); else #endif err = add_mtd_device(&info->mtd); dev_set_drvdata(&pdev->dev, info); return 0; out_iounmap: iounmap(info->onenand.base); out_release_mem_region: release_mem_region(res->start, size); out_free_info: kfree(info); return err; }
static int __init lpc32xx_add_partitions(struct lpc32xx_nand_host *host) { #ifdef CONFIG_MTD_PARTITIONS struct mtd_info *mtd = &host->mtd; struct mtd_partition *partitions = NULL; int num_partitions = 0; #ifdef CONFIG_MTD_CMDLINE_PARTS static const char *part_probes[] = { "cmdlinepart", NULL }; mtd->name = LPC32XX_MODNAME; num_partitions = parse_mtd_partitions(mtd, part_probes, &partitions, 0); #endif if ((num_partitions <= 0) && (host->ncfg->partition_info)) partitions = host->ncfg->partition_info(mtd->size, &num_partitions); if ((!partitions) || (num_partitions == 0)) { dev_err(mtd->dev.parent,"No parititions defined," " or unsupported device.\n"); return ENXIO; } return add_mtd_partitions(mtd, partitions, num_partitions); #else return add_mtd_device(mtd); #endif }
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; }
/* * Initialize FLASH support */ static int __init h720x_mtd_init(void) { char *part_type = NULL; h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size); if (!h720x_map.virt) { printk(KERN_ERR "H720x-MTD: ioremap failed\n"); return -EIO; } simple_map_init(&h720x_map); // Probe for flash bankwidth 4 printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n"); mymtd = do_map_probe("cfi_probe", &h720x_map); if (!mymtd) { printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n"); // Probe for bankwidth 2 h720x_map.bankwidth = 2; mymtd = do_map_probe("cfi_probe", &h720x_map); } if (mymtd) { mymtd->owner = THIS_MODULE; <<<<<<< HEAD nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); if (nr_mtd_parts > 0) part_type = "command line"; =======
static int __init omapflash_probe(struct platform_device *pdev) { int err; struct omapflash_info *info; struct flash_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = res->end - res->start + 1; info = kzalloc(sizeof(struct omapflash_info), GFP_KERNEL); if (!info) return -ENOMEM; if (!request_mem_region(res->start, size, "flash")) { err = -EBUSY; goto out_free_info; } info->map.virt = ioremap(res->start, size); if (!info->map.virt) { err = -ENOMEM; goto out_release_mem_region; } info->map.name = pdev->dev.bus_id; info->map.phys = res->start; info->map.size = size; info->map.bankwidth = pdata->width; info->map.set_vpp = omap_set_vpp; simple_map_init(&info->map); info->mtd = do_map_probe(pdata->map_name, &info->map); if (!info->mtd) { err = -EIO; goto out_iounmap; } info->mtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); if (err > 0) add_mtd_partitions(info->mtd, info->parts, err); else if (err <= 0 && pdata->parts) add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); else #endif add_mtd_device(info->mtd); platform_set_drvdata(pdev, info); return 0; out_iounmap: iounmap(info->map.virt); out_release_mem_region: release_mem_region(res->start, size); out_free_info: kfree(info); return err; }
static int __init cs553x_init(void) { int err = -ENXIO; int i; uint64_t val; #ifdef CONFIG_MTD_PARTITIONS int mtd_parts_nb = 0; struct mtd_partition *mtd_parts = NULL; #endif /* If the CPU isn't a Geode GX or LX, abort */ if (!is_geode()) return -ENXIO; /* If it doesn't have the CS553[56], abort */ rdmsrl(MSR_DIVIL_GLD_CAP, val); val &= ~0xFFULL; if (val != CAP_CS5535 && val != CAP_CS5536) return -ENXIO; /* If it doesn't have the NAND controller enabled, abort */ rdmsrl(MSR_DIVIL_BALL_OPTS, val); if (val & PIN_OPT_IDE) { printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n"); return -ENXIO; } for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val); if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND)) err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF); } /* Register all devices together here. This means we can easily hack it to do mtdconcat etc. if we want to. */ for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { if (cs553x_mtd[i]) { /* If any devices registered, return success. Else the last error. */ #ifdef CONFIG_MTD_PARTITIONS mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0); if (mtd_parts_nb > 0) { printk(KERN_NOTICE "Using command line partition definition\n"); add_mtd_partitions(cs553x_mtd[i], mtd_parts, mtd_parts_nb); } else { add_mtd_device(cs553x_mtd[i]); } #else add_mtd_device(cs553x_mtd[i]); #endif err = 0; } } return err; }
static int __devinit bfin_flash_probe(struct platform_device *pdev) { int ret; struct physmap_flash_data *pdata = pdev->dev.platform_data; struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); struct async_state *state; state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) return -ENOMEM; state->map.name = DRIVER_NAME; state->map.read = bfin_flash_read; state->map.copy_from = bfin_flash_copy_from; state->map.write = bfin_flash_write; state->map.copy_to = bfin_flash_copy_to; state->map.bankwidth = pdata->width; state->map.size = resource_size(memory); state->map.virt = (void __iomem *)memory->start; state->map.phys = memory->start; state->map.map_priv_1 = (unsigned long)state; state->enet_flash_pin = platform_get_irq(pdev, 0); state->flash_ambctl0 = flash_ambctl->start; state->flash_ambctl1 = flash_ambctl->end; if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); kfree(state); return -EBUSY; } gpio_direction_output(state->enet_flash_pin, 1); pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); state->mtd = do_map_probe(memory->name, &state->map); if (!state->mtd) { gpio_free(state->enet_flash_pin); kfree(state); return -ENXIO; } ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); if (ret > 0) { pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); mtd_device_register(state->mtd, pdata->parts, ret); state->parts = pdata->parts; } else if (pdata->nr_parts) { pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts); } else { pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); mtd_device_register(state->mtd, NULL, 0); } platform_set_drvdata(pdev, state); return 0; }
static int __init dm270_init_flash (void) { struct mtd_partition *parts; int nb_parts = 0; int parsed_nr_parts = 0; const char *part_type; /* * Static partition definition selection */ part_type = "static"; parts = dm270_partitions; nb_parts = ARRAY_SIZE(dm270_partitions); dm270_map_flash.virt = phys_to_virt(dm270_map_flash.phys); simple_map_init(&dm270_map_flash); /* * Now let's probe for the actual flash. Do it here since * specific machine settings might have been set above. */ printk(KERN_NOTICE "DM270 flash: probing %d-bit flash bus\n", dm270_map_flash.bankwidth*8); dm270_flash_mtd = do_map_probe("cfi_probe", &dm270_map_flash); if (!dm270_flash_mtd) { return -ENXIO; } dm270_flash_mtd->owner = THIS_MODULE; /* * Dynamic partition selection stuff (might override the static ones) */ if (dm270_partition_types[0]) { parsed_nr_parts = parse_mtd_partitions(dm270_flash_mtd, dm270_partition_types, &parsed_parts, CONFIG_FLASH_MEM_BASE); } if (parsed_nr_parts > 0) { part_type = "dynamic"; parts = parsed_parts; nb_parts = parsed_nr_parts; } if (nb_parts == 0) { printk(KERN_NOTICE "DM270 flash: no partition info available," "registering whole flash at once\n"); if (add_mtd_device(dm270_flash_mtd)) { return -ENXIO; } } else { printk(KERN_NOTICE "Using %s partition definition\n", part_type); return add_mtd_partitions(dm270_flash_mtd, parts, nb_parts); } return 0; }
static int __init init_soleng_maps(void) { int nr_parts = 0; /* First probe at offset 0 */ soleng_flash_map.phys = 0; soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0); soleng_eprom_map.phys = 0x01000000; soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); simple_map_init(&soleng_eprom_map); simple_map_init(&soleng_flash_map); printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); if (!flash_mtd) { /* Not there. Try swapping */ printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n"); soleng_flash_map.phys = 0x01000000; soleng_flash_map.virt = P2SEGADDR(0x01000000); soleng_eprom_map.phys = 0; soleng_eprom_map.virt = P1SEGADDR(0); flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); if (!flash_mtd) { /* Eep. */ printk(KERN_NOTICE "Flash chips not detected at either possible location.\n"); return -ENXIO; } } printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n", soleng_flash_map.phys & 0x1fffffff, soleng_eprom_map.phys & 0x1fffffff); flash_mtd->owner = THIS_MODULE; eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); if (eprom_mtd) { eprom_mtd->owner = THIS_MODULE; add_mtd_device(eprom_mtd); } nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); #ifdef CONFIG_MTD_SUPERH_RESERVE if (nr_parts <= 0) { printk(KERN_NOTICE "Using configured partition at 0x%08x.\n", CONFIG_MTD_SUPERH_RESERVE); parsed_parts = superh_se_partitions; nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts); } #endif /* CONFIG_MTD_SUPERH_RESERVE */ if (nr_parts > 0) add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); else add_mtd_device(flash_mtd); return 0; }
static int __devinit generic_onenand_probe(struct platform_device *pdev) { struct onenand_info *info; struct onenand_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = resource_size(res); int err; info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL); if (!info) return -ENOMEM; if (!request_mem_region(res->start, size, dev_name(&pdev->dev))) { err = -EBUSY; goto out_free_info; } info->onenand.base = ioremap(res->start, size); if (!info->onenand.base) { err = -ENOMEM; goto out_release_mem_region; } info->onenand.mmcontrol = pdata ? pdata->mmcontrol : 0; info->onenand.irq = platform_get_irq(pdev, 0); info->mtd.name = dev_name(&pdev->dev); info->mtd.priv = &info->onenand; info->mtd.owner = THIS_MODULE; if (onenand_scan(&info->mtd, 1)) { err = -ENXIO; goto out_iounmap; } err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) mtd_device_register(&info->mtd, info->parts, err); else if (err <= 0 && pdata && pdata->parts) mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts); else err = mtd_device_register(&info->mtd, NULL, 0); platform_set_drvdata(pdev, info); return 0; out_iounmap: iounmap(info->onenand.base); out_release_mem_region: release_mem_region(res->start, size); out_free_info: kfree(info); return err; }
int mtdsf_init_device(struct mtd_info *mtd, unsigned long size, char *name) { int nr_parts, cut_parts = 0; char *part_type = NULL; mtd->name = name; mtd->type = MTD_NORFLASH; mtd->flags = MTD_CAP_NORFLASH; mtd->size = size; mtd->erasesize = MTDSF_ERASE_SIZE; mtd->owner = THIS_MODULE; mtd->erase = sf_erase; mtd->read = sf_read; mtd->write = sf_write; mtd->writesize = 1; boot_partitions[5].offset = size - boot_partitions[5].size; boot_partitions[4].offset = boot_partitions[5].offset - boot_partitions[4].size; boot_partitions[3].offset = boot_partitions[4].offset - boot_partitions[3].size; boot_partitions[2].offset = boot_partitions[3].offset - boot_partitions[2].size; if (boot_partitions[2].offset > 0x00280000) { boot_partitions[1].offset = boot_partitions[2].offset - boot_partitions[1].size; if (boot_partitions[1].offset > 0) boot_partitions[0].size = boot_partitions[1].offset; else { shift_partition_content(1); cut_parts = 1; } } else if (boot_partitions[2].offset > 0) { boot_partitions[1].size = boot_partitions[2].offset; boot_partitions[1].offset = 0; shift_partition_content(1); cut_parts = 1; } else { shift_partition_content(2); cut_parts = 2; } nr_parts = parse_mtd_partitions(mtd, part_probes, &parts, 0); if (nr_parts > 0) { part_type = "command line"; cut_parts = 0; } if (nr_parts <= 0) { parts = boot_partitions; nr_parts = NUM_SF_PARTITIONS; part_type = "builtin"; } printk(KERN_INFO "SF Using %s partition table count=%d\n", part_type, nr_parts - cut_parts); mtd_device_register(mtd, parts, nr_parts - cut_parts); //add_mtd_partitions(mtd, boot_partitions, ARRAY_SIZE(boot_partitions)); return 0; }
static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) { struct mtd_partition *parts; static const char *part_probes[] = { "cmdlinepart", NULL }; /* register the flash bank */ /* partition the flash bank */ p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0); return mtd_device_register(p->info, parts, p->nr_parts); }
int __init init_s3c2410nor(void) { static const char *rom_probe_types[] = PROBETYPES; const char **type; const char *part_type = 0; printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR); s3c2410nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);//物理->虚拟地址 if (!s3c2410nor_map.virt) { printk(MSG_PREFIX "failed to ioremap\n"); return - EIO; } simple_map_init(&s3c2410nor_map); mymtd = 0; type = rom_probe_types; for (; !mymtd && *type; type++) { mymtd = do_map_probe(*type, &s3c2410nor_map);//探测NOR FLASH } if (mymtd) { mymtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS mtd_parts_nb = parse_mtd_partitions(mymtd, NULL, &mtd_parts, MTDID);//探测分区信息 if (mtd_parts_nb > 0) part_type = "detected"; if (mtd_parts_nb == 0) //未探测到,使用数组定义的分区信息 { mtd_parts = static_partitions; mtd_parts_nb = ARRAY_SIZE(static_partitions); part_type = "static"; } #endif add_mtd_device(mymtd); if (mtd_parts_nb == 0) printk(KERN_NOTICE MSG_PREFIX "no partition info available\n"); else { printk(KERN_NOTICE MSG_PREFIX "using %s partition definition\n", part_type); add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);//添加分区信息 } return 0; } iounmap((void*)s3c2410nor_map.virt); return - ENXIO; }
static int __init epxa_mtd_init(void) { int i; printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); epxa_map.virt = (void __iomem *)ioremap(FLASH_START, FLASH_SIZE); if (!epxa_map.virt) { printk("Failed to ioremap %s flash\n",BOARD_NAME); return -EIO; } simple_map_init(&epxa_map); mymtd = do_map_probe("cfi_probe", &epxa_map); if (!mymtd) { iounmap((void *)epxa_map.virt); return -ENXIO; } mymtd->owner = THIS_MODULE; /* Unlock the flash device. */ if(mymtd->unlock){ for (i=0; i<mymtd->numeraseregions;i++){ int j; for(j=0;j<mymtd->eraseregions[i].numblocks;j++){ mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize); } } } #ifdef CONFIG_MTD_PARTITIONS nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0); if (nr_parts > 0) { add_mtd_partitions(mymtd, parts, nr_parts); return 0; } #endif /* No recognised partitioning schemes found - use defaults */ nr_parts = epxa_default_partitions(mymtd, &parts); if (nr_parts > 0) { add_mtd_partitions(mymtd, parts, nr_parts); return 0; } /* If all else fails... */ add_mtd_device(mymtd); return 0; }
int __init init_physmap(void) { static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 }; const char **type; printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); physmap_map.virt = (unsigned long)ioremap(physmap_map.phys, physmap_map.size); if (!physmap_map.virt) { printk("Failed to ioremap\n"); return -EIO; } simple_map_init(&physmap_map); mymtd = 0; type = rom_probe_types; for(; !mymtd && *type; type++) { mymtd = do_map_probe(*type, &physmap_map); } if (mymtd) { mymtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, &mtd_parts, 0); if (mtd_parts_nb > 0) { add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); return 0; } if (num_physmap_partitions != 0) { printk(KERN_NOTICE "Using physmap partition definition\n"); add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); return 0; } #endif add_mtd_device(mymtd); return 0; } iounmap((void *)physmap_map.virt); return -ENXIO; }
static int __init armflash_cfi_init(void *base, u_int size) { int ret; armflash_flash_init(); armflash_flash_wp(1); /* * look for CFI based flash parts fitted to this board */ armflash_map.size = size; armflash_map.buswidth = 4; armflash_map.virt = (unsigned long) base; simple_map_init(&armflash_map); /* * The CFI layer automatically works out what size chips we have * and does the necessary identification for us automatically. */ mtd = do_map_probe("cfi_probe", &armflash_map); if (!mtd) return -ENXIO; mtd->owner = THIS_MODULE; ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0); if (ret <= 0) { /* * Use default static MTD partition definition: */ parts = integrator_partitions; ret = ARRAY_SIZE(integrator_partitions); } ret = add_mtd_partitions(mtd, parts, ret); if (ret) printk(KERN_ERR "mtd partition registration failed: %d\n", ret); /* * If we got an error, free all resources. */ if (ret < 0) { del_mtd_partitions(mtd); map_destroy(mtd); } return ret; }
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 void __init set_mtd_partitions(void) { int nr_parts = 0; simple_map_init(&rsk_flash_map); flash_mtd = do_map_probe("cfi_probe", &rsk_flash_map); nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_partitions, 0); /* If there is no partition table, used the hard coded table */ if (nr_parts <= 0) { flash_data.parts = rsk_partitions; flash_data.nr_parts = ARRAY_SIZE(rsk_partitions); } else { flash_data.nr_parts = nr_parts; flash_data.parts = parsed_partitions; } }
int __init init_alteramap(void) { static const char *rom_probe_types[] = {"cfi_probe", "jedec_probe", 0 }; const char **type; ndk_amd_map.virt = (unsigned long *)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); /* if (!ndk_amd_map.virt) { printk("Failed to ioremap\n"); return -EIO; } */ simple_map_init(&ndk_amd_map); mymtd = 0; type = rom_probe_types; for(; !mymtd && *type; type++) { mymtd = do_map_probe(*type, &ndk_amd_map); } if (mymtd) { mymtd->owner = THIS_MODULE; mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, &mtd_parts, 0); if (mtd_parts_nb > 0) { mtd_device_register(mymtd, mtd_parts, mtd_parts_nb); return 0; } if (NUM_PARTITIONS != 0) { printk(KERN_NOTICE "Using Altera NDK partition definition\n"); mtd_device_register(mymtd, alteramap_partitions, NUM_PARTITIONS); return 0; } return 0; } iounmap((void *)ndk_amd_map.virt); return -ENXIO; }
static int __init armflash_cfi_init(void *base, u_int size) { int ret; armflash_flash_init(); armflash_flash_wp(1); /* * look for CFI based flash parts fitted to this board */ armflash_map.size = size; armflash_map.bankwidth = 4; armflash_map.virt = (void __iomem *) base; simple_map_init(&armflash_map); /* * Also, the CFI layer automatically works out what size * of chips we have, and does the necessary identification * for us automatically. */ mtd = do_map_probe("cfi_probe", &armflash_map); if (!mtd) return -ENXIO; mtd->owner = THIS_MODULE; ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0); if (ret > 0) { ret = add_mtd_partitions(mtd, parts, ret); if (ret) printk(KERN_ERR "mtd partition registration " "failed: %d\n", ret); } /* * If we got an error, free all resources. */ if (ret < 0) { del_mtd_partitions(mtd); map_destroy(mtd); } return ret; }
static int __init flash_init(void) { /* * Read the bootbus region 0 setup to determine the base * address of the flash. */ union cvmx_mio_boot_reg_cfgx region_cfg; region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0)); if (region_cfg.s.en) { /* * The bootloader always takes the flash and sets its * address so the entire flash fits below * 0x1fc00000. This way the flash aliases to * 0x1fc00000 for booting. Software can access the * full flash at the true address, while core boot can * access 4MB. */ /* Use this name so old part lines work */ flash_map.name = "phys_mapped_flash"; flash_map.phys = region_cfg.s.base << 16; flash_map.size = 0x1fc00000 - flash_map.phys; flash_map.bankwidth = 1; flash_map.virt = ioremap(flash_map.phys, flash_map.size); pr_notice("Bootbus flash: Setting flash for %luMB flash at " "0x%08llx\n", flash_map.size >> 20, flash_map.phys); simple_map_init(&flash_map); mymtd = do_map_probe("cfi_probe", &flash_map); if (mymtd) { mymtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS nr_parts = parse_mtd_partitions(mymtd, part_probe_types, &parts, 0); if (nr_parts > 0) add_mtd_partitions(mymtd, parts, nr_parts); else add_mtd_device(mymtd); #else add_mtd_device(mymtd); #endif } else { pr_err("Failed to register MTD device for flash\n"); } }
/* * Initialize FLASH support */ int __init h720x_mtd_init(void) { char *part_type = NULL; h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); if (!h720x_map.virt) { printk(KERN_ERR "H720x-MTD: ioremap failed\n"); return -EIO; } simple_map_init(&h720x_map); // Probe for flash bankwidth 4 printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n"); mymtd = do_map_probe("cfi_probe", &h720x_map); if (!mymtd) { printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n"); // Probe for bankwidth 2 h720x_map.bankwidth = 2; mymtd = do_map_probe("cfi_probe", &h720x_map); } if (mymtd) { mymtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); if (nr_mtd_parts > 0) part_type = "command line"; #endif if (nr_mtd_parts <= 0) { mtd_parts = h720x_partitions; nr_mtd_parts = NUM_PARTITIONS; part_type = "builtin"; } printk(KERN_INFO "Using %s partition table\n", part_type); add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts); return 0; } iounmap((void *)h720x_map.virt); return -ENXIO; }
static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) { int err = 0; #if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE) struct mtd_partition *parts; static const char *part_probes[] = { "cmdlinepart", NULL }; #endif /* register the flash bank */ #if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE) /* partition the flash bank */ p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0); if (p->nr_parts > 0) err = add_mtd_partitions(p->info, parts, p->nr_parts); #endif if (p->nr_parts <= 0) err = add_mtd_device(p->info); return err; }
static int __init init_iq80310(void) { struct mtd_partition *parts; int nb_parts = 0; int parsed_nr_parts = 0; int ret; iq80310_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); if (!iq80310_map.virt) { printk("Failed to ioremap\n"); return -EIO; } simple_map_init(&iq80310_map); mymtd = do_map_probe("cfi_probe", &iq80310_map); if (!mymtd) { iounmap((void *)iq80310_map.virt); return -ENXIO; } mymtd->owner = THIS_MODULE; ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); if (ret > 0) parsed_nr_parts = ret; if (parsed_nr_parts > 0) { parts = parsed_parts; nb_parts = parsed_nr_parts; } else { parts = iq80310_partitions; nb_parts = ARRAY_SIZE(iq80310_partitions); } add_mtd_partitions(mymtd, parts, nb_parts); return 0; }
/* * Probe for the NAND device. */ static int __init plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = pdev->dev.platform_data; struct plat_nand_data *data; int res = 0; /* Allocate memory for the device structure (and zero it) */ data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL); if (!data) { dev_err(&pdev->dev, "failed to allocate device structure.\n"); return -ENOMEM; } data->io_base = ioremap(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); if (data->io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); kfree(data); return -EIO; } data->chip.priv = &data; data->mtd.priv = &data->chip; data->mtd.owner = THIS_MODULE; data->mtd.name = dev_name(&pdev->dev); data->chip.IO_ADDR_R = data->io_base; data->chip.IO_ADDR_W = data->io_base; data->chip.cmd_ctrl = pdata->ctrl.cmd_ctrl; data->chip.dev_ready = pdata->ctrl.dev_ready; data->chip.select_chip = pdata->ctrl.select_chip; data->chip.chip_delay = pdata->chip.chip_delay; data->chip.options |= pdata->chip.options; data->chip.ecc.hwctl = pdata->ctrl.hwcontrol; data->chip.ecc.layout = pdata->chip.ecclayout; data->chip.ecc.mode = NAND_ECC_SOFT; platform_set_drvdata(pdev, data); /* Scan to find existance of the device */ if (nand_scan(&data->mtd, 1)) { res = -ENXIO; goto out; } #ifdef CONFIG_MTD_PARTITIONS if (pdata->chip.part_probe_types) { res = parse_mtd_partitions(&data->mtd, pdata->chip.part_probe_types, &data->parts, 0); if (res > 0) { add_mtd_partitions(&data->mtd, data->parts, res); return 0; } } if (pdata->chip.partitions) { data->parts = pdata->chip.partitions; res = add_mtd_partitions(&data->mtd, data->parts, pdata->chip.nr_partitions); } else #endif res = add_mtd_device(&data->mtd); if (!res) return res; nand_release(&data->mtd); out: platform_set_drvdata(pdev, NULL); iounmap(data->io_base); kfree(data); return res; }
static int __init pxa2xx_flash_probe(struct platform_device *pdev) { struct flash_platform_data *flash = pdev->dev.platform_data; struct pxa2xx_flash_info *info; struct mtd_partition *parts; struct resource *res; int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(struct pxa2xx_flash_info)); info->map.name = (char *) flash->name; info->map.bankwidth = flash->width; info->map.phys = res->start; info->map.size = res->end - res->start + 1; info->parts = flash->parts; info->nr_parts = flash->nr_parts; info->map.virt = ioremap(info->map.phys, info->map.size); if (!info->map.virt) { printk(KERN_WARNING "Failed to ioremap %s\n", info->map.name); return -ENOMEM; } info->map.cached = ioremap_cached(info->map.phys, info->map.size); if (!info->map.cached) printk(KERN_WARNING "Failed to ioremap cached %s\n", info->map.name); info->map.inval_cache = pxa2xx_map_inval_cache; simple_map_init(&info->map); printk(KERN_NOTICE "Probing %s at physical address 0x%08lx" " (%d-bit bankwidth)\n", info->map.name, (unsigned long)info->map.phys, info->map.bankwidth * 8); info->mtd = do_map_probe(flash->map_name, &info->map); if (!info->mtd) { iounmap((void *)info->map.virt); if (info->map.cached) iounmap(info->map.cached); return -EIO; } info->mtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS ret = parse_mtd_partitions(info->mtd, probes, &parts, 0); if (ret > 0) { info->nr_parts = ret; info->parts = parts; } #endif if (info->nr_parts) { add_mtd_partitions(info->mtd, info->parts, info->nr_parts); } else { printk("Registering %s as whole device\n", info->map.name); add_mtd_device(info->mtd); } platform_set_drvdata(pdev, info); return 0; }
static int ixp2000_flash_probe(struct platform_device *dev) { static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; struct ixp2000_flash_data *ixp_data = dev->dev.platform_data; struct flash_platform_data *plat; struct ixp2000_flash_info *info; unsigned long window_size; int err = -1; if (!ixp_data) return -ENODEV; plat = ixp_data->platform_data; if (!plat) return -ENODEV; window_size = dev->resource->end - dev->resource->start + 1; dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n", ixp_data->nr_banks, ((u32)window_size >> 20)); if (plat->width != 1) { dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n", plat->width * 8); return -EIO; } info = kmalloc(sizeof(struct ixp2000_flash_info), GFP_KERNEL); if(!info) { err = -ENOMEM; goto Error; } memzero(info, sizeof(struct ixp2000_flash_info)); platform_set_drvdata(dev, info); /* * Tell the MTD layer we're not 1:1 mapped so that it does * not attempt to do a direct access on us. */ info->map.phys = NO_XIP; info->map.size = ixp_data->nr_banks * window_size; info->map.bankwidth = 1; /* * map_priv_2 is used to store a ptr to to the bank_setup routine */ info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup; info->map.name = dev->dev.bus_id; info->map.read = ixp2000_flash_read8; info->map.write = ixp2000_flash_write8; info->map.copy_from = ixp2000_flash_copy_from; info->map.copy_to = ixp2000_flash_copy_to; info->res = request_mem_region(dev->resource->start, dev->resource->end - dev->resource->start + 1, dev->dev.bus_id); if (!info->res) { dev_err(&dev->dev, "Could not reserve memory region\n"); err = -ENOMEM; goto Error; } info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start, dev->resource->end - dev->resource->start + 1); if (!info->map.map_priv_1) { dev_err(&dev->dev, "Failed to ioremap flash region\n"); err = -EIO; goto Error; } #if defined(__ARMEB__) /* * Enable erratum 44 workaround for NPUs with broken slowport */ erratum44_workaround = ixp2000_has_broken_slowport(); dev_info(&dev->dev, "Erratum 44 workaround %s\n", erratum44_workaround ? "enabled" : "disabled"); #endif info->mtd = do_map_probe(plat->map_name, &info->map); if (!info->mtd) { dev_err(&dev->dev, "map_probe failed\n"); err = -ENXIO; goto Error; } info->mtd->owner = THIS_MODULE; err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); if (err > 0) { err = add_mtd_partitions(info->mtd, info->partitions, err); if(err) dev_err(&dev->dev, "Could not parse partitions\n"); } if (err) goto Error; return 0; Error: ixp2000_flash_remove(dev); return err; }
/* * board specific setup should have ensured the SPI clock used here * matches what the READ command supports, at least until this driver * understands FAST_READ (for clocks over 25 MHz). */ static int __devinit m25p_probe(struct spi_device *spi) { struct flash_platform_data *data; struct m25p *flash; struct flash_info *info; unsigned i; uint64_t tmpdiv; /* Platform data helps sort out which chip type we have, as * well as how this board partitions it. If we don't have * a chip ID, try the JEDEC id commands; they'll work for most * newer chips, even if we don't recognize the particular chip. */ data = spi->dev.platform_data; if (data && data->type) { for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) { if (strcmp(data->type, info->name) == 0) break; } /* unrecognized chip? */ if (i == ARRAY_SIZE(m25p_data)) { DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n", spi->dev.bus_id, data->type); info = NULL; /* recognized; is that chip really what's there? */ } else if (info->jedec_id) { struct flash_info *chip = jedec_probe(spi); if (!chip || chip != info) { dev_warn(&spi->dev, "found %s, expected %s\n", chip ? chip->name : "UNKNOWN", info->name); info = NULL; } } } else info = jedec_probe(spi); if (!info) return -ENODEV; flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) return -ENOMEM; flash->spi = spi; mutex_init(&flash->lock); dev_set_drvdata(&spi->dev, flash); if (data && data->name) flash->mtd.name = data->name; else flash->mtd.name = spi->dev.bus_id; flash->mtd.type = MTD_NORFLASH; flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.size = info->sector_size * info->n_sectors; flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; flash->mtd.write = m25p80_write; /* prefer "small sector" erase if possible */ if (info->flags & SECT_4K) { flash->erase_opcode = OPCODE_BE_4K; flash->mtd.erasesize = 4096; } else { flash->erase_opcode = OPCODE_SE; flash->mtd.erasesize = info->sector_size; } tmpdiv = (uint64_t) info->sector_size * info->n_sectors; do_div(tmpdiv, flash->mtd.erasesize); flash->mtd.num_eraseblocks = tmpdiv; dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name, device_size(&(flash->mtd)) >> (ffs(1024)-1)); DEBUG(MTD_DEBUG_LEVEL2, "mtd .name = %s, .size = 0x%.8x (%uMiB) " ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", flash->mtd.name, flash->mtd.size, flash->mtd.size / (1024*1024), flash->mtd.erasesize, flash->mtd.erasesize / 1024, flash->mtd.numeraseregions); if (flash->mtd.numeraseregions) for (i = 0; i < flash->mtd.numeraseregions; i++) DEBUG(MTD_DEBUG_LEVEL2, "mtd.eraseregions[%d] = { .offset = 0x%.8x, " ".erasesize = 0x%.8x (%uKiB), " ".numblocks = %d }\n", i, flash->mtd.eraseregions[i].offset, flash->mtd.eraseregions[i].erasesize, flash->mtd.eraseregions[i].erasesize / 1024, flash->mtd.eraseregions[i].numblocks); /* partitions should match sector boundaries; and it may be good to * use readonly partitions for writeprotected sectors (BP2..BP0). */ if (mtd_has_partitions()) { struct mtd_partition *parts = NULL; int nr_parts = 0; #ifdef CONFIG_MTD_CMDLINE_PARTS static const char *part_probes[] = { "cmdlinepart", NULL, }; nr_parts = parse_mtd_partitions(&flash->mtd, part_probes, &parts, 0); #endif if (nr_parts <= 0 && data && data->parts) { parts = data->parts; nr_parts = data->nr_parts; } if (nr_parts > 0) { for (i = 0; i < nr_parts; i++) { DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " "{.name = %s, .offset = 0x%.8x, " ".size = 0x%.8x (%uKiB) }\n", i, parts[i].name, parts[i].offset, parts[i].size, parts[i].size / 1024); } flash->partitioned = 1; return add_mtd_partitions(&flash->mtd, parts, nr_parts); } } else if (data->nr_parts) dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", data->nr_parts, data->name); return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0; }
static int __devinit omap_nand_probe(struct platform_device *pdev) { struct omap_nand_info *info; struct omap_nand_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = res->end - res->start + 1; int err; info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL); if (!info) return -ENOMEM; if (!request_mem_region(res->start, size, pdev->dev.driver->name)) { err = -EBUSY; goto out_free_info; } info->nand.IO_ADDR_R = ioremap(res->start, size); if (!info->nand.IO_ADDR_R) { err = -ENOMEM; goto out_release_mem_region; } info->nand.IO_ADDR_W = info->nand.IO_ADDR_R; info->nand.cmd_ctrl = omap_nand_hwcontrol; info->nand.ecc.mode = NAND_ECC_SOFT; info->nand.options = pdata->options; if (pdata->dev_ready) info->nand.dev_ready = omap_nand_dev_ready; else info->nand.chip_delay = 20; info->mtd.name = pdev->dev.bus_id; info->mtd.priv = &info->nand; info->pdata = pdata; /* DIP switches on H2 and some other boards change between 8 and 16 bit * bus widths for flash. Try the other width if the first try fails. */ if (nand_scan(&info->mtd, 1)) { info->nand.options ^= NAND_BUSWIDTH_16; if (nand_scan(&info->mtd, 1)) { err = -ENXIO; goto out_iounmap; } } info->mtd.owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) add_mtd_partitions(&info->mtd, info->parts, err); else if (err < 0 && pdata->parts) add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); else #endif add_mtd_device(&info->mtd); platform_set_drvdata(pdev, info); return 0; out_iounmap: iounmap(info->nand.IO_ADDR_R); out_release_mem_region: release_mem_region(res->start, size); out_free_info: kfree(info); return err; }
static int __init init_lubbock(void) { int flashboot = (LUB_CONF_SWITCHES & 1); int ret = 0, i; lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth = (BOOT_DEF & 1) ? 2 : 4; /* Compensate for the nROMBT switch which swaps the flash banks */ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", flashboot?"Flash":"ROM", flashboot); lubbock_maps[flashboot^1].name = "Lubbock Application Flash"; lubbock_maps[flashboot].name = "Lubbock Boot ROM"; for (i = 0; i < 2; i++) { lubbock_maps[i].virt = ioremap(lubbock_maps[i].phys, WINDOW_SIZE); if (!lubbock_maps[i].virt) { printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name); if (!ret) ret = -ENOMEM; continue; } lubbock_maps[i].cached = ioremap_cached(lubbock_maps[i].phys, WINDOW_SIZE); if (!lubbock_maps[i].cached) printk(KERN_WARNING "Failed to ioremap cached %s\n", lubbock_maps[i].name); simple_map_init(&lubbock_maps[i]); printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", lubbock_maps[i].name, lubbock_maps[i].phys, lubbock_maps[i].bankwidth * 8); mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); if (!mymtds[i]) { iounmap((void *)lubbock_maps[i].virt); if (lubbock_maps[i].cached) iounmap(lubbock_maps[i].cached); if (!ret) ret = -EIO; continue; } mymtds[i]->owner = THIS_MODULE; ret = parse_mtd_partitions(mymtds[i], probes, &parsed_parts[i], 0); if (ret > 0) nr_parsed_parts[i] = ret; } if (!mymtds[0] && !mymtds[1]) return ret; for (i = 0; i < 2; i++) { if (!mymtds[i]) { printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); } else if (nr_parsed_parts[i]) { add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); } else if (!i) { printk("Using static partitions on %s\n", lubbock_maps[i].name); add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions)); } else { printk("Registering %s as whole device\n", lubbock_maps[i].name); add_mtd_device(mymtds[i]); } } return 0; }