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; 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; nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes, &sbcmtd_parts[i], 0); if (nr_parts > 0) { add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts); continue; } /* No partitioning detected. Use default */ if (i == 2) { add_mtd_device(sbcmtd[i]); } else if (i == bigflash) { add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts)); } else { add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts)); } } 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->nr_banks = ixp_data->nr_banks; 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; }
/* * Main initialization routine */ int __init autcpu12_init (void) { struct nand_chip *this; int err = 0; /* Allocate memory for MTD device structure and private data */ autcpu12_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL); if (!autcpu12_mtd) { printk ("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); err = -ENOMEM; goto out; } /* map physical adress */ autcpu12_fio_base = ioremap(autcpu12_fio_pbase,SZ_1K); if(!autcpu12_fio_base){ printk("Ioremap autcpu12 SmartMedia Card failed\n"); err = -EIO; goto out_mtd; } /* Get pointer to private data */ this = (struct nand_chip *) (&autcpu12_mtd[1]); /* Initialize structures */ memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info)); memset((char *) this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ autcpu12_mtd->priv = this; /* Set address of NAND IO lines */ this->IO_ADDR_R = autcpu12_fio_base; this->IO_ADDR_W = autcpu12_fio_base; this->hwcontrol = autcpu12_hwcontrol; this->dev_ready = autcpu12_device_ready; /* 20 us command delay time */ this->chip_delay = 20; this->eccmode = NAND_ECC_SOFT; /* Enable the following for a flash based bad block table */ /* this->options = NAND_USE_FLASH_BBT; */ this->options = NAND_USE_FLASH_BBT; /* Scan to find existance of the device */ if (nand_scan (autcpu12_mtd, 1)) { err = -ENXIO; goto out_ior; } /* Register the partitions */ switch(autcpu12_mtd->size){ case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; default: { printk ("Unsupported SmartMedia device\n"); err = -ENXIO; goto out_ior; } } goto out; out_ior: iounmap((void *)autcpu12_fio_base); out_mtd: kfree (autcpu12_mtd); out: return err; }
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 = dev_name(&pdev->dev); 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; info->mtd->dev.parent = &pdev->dev; #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; }
int __init init_txmtd(void) { int i; struct mtd_info *mymtd = NULL; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *parts; int j; #endif /* tx4938_desc[] is initialized by early_txmtd_setup() */ /* Initialize mapping */ for (i=0;i<PHYSMAP_NUMBER;i++) { if (!tx4938_desc[i].name) continue; printk(KERN_DEBUG "tx4938 flash device: probe %lx at %lx\n", tx4938_desc[i].window_size, tx4938_desc[i].window_addr); printk("tx4938 flash device: probe %lx at %lx\n", tx4938_desc[i].window_size, tx4938_desc[i].window_addr); tx4938_maps[i].phys = tx4938_desc[i].window_addr; tx4938_maps[i].virt = (unsigned long)ioremap(tx4938_desc[i].window_addr, tx4938_desc[i].window_size); if (!tx4938_maps[i].virt) { printk(KERN_WARNING "Failed to ioremap\n"); return -EIO; } tx4938_maps[i].name = tx4938_desc[i].name; tx4938_maps[i].size = tx4938_desc[i].window_size; tx4938_maps[i].buswidth = tx4938_desc[i].buswidth; simple_map_init(&tx4938_maps[i]); //printk(KERN_NOTICE "tx4938: ioremap is %x\n",(unsigned int)(tx4938_maps[i].virt)); } for (i=0;i<PHYSMAP_NUMBER;i++) { struct tx4938_info *txinfo = &tx4938_desc[i]; if (!tx4938_maps[i].name) continue; if (txinfo->drvname) { /* probe only specified chipdriver */ mymtd = (struct mtd_info *)do_map_probe(txinfo->drvname, &tx4938_maps[i]); } else { /* probe cfi then try jedec */ mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &tx4938_maps[i]); //printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd); if (!mymtd) { mymtd = (struct mtd_info *)do_map_probe("jedec_probe", &tx4938_maps[i]); //printk(KERN_NOTICE "tx4938 %d jedec: mymtd is %x\n",i,(unsigned int)mymtd); } } if (!mymtd) continue; mymtd->owner = THIS_MODULE; /* true map size */ tx4938_maps[i].size = mymtd->size; /* If this window contains boot vector, adjust the map area. * 1f000000-1f3fffff to 1fc00000-1fffffff, * 1f000000-1f7fffff to 1f800000-1fffffff, etc. */ if (txinfo->window_addr <= 0x1fc00000 && txinfo->window_addr + txinfo->window_size > 0x1fc00000) { txinfo->window_addr = 0x1fc00000 / tx4938_maps[i].size * tx4938_maps[i].size; iounmap((void *)tx4938_maps[i].virt); tx4938_maps[i].virt = (unsigned long)ioremap(txinfo->window_addr, tx4938_maps[i].size); } printk(KERN_NOTICE "tx4938 flash device(%s): %lx at %lx\n", tx4938_maps[i].name, tx4938_maps[i].size, txinfo->window_addr); txinfo->mtd_info = mymtd; tx4938_maps[i].map_priv_2 = 1; /* mark invalidate */ #ifdef CONFIG_MTD_PARTITIONS parts = &txinfo->partitions[0]; if (txinfo->num_partitions == 0) { /* initialize txinfo->partitions[] */ if (txinfo->window_addr < 0x1fc00000 && txinfo->window_addr + mymtd->size > 0x1fc00000) { /* split boot mtd device */ parts[0].offset = 0x1fc00000 - txinfo->window_addr; parts[0].size = txinfo->window_addr + mymtd->size - 0x1fc00000; parts[1].offset = 0; parts[1].size = 0x1fc00000 - txinfo->window_addr; txinfo->num_partitions = 2; } else { //parts->size = mymtd->size; parts->size = txinfo->window_size; txinfo->num_partitions = 1; } } for (j = 0; j < txinfo->num_partitions; j++) { int isboot = (txinfo->window_addr + parts[j].offset == 0x1fc00000); char buf[128]; if (parts[j].name) strcpy(buf, parts[j].name); else if (txinfo->num_partitions == 1) strcpy(buf, mymtd->name); else sprintf(buf, "%s (part%d)", mymtd->name, j); if (isboot) strcat(buf, " (boot)"); txinfo->part_names[j] = kmalloc(strlen(buf) + 1, GFP_KERNEL); if (txinfo->part_names[j]) { strcpy(txinfo->part_names[j], buf); parts[j].name = txinfo->part_names[j]; } else { parts[j].name = mymtd->name; } } add_mtd_partitions(mymtd, parts, txinfo->num_partitions); #else add_mtd_device(mymtd); #endif } if (!mymtd) return -ENXIO; return 0; }
/* * Main initialization routine */ int __init toto_init (void) { struct nand_chip *this; int err = 0; /* Allocate memory for MTD device structure and private data */ toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL); if (!toto_mtd) { printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n"); err = -ENOMEM; goto out; } /* Get pointer to private data */ this = (struct nand_chip *) (&toto_mtd[1]); /* Initialize structures */ memset((char *) toto_mtd, 0, sizeof(struct mtd_info)); memset((char *) this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ toto_mtd->priv = this; /* Set address of NAND IO lines */ this->IO_ADDR_R = toto_io_base; this->IO_ADDR_W = toto_io_base; this->hwcontrol = toto_hwcontrol; this->dev_ready = NULL; /* 25 us command delay time */ this->chip_delay = 30; this->eccmode = NAND_ECC_SOFT; /* Scan to find existance of the device */ if (nand_scan (toto_mtd, 1)) { err = -ENXIO; goto out_mtd; } /* Register the partitions */ switch(toto_mtd->size){ case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; default: { printk (KERN_WARNING "Unsupported Nand device\n"); err = -ENXIO; goto out_buf; } } gpioreserve(NAND_MASK); /* claim our gpios */ archflashwp(0,0); /* open up flash for writing */ goto out; out_buf: kfree (this->data_buf); out_mtd: kfree (toto_mtd); out: return err; }
static int __devinit omap2_onenand_probe(struct platform_device *pdev) { struct omap_onenand_platform_data *pdata; struct omap2_onenand *c; int r; pdata = pdev->dev.platform_data; 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->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; } r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base); if (r < 0) { dev_err(&pdev->dev, "Cannot request GPMC CS\n"); goto err_kfree; } if (request_mem_region(c->phys_base, ONENAND_IO_SIZE, pdev->dev.driver->name) == NULL) { dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, " "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE); r = -EBUSY; goto err_free_cs; } c->onenand.base = ioremap(c->phys_base, ONENAND_IO_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\n", c->gpmc_cs, c->phys_base, c->onenand.base); c->pdev = pdev; c->mtd.name = pdev->dev.bus_id; c->mtd.priv = &c->onenand; c->mtd.owner = THIS_MODULE; if (c->dma_channel >= 0) { struct onenand_chip *this = &c->onenand; this->wait = omap2_onenand_wait; if (cpu_is_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 ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_dma; switch ((c->onenand.version_id >> 4) & 0xf) { case 0: c->freq = 40; break; case 1: c->freq = 54; break; case 2: c->freq = 66; break; case 3: c->freq = 83; break; } #ifdef CONFIG_MTD_PARTITIONS if (pdata->parts != NULL) r = add_mtd_partitions(&c->mtd, pdata->parts, pdata->nr_parts); else #endif r = add_mtd_device(&c->mtd); if (r < 0) goto err_release_onenand; platform_set_drvdata(pdev, c); return 0; err_release_onenand: onenand_release(&c->mtd); 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, ONENAND_IO_SIZE); err_free_cs: gpmc_cs_free(c->gpmc_cs); err_kfree: kfree(c); return r; }
static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) { struct device_node *dp = dev->node; struct resource res; struct physmap_flash_info *info; const char **probe_type; const char *of_probe; const u32 *width; int err; if (of_address_to_resource(dp, 0, &res)) { dev_err(&dev->dev, "Can't get the flash mapping!\n"); err = -EINVAL; goto err_out; } dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n", (unsigned long long)res.end - res.start + 1, (unsigned long long)res.start); info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); if (info == NULL) { err = -ENOMEM; goto err_out; } memset(info, 0, sizeof(*info)); dev_set_drvdata(&dev->dev, info); info->res = request_mem_region(res.start, res.end - res.start + 1, dev->dev.bus_id); if (info->res == NULL) { dev_err(&dev->dev, "Could not reserve memory region\n"); err = -ENOMEM; goto err_out; } width = get_property(dp, "bank-width", NULL); if (width == NULL) { dev_err(&dev->dev, "Can't get the flash bank width!\n"); err = -EINVAL; goto err_out; } info->map.name = dev->dev.bus_id; info->map.phys = res.start; info->map.size = res.end - res.start + 1; info->map.bankwidth = *width; info->map.virt = ioremap(info->map.phys, info->map.size); if (info->map.virt == NULL) { dev_err(&dev->dev, "Failed to ioremap flash region\n"); err = EIO; goto err_out; } simple_map_init(&info->map); of_probe = get_property(dp, "probe-type", NULL); if (of_probe == NULL) { probe_type = rom_probe_types; for (; info->mtd == NULL && *probe_type != NULL; probe_type++) info->mtd = do_map_probe(*probe_type, &info->map); } else if (!strcmp(of_probe, "CFI")) info->mtd = do_map_probe("cfi_probe", &info->map); else if (!strcmp(of_probe, "JEDEC")) info->mtd = do_map_probe("jedec_probe", &info->map); else { if (strcmp(of_probe, "ROM")) dev_dbg(&dev->dev, "map_probe: don't know probe type " "'%s', mapping as rom\n"); info->mtd = do_map_probe("mtd_rom", &info->map); } if (info->mtd == NULL) { dev_err(&dev->dev, "map_probe failed\n"); err = -ENXIO; goto err_out; } info->mtd->owner = THIS_MODULE; #ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); if (err > 0) { add_mtd_partitions(info->mtd, info->parts, err); } else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) { dev_info(&dev->dev, "Using OF partition information\n"); add_mtd_partitions(info->mtd, info->parts, err); info->nr_parts = err; } else #endif add_mtd_device(info->mtd); return 0; err_out: of_physmap_remove(dev); return err; return 0; }
int __init lart_flash_init (void) { int result; memset (&mtd,0,sizeof (mtd)); printk ("MTD driver for LART. Written by Abraham vd Merwe <*****@*****.**>\n"); printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name); if (!flash_probe ()) { printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name); return (-ENXIO); } printk ("%s: This looks like a LART board to me.\n",module_name); mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; mtd.write = flash_write; mtd.owner = THIS_MODULE; #ifdef LART_DEBUG printk (KERN_DEBUG "mtd.name = %s\n" "mtd.size = 0x%.8x (%uM)\n" "mtd.erasesize = 0x%.8x (%uK)\n" "mtd.numeraseregions = %d\n", mtd.name, mtd.size,mtd.size / (1024*1024), mtd.erasesize,mtd.erasesize / 1024, mtd.numeraseregions); if (mtd.numeraseregions) for (result = 0; result < mtd.numeraseregions; result++) printk (KERN_DEBUG "\n\n" "mtd.eraseregions[%d].offset = 0x%.8x\n" "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n" "mtd.eraseregions[%d].numblocks = %d\n", result,mtd.eraseregions[result].offset, result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024, result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" "lart_partitions[%d].offset = 0x%.8x\n" "lart_partitions[%d].size = 0x%.8x (%uK)\n", result,lart_partitions[result].name, result,lart_partitions[result].offset, result,lart_partitions[result].size,lart_partitions[result].size / 1024); #endif #endif #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); #endif return (result); }
/** * Module/ driver initialization. * * Returns Zero on success */ static int __init flash_init(void) { switch(ctc_bd_info.flash_type) { case FLASH_TYPE_1: flash_map.size = 0x2000000; break; case FLASH_TYPE_2: flash_map.size = 0x2000000; break; case FLASH_TYPE_3: flash_map.size = 0x4000000; parts[1].size = 0x3f00000; break; case FLASH_TYPE_4: /*bug21815, support 3 parts for 256M flash*/ nr_parts = 3; flash_map.size = 0x10000000; parts[1].offset = 0x00100000; parts[1].size = 0x3f00000; parts[2].offset = 0x4000000; parts[2].size = 0xbb00000; break; default: printk("Unknow flash type parameters, use default."); flash_map.size = 0x2000000; break; } flash_map.name = "phys_mapped_flash"; /*bug21815. support 256M flash*/ if(ctc_bd_info.bootbus_updated) { flash_map.phys = GLB_FLASH_NEW_BASE; } else { flash_map.phys = GLB_FLASH_BASE; } flash_map.bankwidth = 2; 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 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"); } return 0; }
static int bcm963xx_probe(struct platform_device *pdev) { int err = 0; int parsed_nr_parts = 0; char *part_type; struct resource *r; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "no resource supplied\n"); return -ENODEV; } bcm963xx_map.phys = r->start; bcm963xx_map.size = resource_size(r); bcm963xx_map.virt = ioremap(r->start, resource_size(r)); if (!bcm963xx_map.virt) { dev_err(&pdev->dev, "failed to ioremap\n"); return -EIO; } dev_info(&pdev->dev, "0x%08lx at 0x%08x\n", bcm963xx_map.size, bcm963xx_map.phys); simple_map_init(&bcm963xx_map); bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map); if (!bcm963xx_mtd_info) { dev_err(&pdev->dev, "failed to probe using CFI\n"); bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map); if (bcm963xx_mtd_info) goto probe_ok; dev_err(&pdev->dev, "failed to probe using JEDEC\n"); err = -EIO; goto err_probe; } probe_ok: bcm963xx_mtd_info->owner = THIS_MODULE; /* This is mutually exclusive */ if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) { dev_info(&pdev->dev, "CFE bootloader detected\n"); if (parsed_nr_parts == 0) { int ret = parse_cfe_partitions(bcm963xx_mtd_info, &parsed_parts); if (ret > 0) { part_type = "CFE"; parsed_nr_parts = ret; } } } else { dev_info(&pdev->dev, "unsupported bootloader\n"); err = -ENODEV; goto err_probe; } return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts); err_probe: iounmap(bcm963xx_map.virt); return err; }
static int __init init_mainstone(void) { int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ int ret = 0, i; mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4; mainstone_maps[1].bankwidth = 4; /* Compensate for SW7 which swaps the flash banks */ mainstone_maps[SW7].name = "processor flash"; mainstone_maps[SW7 ^ 1].name = "main board flash"; printk(KERN_NOTICE "Mainstone configured to boot from %s\n", mainstone_maps[0].name); for (i = 0; i < 2; i++) { mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys, WINDOW_SIZE); if (!mainstone_maps[i].virt) { printk(KERN_WARNING "Failed to ioremap %s\n", mainstone_maps[i].name); if (!ret) ret = -ENOMEM; continue; } mainstone_maps[i].cached = ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE); if (!mainstone_maps[i].cached) printk(KERN_WARNING "Failed to ioremap cached %s\n", mainstone_maps[i].name); simple_map_init(&mainstone_maps[i]); printk(KERN_NOTICE "Probing %s at physical address 0x%08lx" " (%d-bit bankwidth)\n", mainstone_maps[i].name, mainstone_maps[i].phys, mainstone_maps[i].bankwidth * 8); mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]); if (!mymtds[i]) { iounmap((void *)mainstone_maps[i].virt); if (mainstone_maps[i].cached) iounmap(mainstone_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", mainstone_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", mainstone_maps[i].name); add_mtd_partitions(mymtds[i], mainstone_partitions, ARRAY_SIZE(mainstone_partitions)); } else { printk("Registering %s as whole device\n", mainstone_maps[i].name); add_mtd_device(mymtds[i]); } } return 0; }
/* * Probe for the NAND device. */ static int __init at91_nand_probe(struct platform_device *pdev) { struct at91_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; int res; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *partitions = NULL; int num_partitions = 0; #endif /* Allocate memory for the device structure (and zero it) */ host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); if (!host) { printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); return -ENOMEM; } host->io_base = ioremap(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); if (host->io_base == NULL) { printk(KERN_ERR "at91_nand: ioremap failed\n"); kfree(host); return -EIO; } mtd = &host->mtd; nand_chip = &host->nand_chip; host->board = pdev->dev.platform_data; nand_chip->priv = host; /* link the private data structures */ mtd->priv = nand_chip; mtd->owner = THIS_MODULE; /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = host->io_base; nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; nand_chip->dev_ready = at91_nand_device_ready; nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ nand_chip->chip_delay = 20; /* 20us command delay time */ if (host->board->bus_width_16) /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; platform_set_drvdata(pdev, host); at91_nand_enable(host); if (host->board->det_pin) { if (at91_get_gpio_value(host->board->det_pin)) { printk ("No SmartMedia card inserted.\n"); res = ENXIO; goto out; } } /* Scan to find existance of the device */ if (nand_scan(mtd, 1)) { res = -ENXIO; goto out; } #ifdef CONFIG_MTD_PARTITIONS if (host->board->partition_info) partitions = host->board->partition_info(mtd->size, &num_partitions); if ((!partitions) || (num_partitions == 0)) { printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; goto release; } res = add_mtd_partitions(mtd, partitions, num_partitions); #else res = add_mtd_device(mtd); #endif if (!res) return res; release: nand_release(mtd); out: at91_nand_disable(host); platform_set_drvdata(pdev, NULL); iounmap(host->io_base); kfree(host); return res; }
int __init init_impa7(void) { static const char *rom_probe_types[] = PROBETYPES; const char **type; const char *part_type = 0; 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++; #ifdef CONFIG_MTD_PARTITIONS mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], probes, &mtd_parts[i], 0); if (mtd_parts_nb[i] > 0) { part_type = "command line"; } else { mtd_parts[i] = static_partitions; mtd_parts_nb[i] = ARRAY_SIZE(static_partitions); part_type = "static"; } printk(KERN_NOTICE MSG_PREFIX "using %s partition definition\n", part_type); add_mtd_partitions(impa7_mtd[i], mtd_parts[i], mtd_parts_nb[i]); #else add_mtd_device(impa7_mtd[i]); #endif } else iounmap((void *)impa7_map[i].virt); } return devicesfound == 0 ? -ENXIO : 0; }
static int __init init_dnpc(void) { int is_dnp; /* ** determine hardware (DNP/ADNP/invalid) */ if((is_dnp = dnp_adnp_probe()) < 0) return -ENXIO; /* ** Things are set up for ADNP by default ** -> modify all that needs to be different for DNP */ if(is_dnp) { /* ** Adjust window size, select correct set_vpp function. ** The partitioning scheme is identical on both DNP ** and ADNP except for the size of the third partition. */ int i; dnpc_map.size = DNP_WINDOW_SIZE; dnpc_map.set_vpp = dnp_set_vpp; partition_info[2].size = 0xf0000; /* ** increment all string pointers so the leading 'A' gets skipped, ** thus turning all occurrences of "ADNP ..." into "DNP ..." */ ++dnpc_map.name; for(i = 0; i < NUM_PARTITIONS; i++) ++partition_info[i].name; higlvl_partition_info[1].size = DNP_WINDOW_SIZE - CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000; for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++) ++higlvl_partition_info[i].name; } printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%llx\n", is_dnp ? "DNPC" : "ADNP", dnpc_map.size, (unsigned long long)dnpc_map.phys); dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size); dnpc_map_flash(dnpc_map.phys, dnpc_map.size); if (!dnpc_map.virt) { printk("Failed to ioremap_nocache\n"); return -EIO; } simple_map_init(&dnpc_map); printk("FLASH virtual address: 0x%p\n", dnpc_map.virt); mymtd = do_map_probe("jedec_probe", &dnpc_map); if (!mymtd) mymtd = do_map_probe("cfi_probe", &dnpc_map); /* ** If flash probes fail, try to make flashes accessible ** at least as ROM. Ajust erasesize in this case since ** the default one (128M) will break our partitioning */ if (!mymtd) if((mymtd = do_map_probe("map_rom", &dnpc_map))) mymtd->erasesize = 0x10000; if (!mymtd) { iounmap(dnpc_map.virt); return -ENXIO; } mymtd->owner = THIS_MODULE; /* ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions() ** -> add_mtd_partitions() will _not_ register MTD devices for ** the partitions, but will instead store pointers to the MTD ** objects it creates into our lowlvl_parts[] array. ** NOTE: we arrange the pointers such that the sequence of the ** partitions gets re-arranged: partition #2 follows ** partition #0. */ partition_info[0].mtdp = &lowlvl_parts[0]; partition_info[1].mtdp = &lowlvl_parts[2]; partition_info[2].mtdp = &lowlvl_parts[1]; partition_info[3].mtdp = &lowlvl_parts[3]; add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); /* ** now create a virtual MTD device by concatenating the for partitions ** (in the sequence given by the lowlvl_parts[] array. */ merged_mtd = mtd_concat_create(lowlvl_parts, NUM_PARTITIONS, "(A)DNP Flash Concatenated"); if(merged_mtd) { /* ** now partition the new device the way we want it. This time, ** we do not supply mtd pointers in higlvl_partition_info, so ** add_mtd_partitions() will register the devices. */ add_mtd_partitions(merged_mtd, higlvl_partition_info, NUM_HIGHLVL_PARTITIONS); } return 0; }
/* * 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; 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 sst25l_probe(struct spi_device *spi) { struct flash_info *flash_info; struct sst25l_flash *flash; struct flash_platform_data *data; int ret, i; flash_info = sst25l_match_device(spi); if (!flash_info) return -ENODEV; flash = kzalloc(sizeof(struct sst25l_flash), GFP_KERNEL); if (!flash) return -ENOMEM; flash->spi = spi; mutex_init(&flash->lock); dev_set_drvdata(&spi->dev, flash); data = spi->dev.platform_data; 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.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); DEBUG(MTD_DEBUG_LEVEL2, "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); if (flash->mtd.numeraseregions) for (i = 0; i < flash->mtd.numeraseregions; i++) DEBUG(MTD_DEBUG_LEVEL2, "mtd.eraseregions[%d] = { .offset = 0x%llx, " ".erasesize = 0x%.8x (%uKiB), " ".numblocks = %d }\n", i, (long long)flash->mtd.eraseregions[i].offset, flash->mtd.eraseregions[i].erasesize, flash->mtd.eraseregions[i].erasesize / 1024, flash->mtd.eraseregions[i].numblocks); if (mtd_has_partitions()) { struct mtd_partition *parts = NULL; int nr_parts = 0; if (mtd_has_cmdlinepart()) { static const char *part_probes[] = {"cmdlinepart", NULL}; nr_parts = parse_mtd_partitions(&flash->mtd, part_probes, &parts, 0); } 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%llx, " ".size = 0x%llx (%lldKiB) }\n", i, parts[i].name, (long long)parts[i].offset, (long long)parts[i].size, (long long)(parts[i].size >> 10)); } flash->partitioned = 1; return add_mtd_partitions(&flash->mtd, parts, nr_parts); } } else if (data->nr_parts) {
/* * Probe for the NAND device. */ static int __init stm_nand_emi_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = pdev->dev.platform_data; struct plat_stmnand_data *stmdata = pdata->ctrl.priv; struct stm_nand_emi *data; struct nand_timing_data *tm; int res = 0; /* Allocate memory for the driver structure (and zero it) */ data = kzalloc(sizeof(struct stm_nand_emi), GFP_KERNEL); if (!data) { printk(KERN_ERR NAME ": Failed to allocate device structure.\n"); return -ENOMEM; } /* Get EMI Bank base address */ data->emi_bank = pdev->id; data->emi_base = emi_bank_base(data->emi_bank) + stmdata->emi_withinbankoffset; data->emi_size = (1 << 18) + 1; /* Configure EMI Bank */ if (nand_config_emi(data->emi_bank, stmdata->timing_data) != 0) { printk(KERN_ERR NAME ": Failed to configure EMI bank " "for NAND device\n"); goto out1; } /* Request IO Memory */ if (!request_mem_region(data->emi_base, data->emi_size, pdev->name)) { printk(KERN_ERR NAME ": Request mem 0x%x region failed\n", data->emi_base); res = -ENODEV; goto out1; } /* Map base address */ data->io_base = ioremap_nocache(data->emi_base, 4096); if (!data->io_base) { printk(KERN_ERR NAME ": ioremap failed for io_base 0x%08x\n", data->emi_base); res = -ENODEV; goto out2; } #ifdef CONFIG_STM_NAND_EMI_CACHED /* Map data address through cache line */ data->io_data = ioremap_cache(data->emi_base + 4096, 4096); if (!data->io_data) { printk(KERN_ERR NAME ": ioremap failed for io_data 0x%08x\n", data->emi_base + 4096); res = -ENOMEM; goto out3; } #else data->io_data = data->io_base; #endif /* Map cmd and addr addresses (emi_addr_17 and emi_addr_18) */ data->io_cmd = ioremap_nocache(data->emi_base | (1 << 17), 1); if (!data->io_cmd) { printk(KERN_ERR NAME ": ioremap failed for io_cmd 0x%08x\n", data->emi_base | (1 << 17)); res = -ENOMEM; goto out4; } data->io_addr = ioremap_nocache(data->emi_base | (1 << 18), 1); if (!data->io_addr) { printk(KERN_ERR NAME ": ioremap failed for io_addr 0x%08x\n", data->emi_base | (1 << 18)); res = -ENOMEM; goto out5; } data->chip.priv = data; data->mtd.priv = &data->chip; data->mtd.owner = THIS_MODULE; /* Assign more sensible name (default is string from nand_ids.c!) */ data->mtd.name = pdev->dev.bus_id; tm = stmdata->timing_data; data->chip.IO_ADDR_R = data->io_base; data->chip.IO_ADDR_W = data->io_base; data->chip.chip_delay = tm->chip_delay; data->chip.cmd_ctrl = nand_cmd_ctrl_emi; /* Do we have access to NAND_RBn? */ if (stmdata->rbn_port >= 0) { data->rbn = stpio_request_pin(stmdata->rbn_port, stmdata->rbn_pin, "nand_RBn", STPIO_IN); if (data->rbn) { data->chip.dev_ready = nand_device_ready; } else { printk(KERN_INFO NAME ": nand_rbn unavailable. " "Falling back to chip_delay\n"); /* Set a default delay if not previosuly specified */ if (data->chip.chip_delay == 0) data->chip.chip_delay = 30; } } /* Set IO routines for acessing NAND pages */ #if defined(CONFIG_STM_NAND_EMI_FDMA) data->chip.read_buf = nand_read_buf_dma; data->chip.write_buf = nand_write_buf_dma; data->dma_chan = -1; data->init_fdma_jiffies = 0; init_fdma_nand_ratelimit(data); data->nand_phys_addr = data->emi_base; #elif defined(CONFIG_STM_NAND_EMI_LONGSL) data->chip.read_buf = nand_readsl_buf; data->chip.write_buf = nand_writesl_buf; #elif defined(CONFIG_STM_NAND_EMI_CACHED) data->chip.read_buf = nand_read_buf_cached_block; data->chip.write_buf = nand_write_buf_cached_block; #elif defined(CONFIG_STM_NAND_EMI_BYTE) /* Default byte orientated routines */ #else #error "Must specify CONFIG_STM_NAND_EMI_xxxx mode" #endif data->chip.ecc.mode = NAND_ECC_SOFT; /* Copy chip options from platform data */ data->chip.options = pdata->chip.options; platform_set_drvdata(pdev, data); /* Scan to find existance of the device */ if (nand_scan(&data->mtd, 1)) { printk(KERN_ERR NAME ": nand_scan failed\n"); res = -ENXIO; goto out6; } #ifdef CONFIG_MTD_PARTITIONS res = parse_mtd_partitions(&data->mtd, part_probes, &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; /* Release resources on error */ out6: nand_release(&data->mtd); if (data->rbn) stpio_free_pin(data->rbn); platform_set_drvdata(pdev, NULL); iounmap(data->io_addr); out5: iounmap(data->io_cmd); out4: #ifdef CONFIG_STM_NAND_EMI_CACHED iounmap(data->io_data); out3: #endif iounmap(data->io_base); out2: release_mem_region(data->emi_base, data->emi_size); out1: kfree(data); return res; }
/* * Probe the flash chip(s) and, if it succeeds, read the partition-table * and register the partitions with MTD. */ static int __init init_axis_flash(void) { struct mtd_info *mymtd; int err = 0; int pidx = 0; struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n"; if (!(mymtd = flash_probe())) { /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); } else { printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", mymtd->name, mymtd->size); axisflash_mtd = mymtd; } if (mymtd) { mymtd->owner = THIS_MODULE; ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); } pidx++; /* First partition is always set to the default. */ if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + ptable_head->size - PARTITIONTABLE_END_MARKER_SIZE) == PARTITIONTABLE_END_MARKER)) { /* Looks like a start, sane length and end of a * partition table, lets check csum etc. */ int ptable_ok = 0; struct partitiontable_entry *max_addr = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head) + ptable_head->size); unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; unsigned char *p; unsigned long csum = 0; ptable = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head)); /* Lets be PARANOID, and check the checksum. */ p = (unsigned char*) ptable; while (p <= (unsigned char*)max_addr) { csum += *p++; csum += *p++; csum += *p++; csum += *p++; } ptable_ok = (csum == ptable_head->checksum); /* Read the entries and use/show the info. */ printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); /* We have found a working bootblock. Now read the * partition table. Scan the table. It ends when * there is 0xffffffff, that is, empty flash. */ while (ptable_ok && ptable->offset != 0xffffffff && ptable < max_addr && pidx < MAX_PARTITIONS) { axis_partitions[pidx].offset = offset + ptable->offset; axis_partitions[pidx].size = ptable->size; printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; ptable++; } use_default_ptable = !ptable_ok; } if (romfs_in_flash) { /* Add an overlapping device for the root partition (romfs). */ axis_partitions[pidx].name = "romfs"; axis_partitions[pidx].size = romfs_length; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE if (mymtd) { main_partition.size = mymtd->size; err = add_mtd_partitions(mymtd, &main_partition, 1); if (err) panic("axisflashmap: Could not initialize " "partition for whole main mtd device!\n"); } #endif if (mymtd) { if (use_default_ptable) { printk(KERN_INFO " Using default partition table.\n"); err = add_mtd_partitions(mymtd, axis_default_partitions, NUM_DEFAULT_PARTITIONS); } else { err = add_mtd_partitions(mymtd, axis_partitions, pidx); } if (err) panic("axisflashmap could not add MTD partitions!\n"); } if (!romfs_in_flash) { /* Create an RAM device for the root partition (romfs). */ #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) /* No use trying to boot this kernel from RAM. Panic! */ printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " "device due to kernel (mis)configuration!\n"); panic("This kernel cannot boot from RAM!\n"); #else struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) panic("axisflashmap couldn't allocate memory for " "mtd_info!\n"); printk(KERN_INFO " Adding RAM partition for romfs image:\n"); printk(pmsg, pidx, (unsigned)romfs_start, (unsigned)romfs_length); err = mtdram_init_device(mtd_ram, (void *)romfs_start, romfs_length, "romfs"); if (err) panic("axisflashmap could not initialize MTD RAM " "device!\n"); #endif } return err; }
static int __init pxa2xx_flash_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); 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); } dev_set_drvdata(dev, info); return 0; }
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 (pdev->dev.platform_data == NULL) { dev_err(&pdev->dev, "no platform data supplied\n"); err = -ENOENT; goto exit_error; } pdata = pdev->dev.platform_data; info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { dev_err(&pdev->dev, "no memory for flash info\n"); 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%lx)\n", res, res->start); /* setup map parameters */ info->map.phys = res->start; info->map.size = (res->end - res->start) + 1; info->map.name = pdata->mapname != NULL ? 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 */ 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; platram_setrw(info, PLATRAM_RW); /* check to see if there are any available partitions, or wether * to add this device whole */ #ifdef CONFIG_MTD_PARTITIONS if (pdata->nr_partitions > 0) { const char **probes = { NULL }; if (pdata->probes) probes = (const char **)pdata->probes; err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); if (err > 0) { err = add_mtd_partitions(info->mtd, info->partitions, err); } } #endif /* CONFIG_MTD_PARTITIONS */ if (add_mtd_device(info->mtd)) { dev_err(&pdev->dev, "add_mtd_device() failed\n"); err = -ENOMEM; } dev_info(&pdev->dev, "registered mtd device\n"); return err; exit_free: platram_remove(pdev); exit_error: return err; }
static int ea1788_nand_probe(struct platform_device *dev) { struct physmap_flash_data *nand_data; struct nand_chip *this; const char *part_type; unsigned long size; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *mtd_parts; int nbparts = 0; #endif int ret = 0; nand_data = dev->dev.platform_data; if (nand_data == NULL) return -ENODEV; if (dev->num_resources != 1) return -ENODEV; /* Allocate memory for MTD device structure and private data */ ea1788_mtd = kzalloc(sizeof(*ea1788_mtd) + sizeof(*this), GFP_KERNEL); if (!ea1788_mtd) { pr_warning("Unable to allocate NAND MTD device structure.\n"); return -ENOMEM; } /* Map physical adress */ size = dev->resource[0].end - dev->resource[0].start + 1; ea1788_nand_base = ioremap(dev->resource[0].start, size); if (!ea1788_nand_base) { printk("Ioremap NAND MTD chip fails.\n"); ret = -EINVAL; goto err_ioremap; } /* Get pointer to private data */ this = (struct nand_chip *)(&ea1788_mtd[1]); /* Link the private data with the MTD structure */ ea1788_mtd->priv = this; ea1788_mtd->owner = THIS_MODULE; /* Set address of NAND IO lines */ this->IO_ADDR_R = ea1788_nand_base; this->IO_ADDR_W = ea1788_nand_base; this->cmd_ctrl = ea1788_nand_hwcontrol; this->chip_delay = CONFIG_MTD_NAND_EA1788_CHIP_DELAY; this->ecc.mode = NAND_ECC_SOFT; this->options = NAND_USE_FLASH_BBT; /* Scan to find existance of the device */ if (nand_scan(ea1788_mtd, 1)) { ret = -ENXIO; goto err_scan; } #ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_CMDLINE_PARTS nbparts = parse_mtd_partitions(ea1788_mtd, part_probes, &mtd_parts, 0); if (nbparts > 0) part_type = "command line"; else nbparts = 0; #endif if (!nbparts) { mtd_parts = nand_data->parts; nbparts = nand_data->nr_parts; part_type = "static"; } /* Register the partitions */ pr_debug("Using %s partition definition\n", part_type); ret = add_mtd_partitions(ea1788_mtd, mtd_parts, nbparts); if (ret) goto err_scan; #endif return 0; err_scan: iounmap(ea1788_nand_base); err_ioremap: kfree(ea1788_mtd); return ret; }
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 = parse_mtd_partitions(info->mtd, probes, &info->partitions, dev->resource->start); if (err > 0) { err = add_mtd_partitions(info->mtd, info->partitions, err); if(err) printk(KERN_ERR "Could not parse partitions\n"); } if (err) goto Error; return 0; Error: ixp4xx_flash_remove(dev); return err; }
static int __init lpc2468_ea_nand_init(void) { struct nand_chip *this; int err = 0; /* Allocate memory for MTD device structure and private data */ lpc2468_ea_nand_mtd = kmalloc(sizeof(struct mtd_info)+sizeof(struct nand_chip), GFP_KERNEL); if(!lpc2468_ea_nand_mtd) { printk("Unable to allocate NAND MTD device structure.\n"); err = -EIO; goto out; } /* Map physical adress */ lpc2468_ea_nand_base = ioremap(NAND_BASE, NAND_SIZE); if (!lpc2468_ea_nand_base) { printk("Ioremap NAND MTD chip fails.\n"); err = -EIO; goto out_mtd; } /* Get pointer to private data */ this = (struct nand_chip *)(&lpc2468_ea_nand_mtd[1]); /* Initialize structures */ memset(lpc2468_ea_nand_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ lpc2468_ea_nand_mtd->priv = this; lpc2468_ea_nand_mtd->owner = THIS_MODULE; /* Set address of NAND IO lines */ this->IO_ADDR_R = lpc2468_ea_nand_base; this->IO_ADDR_W = lpc2468_ea_nand_base; this->cmd_ctrl = lpc2468_ea_nand_hwcontrol; /* this->dev_ready = lpc2468_ea_nand_device_ready; */ this->chip_delay = 25; /* 25 us command delay time */ this->ecc.mode = NAND_ECC_SOFT; /* this->options = NAND_USE_FLASH_BBT; */ /* Scan to find existance of the device */ if (nand_scan(lpc2468_ea_nand_mtd, 1)) { err = -ENXIO; goto out_ior; } #ifdef CONFIG_MTD_PARTITIONS /* Register the partitions */ add_mtd_partitions(lpc2468_ea_nand_mtd, lpc2468_ea_nand_partition_info, ARRAY_SIZE(lpc2468_ea_nand_partition_info)); #endif goto out; out_ior: iounmap(lpc2468_ea_nand_base); out_mtd: kfree(lpc2468_ea_nand_mtd); lpc2468_ea_nand_mtd = NULL; out: return err; }
static int armadillo_mtd_probe(struct platform_device *pdev) { struct armadillo_flash_private_data *priv = pdev->dev.platform_data; struct flash_platform_data *plat = &priv->plat; struct resource *res; unsigned int region_size; struct armadillo_flash_info *info; int err; int default_parts = 0; info = kmalloc(sizeof(struct armadillo_flash_info), GFP_KERNEL); if (!info) { err = -ENOMEM; goto out; } memset(info, 0, sizeof(struct armadillo_flash_info)); info->plat = plat; if (plat && plat->init) { err = plat->init(); if (err) goto no_resource; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { err = -ENOMEM; goto no_resource; } region_size = res->end - res->start + 1; info->res = request_mem_region(res->start, region_size, "mtd"); if (!info->res) { err = -EBUSY; goto no_resource; } /* * look for CFI based flash parts fitted to this board */ info->map.size = region_size; info->map.bankwidth = plat->width; info->map.phys = res->start; info->map.virt = (void __iomem *)CS0_BASE_ADDR_VIRT; info->map.name = priv->map_name; info->map.set_vpp = 0; simple_map_init(&info->map); /* * Also, the CFI layer automatically works out what size * of chips we have, and does the necessary identification * for us automatically. */ info->mtd = do_map_probe(plat->map_name, &info->map); if (!info->mtd) { err = -ENXIO; goto no_device; } info->mtd->owner = THIS_MODULE; err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); if (err > 0) { PRINT_INFO("use cmdline partitions(%d)\n", err); err = add_mtd_partitions(info->mtd, info->parts, err); if (err) { PRINT_ERR("mtd partition registration failed: %d\n", err); default_parts = 1; } } else { default_parts = 1; } if (default_parts) { if (priv && priv->update_partitions) priv->update_partitions(&info->map, plat); PRINT_INFO("use default partitions(%d)\n", plat->nr_parts); err = add_mtd_partitions(info->mtd, plat->parts, plat->nr_parts); if (err) PRINT_ERR("mtd partition registration failed: %d\n", err); } if (err == 0) platform_set_drvdata(pdev, info); /* * If we got an error, free all resources. */ if (err < 0) { if (info->mtd) { del_mtd_partitions(info->mtd); map_destroy(info->mtd); } if (info->parts) kfree(info->parts); no_device: release_mem_region(res->start, region_size); no_resource: if (plat && plat->exit) plat->exit(); kfree(info); } out: return err; }
/* * Main initialization routine */ static int __init h1910_init (void) { struct nand_chip *this; const char *part_type = 0; int mtd_parts_nb = 0; struct mtd_partition *mtd_parts = 0; void __iomem *nandaddr; if (!machine_is_h1900()) return -ENODEV; nandaddr = ioremap(0x08000000, 0x1000); if (!nandaddr) { printk("Failed to ioremap nand flash.\n"); return -ENOMEM; } /* Allocate memory for MTD device structure and private data */ h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!h1910_nand_mtd) { printk("Unable to allocate h1910 NAND MTD device structure.\n"); iounmap ((void *) nandaddr); return -ENOMEM; } /* Get pointer to private data */ this = (struct nand_chip *) (&h1910_nand_mtd[1]); /* Initialize structures */ memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); memset((char *) this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ h1910_nand_mtd->priv = this; /* * Enable VPEN */ GPSR(37) = GPIO_bit(37); /* insert callbacks */ this->IO_ADDR_R = nandaddr; this->IO_ADDR_W = nandaddr; this->hwcontrol = h1910_hwcontrol; this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ /* 15 us command delay time */ this->chip_delay = 50; this->eccmode = NAND_ECC_SOFT; this->options = NAND_NO_AUTOINCR; /* Scan to find existence of the device */ if (nand_scan (h1910_nand_mtd, 1)) { printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); kfree (h1910_nand_mtd); iounmap ((void *) nandaddr); return -ENXIO; } #ifdef CONFIG_MTD_CMDLINE_PARTS mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand"); if (mtd_parts_nb > 0) part_type = "command line"; else mtd_parts_nb = 0; #endif if (mtd_parts_nb == 0) { mtd_parts = partition_info; mtd_parts_nb = NUM_PARTITIONS; part_type = "static"; } /* Register the partitions */ printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); /* Return happy */ return 0; }
static int bast_flash_probe(struct platform_device *pdev) { struct bast_flash_info *info; struct resource *res; int err = 0; info = kmalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { printk(KERN_ERR PFX "no memory for flash info\n"); err = -ENOMEM; goto exit_error; } memzero(info, sizeof(*info)); platform_set_drvdata(pdev, info); res = pdev->resource; /* assume that the flash has one resource */ info->map.phys = res->start; info->map.size = res->end - res->start + 1; info->map.name = pdev->dev.bus_id; info->map.bankwidth = 2; if (info->map.size > AREA_MAXSIZE) info->map.size = AREA_MAXSIZE; pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, info->map.phys, info->map.size); info->area = request_mem_region(res->start, info->map.size, pdev->name); if (info->area == NULL) { printk(KERN_ERR PFX "cannot reserve flash memory region\n"); err = -ENOENT; goto exit_error; } info->map.virt = ioremap(res->start, info->map.size); pr_debug("%s: virt at %08x\n", __FUNCTION__, (int)info->map.virt); if (info->map.virt == 0) { printk(KERN_ERR PFX "failed to ioremap() region\n"); err = -EIO; goto exit_error; } simple_map_init(&info->map); /* enable the write to the flash area */ bast_flash_setrw(1); /* probe for the device(s) */ info->mtd = do_map_probe("jedec_probe", &info->map); if (info->mtd == NULL) info->mtd = do_map_probe("cfi_probe", &info->map); if (info->mtd == NULL) { printk(KERN_ERR PFX "map_probe() failed\n"); err = -ENXIO; goto exit_error; } /* mark ourselves as the owner */ 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) printk(KERN_ERR PFX "cannot add/parse partitions\n"); } else { err = add_mtd_device(info->mtd); } if (err == 0) return 0; /* fall through to exit error */ exit_error: bast_flash_remove(pdev); return err; }
int __init init_dc21285(void) { /* Determine buswidth */ switch (*CSR_SA110_CNTL & (3<<14)) { case SA110_CNTL_ROMWIDTH_8: dc21285_map.buswidth = 1; break; case SA110_CNTL_ROMWIDTH_16: dc21285_map.buswidth = 2; break; case SA110_CNTL_ROMWIDTH_32: dc21285_map.buswidth = 4; break; default: printk (KERN_ERR "DC21285 flash: undefined buswidth\n"); return -ENXIO; } printk (KERN_NOTICE "DC21285 flash support (%d-bit buswidth)\n", dc21285_map.buswidth*8); /* Let's map the flash area */ dc21285_map.map_priv_1 = (unsigned long)ioremap(DC21285_FLASH, 16*1024*1024); if (!dc21285_map.map_priv_1) { printk("Failed to ioremap\n"); return -EIO; } mymtd = do_map_probe("cfi_probe", &dc21285_map); if (mymtd) { int nrparts = 0; mymtd->module = THIS_MODULE; /* partition fixup */ #ifdef CONFIG_MTD_REDBOOT_PARTS nrparts = parse_redboot_partitions(mymtd, &dc21285_parts); #endif if (nrparts > 0) { add_mtd_partitions(mymtd, dc21285_parts, nrparts); } else if (nrparts == 0) { printk(KERN_NOTICE "RedBoot partition table failed\n"); add_mtd_device(mymtd); } /* * Flash timing is determined with bits 19-16 of the * CSR_SA110_CNTL. The value is the number of wait cycles, or * 0 for 16 cycles (the default). Cycles are 20 ns. * Here we use 7 for 140 ns flash chips. */ /* access time */ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); /* burst time */ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); /* tristate time */ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); return 0; } iounmap((void *)dc21285_map.map_priv_1); return -ENXIO; }
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; }
static int __init init_ocelot_maps(void) { void *pld; int nr_parts; unsigned char brd_status; printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n", FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR); /* First check whether the flash jumper is present */ pld = ioremap(OCELOT_PLD, 0x10); if (!pld) { printk(KERN_NOTICE "Failed to ioremap Ocelot PLD\n"); return -EIO; } brd_status = readb(pld+4); iounmap(pld); /* Now ioremap the NVRAM space */ ocelot_nvram_map.virt = ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE); if (!ocelot_nvram_map.virt) { printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n"); return -EIO; } simple_map_init(&ocelot_nvram_map); /* And do the RAM probe on it to get an MTD device */ nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map); if (!nvram_mtd) { printk("NVRAM probe failed\n"); goto fail_1; } nvram_mtd->owner = THIS_MODULE; nvram_mtd->erasesize = 16; /* Override the write() method */ nvram_mtd->write = ocelot_ram_write; /* Now map the flash space */ ocelot_flash_map.virt = ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE); if (!ocelot_flash_map.virt) { printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n"); goto fail_2; } /* Now the cached version */ ocelot_flash_map.cached = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0); simple_map_init(&ocelot_flash_map); /* Only probe for flash if the write jumper is present */ if (brd_status & 0x40) { flash_mtd = do_map_probe("jedec", &ocelot_flash_map); } else { printk(KERN_NOTICE "Ocelot flash write jumper not present. Treating as ROM\n"); } /* If that failed or the jumper's absent, pretend it's ROM */ if (!flash_mtd) { flash_mtd = do_map_probe("map_rom", &ocelot_flash_map); /* If we're treating it as ROM, set the erase size */ if (flash_mtd) flash_mtd->erasesize = 0x10000; } if (!flash_mtd) goto fail3; add_mtd_device(nvram_mtd); flash_mtd->owner = THIS_MODULE; nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); if (nr_parts > 0) add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); else add_mtd_device(flash_mtd); return 0; fail3: iounmap((void *)ocelot_flash_map.virt); if (ocelot_flash_map.cached) iounmap((void *)ocelot_flash_map.cached); fail_2: map_destroy(nvram_mtd); fail_1: iounmap((void *)ocelot_nvram_map.virt); return -ENXIO; }