static int __init h720x_mtd_init(void) { 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); // 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"); // h720x_map.bankwidth = 2; mymtd = do_map_probe("cfi_probe", &h720x_map); } if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_parse_register(mymtd, NULL, NULL, h720x_partitions, NUM_PARTITIONS); return 0; } iounmap((void *)h720x_map.virt); return -ENXIO; }
static int bcm47xxnflash_probe(struct platform_device *pdev) { struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); struct bcm47xxnflash *b47n; int err = 0; b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL); if (!b47n) return -ENOMEM; b47n->nand_chip.priv = b47n; b47n->mtd.owner = THIS_MODULE; b47n->mtd.priv = &b47n->nand_chip; /* Required */ b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { err = bcm47xxnflash_ops_bcm4706_init(b47n); } else { pr_err("Device not supported\n"); err = -ENOTSUPP; } if (err) { pr_err("Initialization failed: %d\n", err); return err; } err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); return err; } return 0; }
/** * Module/ driver initialization. * * Returns Zero on success */ 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; mtd_device_parse_register(mymtd, part_probe_types, NULL, NULL, 0); } else { pr_err("Failed to register MTD device for flash\n"); } }
static int bcm47xxsflash_probe(struct platform_device *pdev) { struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); struct bcm47xxsflash *b47s; int err; b47s = kzalloc(sizeof(*b47s), GFP_KERNEL); if (!b47s) { err = -ENOMEM; goto out; } sflash->priv = b47s; b47s->window = sflash->window; b47s->blocksize = sflash->blocksize; b47s->numblocks = sflash->numblocks; b47s->size = sflash->size; bcm47xxsflash_fill_mtd(b47s); err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); goto err_dev_reg; } return 0; err_dev_reg: kfree(&b47s->mtd); out: return err; }
static int bcm47xxsflash_probe(struct platform_device *pdev) { struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); int err; sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!sflash->mtd) { err = -ENOMEM; goto out; } bcm47xxsflash_fill_mtd(sflash, sflash->mtd); err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); goto err_dev_reg; } return 0; err_dev_reg: kfree(sflash->mtd); out: return err; }
static int sst25l_probe(struct spi_device *spi) { struct flash_info *flash_info; struct sst25l_flash *flash; struct flash_platform_data *data; int ret; flash_info = sst25l_match_device(spi); if (!flash_info) return -ENODEV; flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); if (!flash) return -ENOMEM; flash->spi = spi; mutex_init(&flash->lock); spi_set_drvdata(spi, flash); data = dev_get_platdata(&spi->dev); if (data && data->name) flash->mtd.name = data->name; else flash->mtd.name = dev_name(&spi->dev); flash->mtd.type = MTD_NORFLASH; flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; flash->mtd.writebufsize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; flash->mtd._erase = sst25l_erase; flash->mtd._read = sst25l_read; flash->mtd._write = sst25l_write; dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, (long long)flash->mtd.size >> 10); pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) " ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", flash->mtd.name, (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), flash->mtd.erasesize, flash->mtd.erasesize / 1024, flash->mtd.numeraseregions); ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, data ? data->parts : NULL, data ? data->nr_parts : 0); if (ret) return -ENODEV; return 0; }
/* * Initialize chip structure */ static int ndfc_chip_init(struct ndfc_controller *ndfc, struct device_node *node) { struct device_node *flash_np; struct nand_chip *chip = &ndfc->chip; struct mtd_part_parser_data ppdata; int ret; chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; chip->cmd_ctrl = ndfc_hwcontrol; chip->dev_ready = ndfc_ready; chip->select_chip = ndfc_select_chip; chip->chip_delay = 50; chip->controller = &ndfc->ndfc_control; chip->read_buf = ndfc_read_buf; chip->write_buf = ndfc_write_buf; chip->verify_buf = ndfc_verify_buf; chip->ecc.correct = nand_correct_data; chip->ecc.hwctl = ndfc_enable_hwecc; chip->ecc.calculate = ndfc_calculate_ecc; chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 256; chip->ecc.bytes = 3; chip->ecc.strength = 1; chip->priv = ndfc; ndfc->mtd.priv = chip; ndfc->mtd.owner = THIS_MODULE; flash_np = of_get_next_child(node, NULL); if (!flash_np) return -ENODEV; ppdata.of_node = flash_np; ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), flash_np->name); if (!ndfc->mtd.name) { ret = -ENOMEM; goto err; } ret = nand_scan(&ndfc->mtd, 1); if (ret) goto err; ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0); err: of_node_put(flash_np); if (ret) kfree(ndfc->mtd.name); return ret; }
static int 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 = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata ? pdata->parts : NULL, pdata ? pdata->nr_parts : 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; }
/** * Module/ driver initialization. * * Returns Zero on success */ static int octeon_flash_probe(struct platform_device *pdev) { union cvmx_mio_boot_reg_cfgx region_cfg; u32 cs; int r; struct device_node *np = pdev->dev.of_node; r = of_property_read_u32(np, "reg", &cs); if (r) return r; /* * Read the bootbus region 0 setup to determine the base * address of the flash. */ region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs)); 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; /* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */ flash_map.bankwidth = region_cfg.s.width + 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); WARN_ON(!map_bankwidth_supported(flash_map.bankwidth)); flash_map.read = octeon_flash_map_read; flash_map.write = octeon_flash_map_write; flash_map.copy_from = octeon_flash_map_copy_from; flash_map.copy_to = octeon_flash_map_copy_to; mymtd = do_map_probe("cfi_probe", &flash_map); if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_parse_register(mymtd, part_probe_types, NULL, NULL, 0); } else { pr_err("Failed to register MTD device for flash\n"); } }
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; } mtd_device_parse_register(state->mtd, part_probe_types, NULL, pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, state); return 0; }
static int __init cs553x_init(void) { int err = -ENXIO; int i; uint64_t val; /* 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. */ mtd_device_parse_register(cs553x_mtd[i], NULL, 0, NULL, 0); err = 0; } } return err; }
static int __init init_soleng_maps(void) { /* 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; mtd_device_register(eprom_mtd, NULL, 0); } mtd_device_parse_register(flash_mtd, probes, NULL, superh_se_partitions, NUM_PARTITIONS); return 0; }
static int __init init_impa7(void) { static const char *rom_probe_types[] = PROBETYPES; const char **type; int i; static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = { { WINDOW_ADDR0, WINDOW_SIZE0 }, { WINDOW_ADDR1, WINDOW_SIZE1 }, }; int devicesfound = 0; for(i=0; i<NUM_FLASHBANKS; i++) { printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr); impa7_map[i].phys = pt[i].addr; impa7_map[i].virt = ioremap(pt[i].addr, pt[i].size); if (!impa7_map[i].virt) { printk(MSG_PREFIX "failed to ioremap\n"); return -EIO; } simple_map_init(&impa7_map[i]); impa7_mtd[i] = 0; type = rom_probe_types; for(; !impa7_mtd[i] && *type; type++) { impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]); } if (impa7_mtd[i]) { impa7_mtd[i]->owner = THIS_MODULE; devicesfound++; mtd_device_parse_register(impa7_mtd[i], NULL, NULL, partitions, ARRAY_SIZE(partitions)); } else iounmap((void *)impa7_map[i].virt); } return devicesfound == 0 ? -ENXIO : 0; }
static int __init cs553x_init(void) { int err = -ENXIO; int i; uint64_t val; if (!is_geode()) return -ENXIO; rdmsrl(MSR_DIVIL_GLD_CAP, val); val &= ~0xFFULL; if (val != CAP_CS5535 && val != CAP_CS5536) return -ENXIO; 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); } for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { if (cs553x_mtd[i]) { mtd_device_parse_register(cs553x_mtd[i], NULL, NULL, NULL, 0); err = 0; } } return err; }
static int bcm47xxnflash_probe(struct platform_device *pdev) { struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); struct bcm47xxnflash *b47n; struct mtd_info *mtd; int err = 0; b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL); if (!b47n) return -ENOMEM; nand_set_controller_data(&b47n->nand_chip, b47n); mtd = nand_to_mtd(&b47n->nand_chip); mtd->dev.parent = &pdev->dev; b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { err = bcm47xxnflash_ops_bcm4706_init(b47n); } else { pr_err("Device not supported\n"); err = -ENOTSUPP; } if (err) { pr_err("Initialization failed: %d\n", err); return err; } platform_set_drvdata(pdev, b47n); err = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); if (err) { pr_err("Failed to register MTD device: %d\n", err); return err; } return 0; }
static int physmap_flash_probe(struct platform_device *dev) { struct physmap_flash_data *physmap_data; struct physmap_flash_info *info; const char **probe_type; const char **part_types; int err = 0; int i; int devices_found = 0; physmap_data = dev->dev.platform_data; if (physmap_data == NULL) return -ENODEV; info = devm_kzalloc(&dev->dev, sizeof(struct physmap_flash_info), GFP_KERNEL); if (info == NULL) { err = -ENOMEM; goto err_out; } if (physmap_data->init) { err = physmap_data->init(dev); if (err) goto err_out; } platform_set_drvdata(dev, info); for (i = 0; i < dev->num_resources; i++) { printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", (unsigned long long)resource_size(&dev->resource[i]), (unsigned long long)dev->resource[i].start); if (!devm_request_mem_region(&dev->dev, dev->resource[i].start, resource_size(&dev->resource[i]), dev_name(&dev->dev))) { dev_err(&dev->dev, "Could not reserve memory region\n"); err = -ENOMEM; goto err_out; } info->map[i].name = dev_name(&dev->dev); info->map[i].phys = dev->resource[i].start; info->map[i].size = resource_size(&dev->resource[i]); info->map[i].bankwidth = physmap_data->width; info->map[i].set_vpp = physmap_set_vpp; info->map[i].pfow_base = physmap_data->pfow_base; info->map[i].map_priv_1 = (unsigned long)dev; info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, info->map[i].size); if (info->map[i].virt == NULL) { dev_err(&dev->dev, "Failed to ioremap flash region\n"); err = -EIO; goto err_out; } simple_map_init(&info->map[i]); probe_type = rom_probe_types; if (physmap_data->probe_type == NULL) { for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) info->mtd[i] = do_map_probe(*probe_type, &info->map[i]); } else info->mtd[i] = do_map_probe(physmap_data->probe_type, &info->map[i]); if (info->mtd[i] == NULL) { dev_err(&dev->dev, "map_probe failed\n"); err = -ENXIO; goto err_out; } else { devices_found++; } info->mtd[i]->owner = THIS_MODULE; info->mtd[i]->dev.parent = &dev->dev; } if (devices_found == 1) { info->cmtd = info->mtd[0]; } else if (devices_found > 1) { /* * We detected multiple devices. Concatenate them together. */ info->cmtd = mtd_concat_create(info->mtd, devices_found, dev_name(&dev->dev)); if (info->cmtd == NULL) err = -ENXIO; } if (err) goto err_out; part_types = physmap_data->part_probe_types ? : part_probe_types; mtd_device_parse_register(info->cmtd, part_types, 0, physmap_data->parts, physmap_data->nr_parts); return 0; err_out: physmap_flash_remove(dev); return err; }
static int platram_probe(struct platform_device *pdev) { struct platdata_mtd_ram *pdata; struct platram_info *info; struct resource *res; int err = 0; dev_dbg(&pdev->dev, "probe entered\n"); if (dev_get_platdata(&pdev->dev) == NULL) { dev_err(&pdev->dev, "no platform data supplied\n"); err = -ENOENT; goto exit_error; } pdata = dev_get_platdata(&pdev->dev); info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { err = -ENOMEM; goto exit_error; } platform_set_drvdata(pdev, info); info->dev = &pdev->dev; info->pdata = pdata; /* get the resource for the memory mapping */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no memory resource specified\n"); err = -ENOENT; goto exit_free; } dev_dbg(&pdev->dev, "got platform resource %p (0x%llx)\n", res, (unsigned long long)res->start); /* setup map parameters */ info->map.phys = res->start; info->map.size = resource_size(res); info->map.name = pdata->mapname != NULL ? (char *)pdata->mapname : (char *)pdev->name; info->map.bankwidth = pdata->bankwidth; /* register our usage of the memory area */ info->area = request_mem_region(res->start, info->map.size, pdev->name); if (info->area == NULL) { dev_err(&pdev->dev, "failed to request memory region\n"); err = -EIO; goto exit_free; } /* remap the memory area */ info->map.virt = ioremap(res->start, info->map.size); dev_dbg(&pdev->dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size); if (info->map.virt == NULL) { dev_err(&pdev->dev, "failed to ioremap() region\n"); err = -EIO; goto exit_free; } simple_map_init(&info->map); dev_dbg(&pdev->dev, "initialised map, probing for mtd\n"); /* probe for the right mtd map driver * supplied by the platform_data struct */ if (pdata->map_probes) { const char * const *map_probes = pdata->map_probes; for ( ; !info->mtd && *map_probes; map_probes++) info->mtd = do_map_probe(*map_probes , &info->map); } /* fallback to map_ram */ else info->mtd = do_map_probe("map_ram", &info->map); if (info->mtd == NULL) { dev_err(&pdev->dev, "failed to probe for map_ram\n"); err = -ENOMEM; goto exit_free; } info->mtd->owner = THIS_MODULE; info->mtd->dev.parent = &pdev->dev; platram_setrw(info, PLATRAM_RW); /* check to see if there are any available partitions, or whether * to add this device whole */ err = mtd_device_parse_register(info->mtd, pdata->probes, NULL, pdata->partitions, pdata->nr_partitions); if (!err) dev_info(&pdev->dev, "registered mtd device\n"); if (pdata->nr_partitions) { /* add the whole device. */ err = mtd_device_register(info->mtd, NULL, 0); if (err) { dev_err(&pdev->dev, "failed to register the entire device\n"); } } return err; exit_free: platram_remove(pdev); exit_error: return err; }
/* * Probe for the NAND device. */ static int __devinit plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = pdev->dev.platform_data; struct plat_nand_data *data; struct resource *res; int err = 0; if (pdata->chip.nr_chips < 1) { dev_err(&pdev->dev, "invalid number of chips specified\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENXIO; /* 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; } if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { dev_err(&pdev->dev, "request_mem_region failed\n"); err = -EBUSY; goto out_free; } data->io_base = ioremap(res->start, resource_size(res)); if (data->io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); err = -EIO; goto out_release_io; } 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.write_buf = pdata->ctrl.write_buf; data->chip.read_buf = pdata->ctrl.read_buf; data->chip.chip_delay = pdata->chip.chip_delay; data->chip.options |= pdata->chip.options; data->chip.bbt_options |= pdata->chip.bbt_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); /* Handle any platform specific setup */ if (pdata->ctrl.probe) { err = pdata->ctrl.probe(pdev); if (err) goto out; } /* Scan to find existence of the device */ if (nand_scan(&data->mtd, pdata->chip.nr_chips)) { err = -ENXIO; goto out; } err = mtd_device_parse_register(&data->mtd, pdata->chip.part_probe_types, NULL, pdata->chip.partitions, pdata->chip.nr_partitions); if (!err) return err; nand_release(&data->mtd); out: if (pdata->ctrl.remove) pdata->ctrl.remove(pdev); platform_set_drvdata(pdev, NULL); iounmap(data->io_base); out_release_io: release_mem_region(res->start, resource_size(res)); out_free: kfree(data); return err; }
static int vr_nor_init_partitions(struct vr_nor_mtd *p) { /* register the flash bank */ /* partition the flash bank */ return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); }
/* * spinand_probe - [spinand Interface] * @spi_nand: registered device driver. * * Description: * To set up the device driver parameters to make the device available. */ static int spinand_probe(struct spi_device *spi_nand) { struct mtd_info *mtd; struct nand_chip *chip; struct spinand_info *info; struct spinand_state *state; struct mtd_part_parser_data ppdata; info = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info), GFP_KERNEL); if (!info) return -ENOMEM; info->spi = spi_nand; spinand_lock_block(spi_nand, BL_ALL_UNLOCKED); state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state), GFP_KERNEL); if (!state) return -ENOMEM; info->priv = state; state->buf_ptr = 0; state->buf = devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL); if (!state->buf) return -ENOMEM; chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip), GFP_KERNEL); if (!chip) return -ENOMEM; #ifdef CONFIG_MTD_SPINAND_ONDIEECC chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 0x200; chip->ecc.bytes = 0x6; chip->ecc.steps = 0x4; chip->ecc.strength = 1; chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; chip->ecc.layout = &spinand_oob_64; chip->ecc.read_page = spinand_read_page_hwecc; chip->ecc.write_page = spinand_write_page_hwecc; #else chip->ecc.mode = NAND_ECC_SOFT; if (spinand_disable_ecc(spi_nand) < 0) pr_info("%s: disable ecc failed!\n", __func__); #endif chip->priv = info; chip->read_buf = spinand_read_buf; chip->write_buf = spinand_write_buf; chip->read_byte = spinand_read_byte; chip->cmdfunc = spinand_cmdfunc; chip->waitfunc = spinand_wait; chip->options |= NAND_CACHEPRG; chip->select_chip = spinand_select_chip; mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL); if (!mtd) return -ENOMEM; dev_set_drvdata(&spi_nand->dev, mtd); mtd->priv = chip; mtd->name = dev_name(&spi_nand->dev); mtd->owner = THIS_MODULE; mtd->oobsize = 64; if (nand_scan(mtd, 1)) return -ENXIO; ppdata.of_node = spi_nand->dev.of_node; return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); }
static int ltq_mtd_probe(struct platform_device *pdev) { struct mtd_part_parser_data ppdata; struct ltq_mtd *ltq_mtd; struct cfi_private *cfi; int err; if (of_machine_is_compatible("lantiq,falcon") && (ltq_boot_select() != BS_FLASH)) { dev_err(&pdev->dev, "invalid bootstrap options\n"); return -ENODEV; } ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL); if (!ltq_mtd) return -ENOMEM; platform_set_drvdata(pdev, ltq_mtd); ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!ltq_mtd->res) { dev_err(&pdev->dev, "failed to get memory resource\n"); return -ENOENT; } ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info), GFP_KERNEL); if (!ltq_mtd->map) return -ENOMEM; ltq_mtd->map->phys = ltq_mtd->res->start; ltq_mtd->map->size = resource_size(ltq_mtd->res); ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res); if (IS_ERR(ltq_mtd->map->virt)) return PTR_ERR(ltq_mtd->map->virt); ltq_mtd->map->name = ltq_map_name; ltq_mtd->map->bankwidth = 2; ltq_mtd->map->read = ltq_read16; ltq_mtd->map->write = ltq_write16; ltq_mtd->map->copy_from = ltq_copy_from; ltq_mtd->map->copy_to = ltq_copy_to; ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING; ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map); ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL; if (!ltq_mtd->mtd) { dev_err(&pdev->dev, "probing failed\n"); return -ENXIO; } ltq_mtd->mtd->owner = THIS_MODULE; cfi = ltq_mtd->map->fldrv_priv; cfi->addr_unlock1 ^= 1; cfi->addr_unlock2 ^= 1; ppdata.of_node = pdev->dev.of_node; err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, &ppdata, NULL, 0); if (err) { dev_err(&pdev->dev, "failed to add partitions\n"); goto err_destroy; } return 0; err_destroy: map_destroy(ltq_mtd->mtd); return err; }
static int tmio_probe(struct platform_device *dev) { struct tmio_nand_data *data = dev_get_platdata(&dev->dev); struct resource *fcr = platform_get_resource(dev, IORESOURCE_MEM, 0); struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); int irq = platform_get_irq(dev, 0); struct tmio_nand *tmio; struct mtd_info *mtd; struct nand_chip *nand_chip; int retval; if (data == NULL) dev_warn(&dev->dev, "NULL platform data!\n"); tmio = kzalloc(sizeof *tmio, GFP_KERNEL); if (!tmio) { retval = -ENOMEM; goto err_kzalloc; } tmio->dev = dev; platform_set_drvdata(dev, tmio); mtd = &tmio->mtd; nand_chip = &tmio->chip; mtd->priv = nand_chip; mtd->name = "tmio-nand"; tmio->ccr = ioremap(ccr->start, resource_size(ccr)); if (!tmio->ccr) { retval = -EIO; goto err_iomap_ccr; } tmio->fcr_base = fcr->start & 0xfffff; tmio->fcr = ioremap(fcr->start, resource_size(fcr)); if (!tmio->fcr) { retval = -EIO; goto err_iomap_fcr; } retval = tmio_hw_init(dev, tmio); if (retval) goto err_hwinit; /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = tmio->fcr; nand_chip->IO_ADDR_W = tmio->fcr; /* Set address of hardware control function */ nand_chip->cmd_ctrl = tmio_nand_hwcontrol; nand_chip->dev_ready = tmio_nand_dev_ready; nand_chip->read_byte = tmio_nand_read_byte; nand_chip->write_buf = tmio_nand_write_buf; nand_chip->read_buf = tmio_nand_read_buf; /* set eccmode using hardware ECC */ nand_chip->ecc.mode = NAND_ECC_HW; nand_chip->ecc.size = 512; nand_chip->ecc.bytes = 6; nand_chip->ecc.strength = 2; nand_chip->ecc.hwctl = tmio_nand_enable_hwecc; nand_chip->ecc.calculate = tmio_nand_calculate_ecc; nand_chip->ecc.correct = tmio_nand_correct_data; if (data) nand_chip->badblock_pattern = data->badblock_pattern; /* 15 us command delay time */ nand_chip->chip_delay = 15; retval = request_irq(irq, &tmio_irq, IRQF_DISABLED, dev_name(&dev->dev), tmio); if (retval) { dev_err(&dev->dev, "request_irq error %d\n", retval); goto err_irq; } tmio->irq = irq; nand_chip->waitfunc = tmio_nand_wait; /* Scan to find existence of the device */ if (nand_scan(mtd, 1)) { retval = -ENODEV; goto err_scan; } /* Register the partitions */ retval = mtd_device_parse_register(mtd, NULL, NULL, data ? data->partition : NULL, data ? data->num_partitions : 0); if (!retval) return retval; nand_release(mtd); err_scan: if (tmio->irq) free_irq(tmio->irq, tmio); err_irq: tmio_hw_stop(dev, tmio); err_hwinit: iounmap(tmio->fcr); err_iomap_fcr: iounmap(tmio->ccr); err_iomap_ccr: kfree(tmio); err_kzalloc: return retval; }
static int __init txx9ndfmc_probe(struct platform_device *dev) { struct txx9ndfmc_platform_data *plat = dev->dev.platform_data; int hold, spw; int i; struct txx9ndfmc_drvdata *drvdata; unsigned long gbusclk = plat->gbus_clock; struct resource *res; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; drvdata->base = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(drvdata->base)) return PTR_ERR(drvdata->base); hold = plat->hold ?: 20; /* tDH */ spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */ hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold); spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw); if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD) hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */ spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */ hold = clamp(hold, 1, 15); drvdata->hold = hold; spw = clamp(spw, 1, 15); drvdata->spw = spw; dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n", (gbusclk + 500000) / 1000000, hold, spw); spin_lock_init(&drvdata->hw_control.lock); init_waitqueue_head(&drvdata->hw_control.wq); platform_set_drvdata(dev, drvdata); txx9ndfmc_initialize(dev); for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) { struct txx9ndfmc_priv *txx9_priv; struct nand_chip *chip; struct mtd_info *mtd; if (!(plat->ch_mask & (1 << i))) continue; txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv), GFP_KERNEL); if (!txx9_priv) { dev_err(&dev->dev, "Unable to allocate " "TXx9 NDFMC MTD device structure.\n"); continue; } chip = &txx9_priv->chip; mtd = &txx9_priv->mtd; mtd->owner = THIS_MODULE; mtd->priv = chip; chip->read_byte = txx9ndfmc_read_byte; chip->read_buf = txx9ndfmc_read_buf; chip->write_buf = txx9ndfmc_write_buf; chip->cmd_ctrl = txx9ndfmc_cmd_ctrl; chip->dev_ready = txx9ndfmc_dev_ready; chip->ecc.calculate = txx9ndfmc_calculate_ecc; chip->ecc.correct = txx9ndfmc_correct_data; chip->ecc.hwctl = txx9ndfmc_enable_hwecc; chip->ecc.mode = NAND_ECC_HW; /* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */ chip->ecc.size = 256; chip->ecc.bytes = 3; chip->ecc.strength = 1; chip->chip_delay = 100; chip->controller = &drvdata->hw_control; chip->priv = txx9_priv; txx9_priv->dev = dev; if (plat->ch_mask != 1) { txx9_priv->cs = i; txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u", dev_name(&dev->dev), i); } else { txx9_priv->cs = -1; txx9_priv->mtdname = kstrdup(dev_name(&dev->dev), GFP_KERNEL); } if (!txx9_priv->mtdname) { kfree(txx9_priv); dev_err(&dev->dev, "Unable to allocate MTD name.\n"); continue; } if (plat->wide_mask & (1 << i)) chip->options |= NAND_BUSWIDTH_16; if (txx9ndfmc_nand_scan(mtd)) { kfree(txx9_priv->mtdname); kfree(txx9_priv); continue; } mtd->name = txx9_priv->mtdname; mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); drvdata->mtds[i] = mtd; } return 0; }
/* * Probe for NAND controller */ static int lpc32xx_nand_probe(struct platform_device *pdev) { struct lpc32xx_nand_host *host; struct mtd_info *mtd; struct nand_chip *chip; struct resource *rc; struct mtd_part_parser_data ppdata = {}; int res; rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (rc == NULL) { dev_err(&pdev->dev, "No memory resource found for device\n"); return -EBUSY; } /* Allocate memory for the device structure (and zero it) */ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); if (!host) return -ENOMEM; host->io_base_dma = rc->start; host->io_base = devm_ioremap_resource(&pdev->dev, rc); if (IS_ERR(host->io_base)) return PTR_ERR(host->io_base); if (pdev->dev.of_node) host->ncfg = lpc32xx_parse_dt(&pdev->dev); if (!host->ncfg) { dev_err(&pdev->dev, "Missing or bad NAND config from device tree\n"); return -ENOENT; } if (host->ncfg->wp_gpio == -EPROBE_DEFER) return -EPROBE_DEFER; if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev, host->ncfg->wp_gpio, "NAND WP")) { dev_err(&pdev->dev, "GPIO not available\n"); return -EBUSY; } lpc32xx_wp_disable(host); host->pdata = dev_get_platdata(&pdev->dev); mtd = &host->mtd; chip = &host->nand_chip; chip->priv = host; mtd->priv = chip; mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; /* Get NAND clock */ host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { dev_err(&pdev->dev, "Clock failure\n"); res = -ENOENT; goto err_exit1; } clk_enable(host->clk); /* Set NAND IO addresses and command/ready functions */ chip->IO_ADDR_R = SLC_DATA(host->io_base); chip->IO_ADDR_W = SLC_DATA(host->io_base); chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; chip->dev_ready = lpc32xx_nand_device_ready; chip->chip_delay = 20; /* 20us command delay time */ /* Init NAND controller */ lpc32xx_nand_setup(host); platform_set_drvdata(pdev, host); /* NAND callbacks for LPC32xx SLC hardware */ chip->ecc.mode = NAND_ECC_HW_SYNDROME; chip->read_byte = lpc32xx_nand_read_byte; chip->read_buf = lpc32xx_nand_read_buf; chip->write_buf = lpc32xx_nand_write_buf; chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome; chip->ecc.read_page = lpc32xx_nand_read_page_syndrome; chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome; chip->ecc.write_page = lpc32xx_nand_write_page_syndrome; chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome; chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome; chip->ecc.calculate = lpc32xx_nand_ecc_calculate; chip->ecc.correct = nand_correct_data; chip->ecc.strength = 1; chip->ecc.hwctl = lpc32xx_nand_ecc_enable; /* * Allocate a large enough buffer for a single huge page plus * extra space for the spare area and ECC storage area */ host->dma_buf_len = LPC32XX_DMA_DATA_SIZE + LPC32XX_ECC_SAVE_SIZE; host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len, GFP_KERNEL); if (host->data_buf == NULL) { res = -ENOMEM; goto err_exit2; } res = lpc32xx_nand_dma_setup(host); if (res) { res = -EIO; goto err_exit2; } /* Find NAND device */ if (nand_scan_ident(mtd, 1, NULL)) { res = -ENXIO; goto err_exit3; } /* OOB and ECC CPU and DMA work areas */ host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); /* * Small page FLASH has a unique OOB layout, but large and huge * page FLASH use the standard layout. Small page FLASH uses a * custom BBT marker layout. */ if (mtd->writesize <= 512) chip->ecc.layout = &lpc32xx_nand_oob_16; /* These sizes remain the same regardless of page size */ chip->ecc.size = 256; chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES; chip->ecc.prepad = chip->ecc.postpad = 0; /* Avoid extra scan if using BBT, setup BBT support */ if (host->ncfg->use_bbt) { chip->bbt_options |= NAND_BBT_USE_FLASH; /* * Use a custom BBT marker setup for small page FLASH that * won't interfere with the ECC layout. Large and huge page * FLASH use the standard layout. */ if (mtd->writesize <= 512) { chip->bbt_td = &bbt_smallpage_main_descr; chip->bbt_md = &bbt_smallpage_mirror_descr; } } /* * Fills out all the uninitialized function pointers with the defaults */ if (nand_scan_tail(mtd)) { res = -ENXIO; goto err_exit3; } mtd->name = "nxp_lpc3220_slc"; ppdata.of_node = pdev->dev.of_node; res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts, host->ncfg->num_parts); if (!res) return res; nand_release(mtd); err_exit3: dma_release_channel(host->dma_chan); err_exit2: clk_disable(host->clk); err_exit1: lpc32xx_wp_enable(host); return res; }
static int latch_addr_flash_probe(struct platform_device *dev) { struct latch_addr_flash_data *latch_addr_data; struct latch_addr_flash_info *info; resource_size_t win_base = dev->resource->start; resource_size_t win_size = resource_size(dev->resource); char **probe_type; int chipsel; int err; latch_addr_data = dev->dev.platform_data; if (latch_addr_data == NULL) return -ENODEV; pr_notice("latch-addr platform flash device: %#llx byte " "window at %#.8llx\n", (unsigned long long)win_size, (unsigned long long)win_base); chipsel = dev->id; if (latch_addr_data->init) { err = latch_addr_data->init(latch_addr_data->data, chipsel); if (err != 0) return err; } info = kzalloc(sizeof(struct latch_addr_flash_info), GFP_KERNEL); if (info == NULL) { err = -ENOMEM; goto done; } platform_set_drvdata(dev, info); info->res = request_mem_region(win_base, win_size, DRIVER_NAME); if (info->res == NULL) { dev_err(&dev->dev, "Could not reserve memory region\n"); err = -EBUSY; goto free_info; } info->map.name = DRIVER_NAME; info->map.size = latch_addr_data->size; info->map.bankwidth = latch_addr_data->width; info->map.phys = NO_XIP; info->map.virt = ioremap(win_base, win_size); if (!info->map.virt) { err = -ENOMEM; goto free_res; } info->map.map_priv_1 = (unsigned long)info; info->map.read = lf_read; info->map.copy_from = lf_copy_from; info->map.write = lf_write; info->set_window = latch_addr_data->set_window; info->data = latch_addr_data->data; info->win_mask = win_size - 1; spin_lock_init(&info->lock); for (probe_type = rom_probe_types; !info->mtd && *probe_type; probe_type++) info->mtd = do_map_probe(*probe_type, &info->map); if (info->mtd == NULL) { dev_err(&dev->dev, "map_probe failed\n"); err = -ENODEV; goto iounmap; } info->mtd->owner = THIS_MODULE; mtd_device_parse_register(info->mtd, NULL, NULL, latch_addr_data->parts, latch_addr_data->nr_parts); return 0; iounmap: iounmap(info->map.virt); free_res: release_mem_region(info->res->start, resource_size(info->res)); free_info: kfree(info); done: if (latch_addr_data->done) latch_addr_data->done(latch_addr_data->data); return err; }
static int __devinit gpio_flash_probe(struct platform_device *pdev) { size_t i, arr_size; struct physmap_flash_data *pdata; struct resource *memory; struct resource *gpios; struct async_state *state; pdata = pdev->dev.platform_data; memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); gpios = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!memory || !gpios || !gpios->end) return -EINVAL; arr_size = sizeof(int) * gpios->end; state = kzalloc(sizeof(*state) + arr_size, GFP_KERNEL); if (!state) return -ENOMEM; state->gpio_count = gpios->end; state->gpio_addrs = (void *)(unsigned long)gpios->start; state->gpio_values = (void *)(state + 1); state->win_size = resource_size(memory); memset(state->gpio_values, 0xff, arr_size); state->map.name = DRIVER_NAME; state->map.read = gf_read; state->map.copy_from = gf_copy_from; state->map.write = gf_write; state->map.copy_to = gf_copy_to; state->map.bankwidth = pdata->width; state->map.size = state->win_size * (1 << state->gpio_count); state->map.virt = ioremap_nocache(memory->start, state->map.size); state->map.phys = NO_XIP; state->map.map_priv_1 = (unsigned long)state; platform_set_drvdata(pdev, state); i = 0; do { if (gpio_request(state->gpio_addrs[i], DRIVER_NAME)) { pr_devinit(KERN_ERR PFX "failed to request gpio %d\n", state->gpio_addrs[i]); while (i--) gpio_free(state->gpio_addrs[i]); kfree(state); return -EBUSY; } gpio_direction_output(state->gpio_addrs[i], 0); } while (++i < state->gpio_count); pr_devinit(KERN_NOTICE PFX "probing %d-bit flash bus\n", state->map.bankwidth * 8); state->mtd = do_map_probe(memory->name, &state->map); if (!state->mtd) { for (i = 0; i < state->gpio_count; ++i) gpio_free(state->gpio_addrs[i]); kfree(state); return -ENXIO; } mtd_device_parse_register(state->mtd, part_probe_types, NULL, pdata->parts, pdata->nr_parts); return 0; }
static int ixp4xx_flash_probe(struct platform_device *dev) { struct flash_platform_data *plat = dev->dev.platform_data; struct ixp4xx_flash_info *info; int err = -1; if (!plat) return -ENODEV; if (plat->init) { err = plat->init(); if (err) return err; } info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL); if(!info) { err = -ENOMEM; goto Error; } 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 = resource_size(dev->resource); /* * We only support 16-bit accesses for now. If and when * any board use 8-bit access, we'll fixup the driver to * handle that. */ info->map.bankwidth = 2; info->map.name = dev_name(&dev->dev); info->map.read = ixp4xx_read16; info->map.write = ixp4xx_probe_write16; info->map.copy_from = ixp4xx_copy_from; info->res = request_mem_region(dev->resource->start, resource_size(dev->resource), "IXP4XXFlash"); if (!info->res) { printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); err = -ENOMEM; goto Error; } info->map.virt = ioremap(dev->resource->start, resource_size(dev->resource)); if (!info->map.virt) { printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); err = -EIO; goto Error; } info->mtd = do_map_probe(plat->map_name, &info->map); if (!info->mtd) { printk(KERN_ERR "IXP4XXFlash: map_probe failed\n"); err = -ENXIO; goto Error; } info->mtd->owner = THIS_MODULE; /* Use the fast version */ info->map.write = ixp4xx_write16; err = mtd_device_parse_register(info->mtd, probes, dev->resource->start, plat->parts, plat->nr_parts); if (err) { printk(KERN_ERR "Could not parse partitions\n"); goto Error; } return 0; Error: ixp4xx_flash_remove(dev); return err; }
static int omap2_onenand_probe(struct platform_device *pdev) { struct omap_onenand_platform_data *pdata; struct omap2_onenand *c; struct onenand_chip *this; int r; struct resource *res; struct mtd_part_parser_data ppdata = {}; pdata = dev_get_platdata(&pdev->dev); if (pdata == NULL) { dev_err(&pdev->dev, "platform data missing\n"); return -ENODEV; } c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL); if (!c) return -ENOMEM; init_completion(&c->irq_done); init_completion(&c->dma_done); c->flags = pdata->flags; c->gpmc_cs = pdata->cs; c->gpio_irq = pdata->gpio_irq; c->dma_channel = pdata->dma_channel; if (c->dma_channel < 0) { /* if -1, don't use DMA */ c->gpio_irq = 0; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { r = -EINVAL; dev_err(&pdev->dev, "error getting memory resource\n"); goto err_kfree; } c->phys_base = res->start; c->mem_size = resource_size(res); if (request_mem_region(c->phys_base, c->mem_size, pdev->dev.driver->name) == NULL) { dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n", c->phys_base, c->mem_size); r = -EBUSY; goto err_kfree; } c->onenand.base = ioremap(c->phys_base, c->mem_size); if (c->onenand.base == NULL) { r = -ENOMEM; goto err_release_mem_region; } if (pdata->onenand_setup != NULL) { r = pdata->onenand_setup(c->onenand.base, &c->freq); if (r < 0) { dev_err(&pdev->dev, "Onenand platform setup failed: " "%d\n", r); goto err_iounmap; } c->setup = pdata->onenand_setup; } if (c->gpio_irq) { if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) { dev_err(&pdev->dev, "Failed to request GPIO%d for " "OneNAND\n", c->gpio_irq); goto err_iounmap; } gpio_direction_input(c->gpio_irq); if ((r = request_irq(gpio_to_irq(c->gpio_irq), omap2_onenand_interrupt, IRQF_TRIGGER_RISING, pdev->dev.driver->name, c)) < 0) goto err_release_gpio; } if (c->dma_channel >= 0) { r = omap_request_dma(0, pdev->dev.driver->name, omap2_onenand_dma_cb, (void *) c, &c->dma_channel); if (r == 0) { omap_set_dma_write_mode(c->dma_channel, OMAP_DMA_WRITE_NON_POSTED); omap_set_dma_src_data_pack(c->dma_channel, 1); omap_set_dma_src_burst_mode(c->dma_channel, OMAP_DMA_DATA_BURST_8); omap_set_dma_dest_data_pack(c->dma_channel, 1); omap_set_dma_dest_burst_mode(c->dma_channel, OMAP_DMA_DATA_BURST_8); } else { dev_info(&pdev->dev, "failed to allocate DMA for OneNAND, " "using PIO instead\n"); c->dma_channel = -1; } } dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base, c->onenand.base, c->freq); c->pdev = pdev; c->mtd.name = dev_name(&pdev->dev); c->mtd.priv = &c->onenand; c->mtd.owner = THIS_MODULE; c->mtd.dev.parent = &pdev->dev; this = &c->onenand; if (c->dma_channel >= 0) { this->wait = omap2_onenand_wait; if (c->flags & ONENAND_IN_OMAP34XX) { this->read_bufferram = omap3_onenand_read_bufferram; this->write_bufferram = omap3_onenand_write_bufferram; } else { this->read_bufferram = omap2_onenand_read_bufferram; this->write_bufferram = omap2_onenand_write_bufferram; } } if (pdata->regulator_can_sleep) { c->regulator = regulator_get(&pdev->dev, "vonenand"); if (IS_ERR(c->regulator)) { dev_err(&pdev->dev, "Failed to get regulator\n"); r = PTR_ERR(c->regulator); goto err_release_dma; } c->onenand.enable = omap2_onenand_enable; c->onenand.disable = omap2_onenand_disable; } if (pdata->skip_initial_unlocking) this->options |= ONENAND_SKIP_INITIAL_UNLOCKING; if ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_regulator; ppdata.of_node = pdata->of_node; r = mtd_device_parse_register(&c->mtd, NULL, &ppdata, pdata ? pdata->parts : NULL, pdata ? pdata->nr_parts : 0); if (r) goto err_release_onenand; platform_set_drvdata(pdev, c); return 0; err_release_onenand: onenand_release(&c->mtd); err_release_regulator: regulator_put(c->regulator); err_release_dma: if (c->dma_channel != -1) omap_free_dma(c->dma_channel); if (c->gpio_irq) free_irq(gpio_to_irq(c->gpio_irq), c); err_release_gpio: if (c->gpio_irq) gpio_free(c->gpio_irq); err_iounmap: iounmap(c->onenand.base); err_release_mem_region: release_mem_region(c->phys_base, c->mem_size); err_kfree: kfree(c); return r; }
static int __init init_sbc82xx_flash(void) { volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; int bigflash; int i; #ifdef CONFIG_SBC8560 mc = ioremap(0xff700000 + 0x5000, sizeof(memctl_cpm2_t)); #else mc = &cpm2_immr->im_memctl; #endif bigflash = 1; if ((mc->memc_br0 & 0x00001800) == 0x00001800) bigflash = 0; init_sbc82xx_one_flash(sbc82xx_flash_map[0], mc->memc_br0, mc->memc_or0); init_sbc82xx_one_flash(sbc82xx_flash_map[1], mc->memc_br6, mc->memc_or6); init_sbc82xx_one_flash(sbc82xx_flash_map[2], mc->memc_br1, mc->memc_or1); #ifdef CONFIG_SBC8560 iounmap((void *) mc); #endif for (i=0; i<3; i++) { int8_t flashcs[3] = { 0, 6, 1 }; int nr_parts; struct mtd_partition *defparts; printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d", sbc82xx_flash_map[i].name, (sbc82xx_flash_map[i].size >> 20), flashcs[i]); if (!sbc82xx_flash_map[i].phys) { /* We know it can't be at zero. */ printk("): disabled by bootloader.\n"); continue; } printk(" at %08lx)\n", sbc82xx_flash_map[i].phys); sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size); if (!sbc82xx_flash_map[i].virt) { printk("Failed to ioremap\n"); continue; } simple_map_init(&sbc82xx_flash_map[i]); sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]); if (!sbcmtd[i]) continue; sbcmtd[i]->owner = THIS_MODULE; /* No partitioning detected. Use default */ if (i == 2) { defparts = NULL; nr_parts = 0; } else if (i == bigflash) { defparts = bigflash_parts; nr_parts = ARRAY_SIZE(bigflash_parts); } else { defparts = smallflash_parts; nr_parts = ARRAY_SIZE(smallflash_parts); } mtd_device_parse_register(sbcmtd[i], part_probes, NULL, defparts, nr_parts); } return 0; }
static int nand_probe(struct platform_device *pdev) { struct nxp_nand_plat_data *pdata = dev_get_platdata(&pdev->dev); struct nxp_nand *nxp; struct mtd_info *mtd; struct nand_chip *chip; int maxchips = CONFIG_SYS_NAND_MAX_CHIPS; int chip_delay = !pdata ? 15 : (pdata->chip_delay ? pdata->chip_delay : 15); #ifdef CFG_NAND_ECCIRQ_MODE int irq = 0; /* platform_get_irq(pdev, 0); */ #endif int ret = 0; if (pdata == NULL) dev_warn(&pdev->dev, "NULL platform data!\n"); nxp = kzalloc(sizeof (*nxp), GFP_KERNEL); if (!nxp) { printk(KERN_ERR "NAND: failed to allocate device structure.\n"); ret = -ENOMEM; goto err_kzalloc; } nxp->pdev = pdev; platform_set_drvdata(pdev, nxp); mtd = &nxp->mtd; chip = &nxp->chip; mtd->priv = chip; mtd->name = DEV_NAME_NAND; mtd->owner = THIS_MODULE; nand_dev_init(mtd); /* insert callbacks */ chip->IO_ADDR_R = (void __iomem *)__PB_IO_MAP_NAND_VIRT; chip->IO_ADDR_W = (void __iomem *)__PB_IO_MAP_NAND_VIRT; chip->cmd_ctrl = nand_cmd_ctrl; chip->dev_ready = nand_dev_ready; chip->select_chip = nand_select_chip; chip->chip_delay = chip_delay; // chip->read_buf = nand_read_buf; // chip->write_buf = nand_write_buf; #if defined (CONFIG_MTD_NAND_ECC_BCH) // chip->write_page = nand_bch_write_page; #endif #if defined (CONFIG_MTD_NAND_ECC_HW) ret = nand_hw_ecc_init_device(mtd); printk(KERN_INFO "NAND ecc: Hardware (delay %d)\n", chip_delay); #elif defined (CONFIG_MTD_NAND_ECC_BCH) chip->ecc.mode = NAND_ECC_SOFT_BCH; /* refer to nand_ecc.c */ switch (ECC_BCH_BITS) { case 4: chip->ecc.bytes = 7; chip->ecc.size = 512; break; case 8: chip->ecc.bytes = 13; chip->ecc.size = 512; break; case 12: chip->ecc.bytes = 20; chip->ecc.size = 512; break; case 16: chip->ecc.bytes = 26; chip->ecc.size = 512; break; case 24: chip->ecc.bytes = 42; chip->ecc.size = 1024; break; case 40: chip->ecc.bytes = 70; chip->ecc.size = 1024; break; // case 60: chip->ecc.bytes = 105; chip->ecc.size = 1024; break; /* not test */ default: printk("Fail: not supoort bch ecc %d mode !!!\n", ECC_BCH_BITS); ret = -1; goto err_something; } printk(KERN_INFO "NAND ecc: Software BCH (delay %d)\n", chip_delay); #else chip->ecc.mode = NAND_ECC_SOFT; printk(KERN_INFO "NAND ecc: Software (delay %d)\n", chip_delay); #endif printk(KERN_NOTICE "Scanning NAND device ...\n"); if (nand_scan(mtd, maxchips)) { ret = -ENXIO; goto err_something; } if (nand_ecc_layout_check(mtd)){ ret = -ENXIO; goto err_something; } #ifdef CFG_NAND_ECCIRQ_MODE ret = request_irq(irq, nxp_irq, 0, DEV_NAME_NAND, nxp); if (ret < 0) { pr_err("%s: failed to request_irq(%d)\n", __func__, 0); ret = -ENODEV; goto err_something; } nxp->irq = irq; #endif /* set command partition */ ret = mtd_device_parse_register(mtd, NULL, 0, pdata->parts, pdata->nr_parts); if (ret) { nand_release(mtd); goto err_something; } else { // platform_set_drvdata(pdev, chip); } #ifdef CONFIG_NAND_RANDOMIZER nxp->pages_per_block_mask = (mtd->erasesize/mtd->writesize) - 1; if (!nxp->randomize_buf) nxp->randomize_buf = kzalloc(mtd->writesize, GFP_KERNEL); if (!nxp->randomize_buf) { ERROUT("randomize buffer alloc failed\n"); goto err_something; } #endif #ifdef CONFIG_MTD_NAND_VERIFY_WRITE if (!nxp->verify_page) nxp->verify_page = kzalloc(NAND_MAX_PAGESIZE, GFP_KERNEL); if (!nxp->verify_page) { ERROUT("verify buffer alloc failed\n"); goto err_something; } #endif nxp_nand_timing_set(mtd); printk(KERN_NOTICE "%s: Nand partition \n", ret?"FAIL":"DONE"); return ret; err_something: #ifdef CONFIG_NAND_RANDOMIZER if (nxp->randomize_buf) kfree (nxp->randomize_buf); #endif #ifdef CONFIG_MTD_NAND_VERIFY_WRITE if (nxp->verify_page) kfree (nxp->verify_page); #endif kfree(nxp); err_kzalloc: return ret; }