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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/*
 * 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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;


}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
/**
 * 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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 19
0
/*
 * 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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
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 = 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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
/*
 * 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;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
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;
}