static int __init h720x_mtd_init(void)
{
	h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);

	if (!h720x_map.virt) {
		printk(KERN_ERR "H720x-MTD: ioremap failed\n");
		return -EIO;
	}

	simple_map_init(&h720x_map);

	//                            
	printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n");
	mymtd = do_map_probe("cfi_probe", &h720x_map);
	if (!mymtd) {
		printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n");
	    //                      
	    h720x_map.bankwidth = 2;
	    mymtd = do_map_probe("cfi_probe", &h720x_map);
	}

	if (mymtd) {
		mymtd->owner = THIS_MODULE;

		mtd_device_parse_register(mymtd, NULL, NULL,
					  h720x_partitions, NUM_PARTITIONS);
		return 0;
	}

	iounmap((void *)h720x_map.virt);
	return -ENXIO;
}
Beispiel #2
0
static int bcm47xxnflash_probe(struct platform_device *pdev)
{
	struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
	struct bcm47xxnflash *b47n;
	int err = 0;

	b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL);
	if (!b47n)
		return -ENOMEM;

	b47n->nand_chip.priv = b47n;
	b47n->mtd.owner = THIS_MODULE;
	b47n->mtd.priv = &b47n->nand_chip; /* Required */
	b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash);

	if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
		err = bcm47xxnflash_ops_bcm4706_init(b47n);
	} else {
		pr_err("Device not supported\n");
		err = -ENOTSUPP;
	}
	if (err) {
		pr_err("Initialization failed: %d\n", err);
		return err;
	}

	err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0);
	if (err) {
		pr_err("Failed to register MTD device: %d\n", err);
		return err;
	}

	return 0;
}
/**
 * Module/ driver initialization.
 *
 * Returns Zero on success
 */
static int __init flash_init(void)
{
	/*
	 * Read the bootbus region 0 setup to determine the base
	 * address of the flash.
	 */
	union cvmx_mio_boot_reg_cfgx region_cfg;
	region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
	if (region_cfg.s.en) {
		/*
		 * The bootloader always takes the flash and sets its
		 * address so the entire flash fits below
		 * 0x1fc00000. This way the flash aliases to
		 * 0x1fc00000 for booting. Software can access the
		 * full flash at the true address, while core boot can
		 * access 4MB.
		 */
		/* Use this name so old part lines work */
		flash_map.name = "phys_mapped_flash";
		flash_map.phys = region_cfg.s.base << 16;
		flash_map.size = 0x1fc00000 - flash_map.phys;
		flash_map.bankwidth = 1;
		flash_map.virt = ioremap(flash_map.phys, flash_map.size);
		pr_notice("Bootbus flash: Setting flash for %luMB flash at "
			  "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
		simple_map_init(&flash_map);
		mymtd = do_map_probe("cfi_probe", &flash_map);
		if (mymtd) {
			mymtd->owner = THIS_MODULE;
			mtd_device_parse_register(mymtd, part_probe_types,
						  NULL, NULL, 0);
		} else {
			pr_err("Failed to register MTD device for flash\n");
		}
	}
Beispiel #4
0
static int bcm47xxsflash_probe(struct platform_device *pdev)
{
	struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
	struct bcm47xxsflash *b47s;
	int err;

	b47s = kzalloc(sizeof(*b47s), GFP_KERNEL);
	if (!b47s) {
		err = -ENOMEM;
		goto out;
	}
	sflash->priv = b47s;

	b47s->window = sflash->window;
	b47s->blocksize = sflash->blocksize;
	b47s->numblocks = sflash->numblocks;
	b47s->size = sflash->size;
	bcm47xxsflash_fill_mtd(b47s);

	err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
	if (err) {
		pr_err("Failed to register MTD device: %d\n", err);
		goto err_dev_reg;
	}

	return 0;

err_dev_reg:
	kfree(&b47s->mtd);
out:
	return err;
}
Beispiel #5
0
static int bcm47xxsflash_probe(struct platform_device *pdev)
{
	struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
	int err;

	sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
	if (!sflash->mtd) {
		err = -ENOMEM;
		goto out;
	}
	bcm47xxsflash_fill_mtd(sflash, sflash->mtd);

	err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0);
	if (err) {
		pr_err("Failed to register MTD device: %d\n", err);
		goto err_dev_reg;
	}

	return 0;

err_dev_reg:
	kfree(sflash->mtd);
out:
	return err;
}
static int sst25l_probe(struct spi_device *spi)
{
	struct flash_info *flash_info;
	struct sst25l_flash *flash;
	struct flash_platform_data *data;
	int ret;

	flash_info = sst25l_match_device(spi);
	if (!flash_info)
		return -ENODEV;

	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
	if (!flash)
		return -ENOMEM;

	flash->spi = spi;
	mutex_init(&flash->lock);
	spi_set_drvdata(spi, flash);

	data = dev_get_platdata(&spi->dev);
	if (data && data->name)
		flash->mtd.name = data->name;
	else
		flash->mtd.name = dev_name(&spi->dev);

	flash->mtd.type		= MTD_NORFLASH;
	flash->mtd.flags	= MTD_CAP_NORFLASH;
	flash->mtd.erasesize	= flash_info->erase_size;
	flash->mtd.writesize	= flash_info->page_size;
	flash->mtd.writebufsize	= flash_info->page_size;
	flash->mtd.size		= flash_info->page_size * flash_info->nr_pages;
	flash->mtd._erase	= sst25l_erase;
	flash->mtd._read		= sst25l_read;
	flash->mtd._write 	= sst25l_write;

	dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
		 (long long)flash->mtd.size >> 10);

	pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
	      ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
	      flash->mtd.name,
	      (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
	      flash->mtd.erasesize, flash->mtd.erasesize / 1024,
	      flash->mtd.numeraseregions);


	ret = mtd_device_parse_register(&flash->mtd, NULL, NULL,
					data ? data->parts : NULL,
					data ? data->nr_parts : 0);
	if (ret)
		return -ENODEV;

	return 0;
}
/*
 * Initialize chip structure
 */
static int ndfc_chip_init(struct ndfc_controller *ndfc,
			  struct device_node *node)
{
	struct device_node *flash_np;
	struct nand_chip *chip = &ndfc->chip;
	struct mtd_part_parser_data ppdata;
	int ret;

	chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
	chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
	chip->cmd_ctrl = ndfc_hwcontrol;
	chip->dev_ready = ndfc_ready;
	chip->select_chip = ndfc_select_chip;
	chip->chip_delay = 50;
	chip->controller = &ndfc->ndfc_control;
	chip->read_buf = ndfc_read_buf;
	chip->write_buf = ndfc_write_buf;
	chip->verify_buf = ndfc_verify_buf;
	chip->ecc.correct = nand_correct_data;
	chip->ecc.hwctl = ndfc_enable_hwecc;
	chip->ecc.calculate = ndfc_calculate_ecc;
	chip->ecc.mode = NAND_ECC_HW;
	chip->ecc.size = 256;
	chip->ecc.bytes = 3;
	chip->ecc.strength = 1;
	chip->priv = ndfc;

	ndfc->mtd.priv = chip;
	ndfc->mtd.owner = THIS_MODULE;

	flash_np = of_get_next_child(node, NULL);
	if (!flash_np)
		return -ENODEV;

	ppdata.of_node = flash_np;
	ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
			dev_name(&ndfc->ofdev->dev), flash_np->name);
	if (!ndfc->mtd.name) {
		ret = -ENOMEM;
		goto err;
	}

	ret = nand_scan(&ndfc->mtd, 1);
	if (ret)
		goto err;

	ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0);

err:
	of_node_put(flash_np);
	if (ret)
		kfree(ndfc->mtd.name);
	return ret;
}
static int generic_onenand_probe(struct platform_device *pdev)
{
	struct onenand_info *info;
	struct onenand_platform_data *pdata = pdev->dev.platform_data;
	struct resource *res = pdev->resource;
	unsigned long size = resource_size(res);
	int err;

	info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (!request_mem_region(res->start, size, dev_name(&pdev->dev))) {
		err = -EBUSY;
		goto out_free_info;
	}

	info->onenand.base = ioremap(res->start, size);
	if (!info->onenand.base) {
		err = -ENOMEM;
		goto out_release_mem_region;
	}

	info->onenand.mmcontrol = pdata ? pdata->mmcontrol : 0;
	info->onenand.irq = platform_get_irq(pdev, 0);

	info->mtd.name = dev_name(&pdev->dev);
	info->mtd.priv = &info->onenand;
	info->mtd.owner = THIS_MODULE;

	if (onenand_scan(&info->mtd, 1)) {
		err = -ENXIO;
		goto out_iounmap;
	}

	err = mtd_device_parse_register(&info->mtd, NULL, NULL,
					pdata ? pdata->parts : NULL,
					pdata ? pdata->nr_parts : 0);

	platform_set_drvdata(pdev, info);

	return 0;

out_iounmap:
	iounmap(info->onenand.base);
out_release_mem_region:
	release_mem_region(res->start, size);
out_free_info:
	kfree(info);

	return err;
}
Beispiel #9
0
/**
 * Module/ driver initialization.
 *
 * Returns Zero on success
 */
static int octeon_flash_probe(struct platform_device *pdev)
{
	union cvmx_mio_boot_reg_cfgx region_cfg;
	u32 cs;
	int r;
	struct device_node *np = pdev->dev.of_node;

	r = of_property_read_u32(np, "reg", &cs);
	if (r)
		return r;

	/*
	 * Read the bootbus region 0 setup to determine the base
	 * address of the flash.
	 */
	region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
	if (region_cfg.s.en) {
		/*
		 * The bootloader always takes the flash and sets its
		 * address so the entire flash fits below
		 * 0x1fc00000. This way the flash aliases to
		 * 0x1fc00000 for booting. Software can access the
		 * full flash at the true address, while core boot can
		 * access 4MB.
		 */
		/* Use this name so old part lines work */
		flash_map.name = "phys_mapped_flash";
		flash_map.phys = region_cfg.s.base << 16;
		flash_map.size = 0x1fc00000 - flash_map.phys;
		/* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */
		flash_map.bankwidth = region_cfg.s.width + 1;
		flash_map.virt = ioremap(flash_map.phys, flash_map.size);
		pr_notice("Bootbus flash: Setting flash for %luMB flash at "
			  "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
		WARN_ON(!map_bankwidth_supported(flash_map.bankwidth));
		flash_map.read = octeon_flash_map_read;
		flash_map.write = octeon_flash_map_write;
		flash_map.copy_from = octeon_flash_map_copy_from;
		flash_map.copy_to = octeon_flash_map_copy_to;
		mymtd = do_map_probe("cfi_probe", &flash_map);
		if (mymtd) {
			mymtd->owner = THIS_MODULE;
			mtd_device_parse_register(mymtd, part_probe_types,
						  NULL, NULL, 0);
		} else {
			pr_err("Failed to register MTD device for flash\n");
		}
	}
static int __devinit bfin_flash_probe(struct platform_device *pdev)
{
	int ret;
	struct physmap_flash_data *pdata = pdev->dev.platform_data;
	struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	struct async_state *state;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	state->map.name       = DRIVER_NAME;
	state->map.read       = bfin_flash_read;
	state->map.copy_from  = bfin_flash_copy_from;
	state->map.write      = bfin_flash_write;
	state->map.copy_to    = bfin_flash_copy_to;
	state->map.bankwidth  = pdata->width;
	state->map.size       = resource_size(memory);
	state->map.virt       = (void __iomem *)memory->start;
	state->map.phys       = memory->start;
	state->map.map_priv_1 = (unsigned long)state;
	state->enet_flash_pin = platform_get_irq(pdev, 0);
	state->flash_ambctl0  = flash_ambctl->start;
	state->flash_ambctl1  = flash_ambctl->end;

	if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
		pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
		kfree(state);
		return -EBUSY;
	}
	gpio_direction_output(state->enet_flash_pin, 1);

	pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
	state->mtd = do_map_probe(memory->name, &state->map);
	if (!state->mtd) {
		gpio_free(state->enet_flash_pin);
		kfree(state);
		return -ENXIO;
	}

	mtd_device_parse_register(state->mtd, part_probe_types, NULL,
				  pdata->parts, pdata->nr_parts);

	platform_set_drvdata(pdev, state);

	return 0;
}
Beispiel #11
0
static int __init cs553x_init(void)
{
	int err = -ENXIO;
	int i;
	uint64_t val;

	/* If the CPU isn't a Geode GX or LX, abort */
	if (!is_geode())
		return -ENXIO;

	/* If it doesn't have the CS553[56], abort */
	rdmsrl(MSR_DIVIL_GLD_CAP, val);
	val &= ~0xFFULL;
	if (val != CAP_CS5535 && val != CAP_CS5536)
		return -ENXIO;

	/* If it doesn't have the NAND controller enabled, abort */
	rdmsrl(MSR_DIVIL_BALL_OPTS, val);
	if (val & PIN_OPT_IDE) {
		printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
		return -ENXIO;
	}

	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
		rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);

		if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
			err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
	}

	/* Register all devices together here. This means we can easily hack it to
	   do mtdconcat etc. if we want to. */
	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
		if (cs553x_mtd[i]) {
			/* If any devices registered, return success. Else the last error. */
			mtd_device_parse_register(cs553x_mtd[i], NULL, 0,
						  NULL, 0);
			err = 0;
		}
	}

	return err;
}
static int __init init_soleng_maps(void)
{
	/* First probe at offset 0 */
	soleng_flash_map.phys = 0;
	soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0);
	soleng_eprom_map.phys = 0x01000000;
	soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
	simple_map_init(&soleng_eprom_map);
	simple_map_init(&soleng_flash_map);

	printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
	flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
	if (!flash_mtd) {
		/* Not there. Try swapping */
		printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n");
		soleng_flash_map.phys = 0x01000000;
		soleng_flash_map.virt = P2SEGADDR(0x01000000);
		soleng_eprom_map.phys = 0;
		soleng_eprom_map.virt = P1SEGADDR(0);
		flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
		if (!flash_mtd) {
			/* Eep. */
			printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
			return -ENXIO;
		}
	}
	printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n",
	       soleng_flash_map.phys & 0x1fffffff,
	       soleng_eprom_map.phys & 0x1fffffff);
	flash_mtd->owner = THIS_MODULE;

	eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map);
	if (eprom_mtd) {
		eprom_mtd->owner = THIS_MODULE;
		mtd_device_register(eprom_mtd, NULL, 0);
	}

	mtd_device_parse_register(flash_mtd, probes, NULL,
				  superh_se_partitions, NUM_PARTITIONS);

	return 0;
}
Beispiel #13
0
static int __init init_impa7(void)
{
	static const char *rom_probe_types[] = PROBETYPES;
	const char **type;
	int i;
	static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
	  { WINDOW_ADDR0, WINDOW_SIZE0 },
	  { WINDOW_ADDR1, WINDOW_SIZE1 },
        };
	int devicesfound = 0;

	for(i=0; i<NUM_FLASHBANKS; i++)
	{
		printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n",
		       pt[i].size, pt[i].addr);

		impa7_map[i].phys = pt[i].addr;
		impa7_map[i].virt = ioremap(pt[i].addr, pt[i].size);
		if (!impa7_map[i].virt) {
			printk(MSG_PREFIX "failed to ioremap\n");
			return -EIO;
		}
		simple_map_init(&impa7_map[i]);

		impa7_mtd[i] = 0;
		type = rom_probe_types;
		for(; !impa7_mtd[i] && *type; type++) {
			impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]);
		}

		if (impa7_mtd[i]) {
			impa7_mtd[i]->owner = THIS_MODULE;
			devicesfound++;
			mtd_device_parse_register(impa7_mtd[i], NULL, NULL,
						  partitions,
						  ARRAY_SIZE(partitions));
		}
		else
			iounmap((void *)impa7_map[i].virt);
	}
	return devicesfound == 0 ? -ENXIO : 0;
}
static int __init cs553x_init(void)
{
	int err = -ENXIO;
	int i;
	uint64_t val;

	
	if (!is_geode())
		return -ENXIO;

	
	rdmsrl(MSR_DIVIL_GLD_CAP, val);
	val &= ~0xFFULL;
	if (val != CAP_CS5535 && val != CAP_CS5536)
		return -ENXIO;

	
	rdmsrl(MSR_DIVIL_BALL_OPTS, val);
	if (val & PIN_OPT_IDE) {
		printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
		return -ENXIO;
	}

	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
		rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);

		if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
			err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
	}

	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
		if (cs553x_mtd[i]) {
			
			mtd_device_parse_register(cs553x_mtd[i], NULL, NULL,
						  NULL, 0);
			err = 0;
		}
	}

	return err;
}
Beispiel #15
0
static int bcm47xxnflash_probe(struct platform_device *pdev)
{
	struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
	struct bcm47xxnflash *b47n;
	struct mtd_info *mtd;
	int err = 0;

	b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL);
	if (!b47n)
		return -ENOMEM;

	nand_set_controller_data(&b47n->nand_chip, b47n);
	mtd = nand_to_mtd(&b47n->nand_chip);
	mtd->dev.parent = &pdev->dev;
	b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash);

	if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
		err = bcm47xxnflash_ops_bcm4706_init(b47n);
	} else {
		pr_err("Device not supported\n");
		err = -ENOTSUPP;
	}
	if (err) {
		pr_err("Initialization failed: %d\n", err);
		return err;
	}

	platform_set_drvdata(pdev, b47n);

	err = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
	if (err) {
		pr_err("Failed to register MTD device: %d\n", err);
		return err;
	}

	return 0;
}
Beispiel #16
0
static int physmap_flash_probe(struct platform_device *dev)
{
	struct physmap_flash_data *physmap_data;
	struct physmap_flash_info *info;
	const char **probe_type;
	const char **part_types;
	int err = 0;
	int i;
	int devices_found = 0;

	physmap_data = dev->dev.platform_data;
	if (physmap_data == NULL)
		return -ENODEV;

	info = devm_kzalloc(&dev->dev, sizeof(struct physmap_flash_info),
			    GFP_KERNEL);
	if (info == NULL) {
		err = -ENOMEM;
		goto err_out;
	}

	if (physmap_data->init) {
		err = physmap_data->init(dev);
		if (err)
			goto err_out;
	}

	platform_set_drvdata(dev, info);

	for (i = 0; i < dev->num_resources; i++) {
		printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
		       (unsigned long long)resource_size(&dev->resource[i]),
		       (unsigned long long)dev->resource[i].start);

		if (!devm_request_mem_region(&dev->dev,
			dev->resource[i].start,
			resource_size(&dev->resource[i]),
			dev_name(&dev->dev))) {
			dev_err(&dev->dev, "Could not reserve memory region\n");
			err = -ENOMEM;
			goto err_out;
		}

		info->map[i].name = dev_name(&dev->dev);
		info->map[i].phys = dev->resource[i].start;
		info->map[i].size = resource_size(&dev->resource[i]);
		info->map[i].bankwidth = physmap_data->width;
		info->map[i].set_vpp = physmap_set_vpp;
		info->map[i].pfow_base = physmap_data->pfow_base;
		info->map[i].map_priv_1 = (unsigned long)dev;

		info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys,
						 info->map[i].size);
		if (info->map[i].virt == NULL) {
			dev_err(&dev->dev, "Failed to ioremap flash region\n");
			err = -EIO;
			goto err_out;
		}

		simple_map_init(&info->map[i]);

		probe_type = rom_probe_types;
		if (physmap_data->probe_type == NULL) {
			for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
				info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
		} else
			info->mtd[i] = do_map_probe(physmap_data->probe_type, &info->map[i]);

		if (info->mtd[i] == NULL) {
			dev_err(&dev->dev, "map_probe failed\n");
			err = -ENXIO;
			goto err_out;
		} else {
			devices_found++;
		}
		info->mtd[i]->owner = THIS_MODULE;
		info->mtd[i]->dev.parent = &dev->dev;
	}

	if (devices_found == 1) {
		info->cmtd = info->mtd[0];
	} else if (devices_found > 1) {
		/*
		 * We detected multiple devices. Concatenate them together.
		 */
		info->cmtd = mtd_concat_create(info->mtd, devices_found, dev_name(&dev->dev));
		if (info->cmtd == NULL)
			err = -ENXIO;
	}
	if (err)
		goto err_out;

	part_types = physmap_data->part_probe_types ? : part_probe_types;

	mtd_device_parse_register(info->cmtd, part_types, 0,
				  physmap_data->parts, physmap_data->nr_parts);
	return 0;

err_out:
	physmap_flash_remove(dev);
	return err;
}
Beispiel #17
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 (dev_get_platdata(&pdev->dev) == NULL) {
		dev_err(&pdev->dev, "no platform data supplied\n");
		err = -ENOENT;
		goto exit_error;
	}

	pdata = dev_get_platdata(&pdev->dev);

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (info == NULL) {
		err = -ENOMEM;
		goto exit_error;
	}

	platform_set_drvdata(pdev, info);

	info->dev = &pdev->dev;
	info->pdata = pdata;

	/* get the resource for the memory mapping */

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (res == NULL) {
		dev_err(&pdev->dev, "no memory resource specified\n");
		err = -ENOENT;
		goto exit_free;
	}

	dev_dbg(&pdev->dev, "got platform resource %p (0x%llx)\n", res,
		(unsigned long long)res->start);

	/* setup map parameters */

	info->map.phys = res->start;
	info->map.size = resource_size(res);
	info->map.name = pdata->mapname != NULL ?
			(char *)pdata->mapname : (char *)pdev->name;
	info->map.bankwidth = pdata->bankwidth;

	/* register our usage of the memory area */

	info->area = request_mem_region(res->start, info->map.size, pdev->name);
	if (info->area == NULL) {
		dev_err(&pdev->dev, "failed to request memory region\n");
		err = -EIO;
		goto exit_free;
	}

	/* remap the memory area */

	info->map.virt = ioremap(res->start, info->map.size);
	dev_dbg(&pdev->dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);

	if (info->map.virt == NULL) {
		dev_err(&pdev->dev, "failed to ioremap() region\n");
		err = -EIO;
		goto exit_free;
	}

	simple_map_init(&info->map);

	dev_dbg(&pdev->dev, "initialised map, probing for mtd\n");

	/* probe for the right mtd map driver
	 * supplied by the platform_data struct */

	if (pdata->map_probes) {
		const char * const *map_probes = pdata->map_probes;

		for ( ; !info->mtd && *map_probes; map_probes++)
			info->mtd = do_map_probe(*map_probes , &info->map);
	}
	/* fallback to map_ram */
	else
		info->mtd = do_map_probe("map_ram", &info->map);

	if (info->mtd == NULL) {
		dev_err(&pdev->dev, "failed to probe for map_ram\n");
		err = -ENOMEM;
		goto exit_free;
	}

	info->mtd->owner = THIS_MODULE;
	info->mtd->dev.parent = &pdev->dev;

	platram_setrw(info, PLATRAM_RW);

	/* check to see if there are any available partitions, or whether
	 * to add this device whole */

	err = mtd_device_parse_register(info->mtd, pdata->probes, NULL,
					pdata->partitions,
					pdata->nr_partitions);
	if (!err)
		dev_info(&pdev->dev, "registered mtd device\n");

	if (pdata->nr_partitions) {
		/* add the whole device. */
		err = mtd_device_register(info->mtd, NULL, 0);
		if (err) {
			dev_err(&pdev->dev,
				"failed to register the entire device\n");
		}
	}

	return err;

 exit_free:
	platram_remove(pdev);
 exit_error:
	return err;
}
/*
 * Probe for the NAND device.
 */
static int __devinit plat_nand_probe(struct platform_device *pdev)
{
	struct platform_nand_data *pdata = pdev->dev.platform_data;
	struct plat_nand_data *data;
	struct resource *res;
	int err = 0;

	if (pdata->chip.nr_chips < 1) {
		dev_err(&pdev->dev, "invalid number of chips specified\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;

	/* Allocate memory for the device structure (and zero it) */
	data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL);
	if (!data) {
		dev_err(&pdev->dev, "failed to allocate device structure.\n");
		return -ENOMEM;
	}

	if (!request_mem_region(res->start, resource_size(res),
				dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "request_mem_region failed\n");
		err = -EBUSY;
		goto out_free;
	}

	data->io_base = ioremap(res->start, resource_size(res));
	if (data->io_base == NULL) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -EIO;
		goto out_release_io;
	}

	data->chip.priv = &data;
	data->mtd.priv = &data->chip;
	data->mtd.owner = THIS_MODULE;
	data->mtd.name = dev_name(&pdev->dev);

	data->chip.IO_ADDR_R = data->io_base;
	data->chip.IO_ADDR_W = data->io_base;
	data->chip.cmd_ctrl = pdata->ctrl.cmd_ctrl;
	data->chip.dev_ready = pdata->ctrl.dev_ready;
	data->chip.select_chip = pdata->ctrl.select_chip;
	data->chip.write_buf = pdata->ctrl.write_buf;
	data->chip.read_buf = pdata->ctrl.read_buf;
	data->chip.chip_delay = pdata->chip.chip_delay;
	data->chip.options |= pdata->chip.options;
	data->chip.bbt_options |= pdata->chip.bbt_options;

	data->chip.ecc.hwctl = pdata->ctrl.hwcontrol;
	data->chip.ecc.layout = pdata->chip.ecclayout;
	data->chip.ecc.mode = NAND_ECC_SOFT;

	platform_set_drvdata(pdev, data);

	/* Handle any platform specific setup */
	if (pdata->ctrl.probe) {
		err = pdata->ctrl.probe(pdev);
		if (err)
			goto out;
	}

	/* Scan to find existence of the device */
	if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
		err = -ENXIO;
		goto out;
	}

	err = mtd_device_parse_register(&data->mtd,
					pdata->chip.part_probe_types, NULL,
					pdata->chip.partitions,
					pdata->chip.nr_partitions);

	if (!err)
		return err;

	nand_release(&data->mtd);
out:
	if (pdata->ctrl.remove)
		pdata->ctrl.remove(pdev);
	platform_set_drvdata(pdev, NULL);
	iounmap(data->io_base);
out_release_io:
	release_mem_region(res->start, resource_size(res));
out_free:
	kfree(data);
	return err;
}
Beispiel #19
0
static int vr_nor_init_partitions(struct vr_nor_mtd *p)
{
	/* register the flash bank */
	/* partition the flash bank */
	return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0);
}
Beispiel #20
0
/*
 * spinand_probe - [spinand Interface]
 * @spi_nand: registered device driver.
 *
 * Description:
 *   To set up the device driver parameters to make the device available.
 */
static int spinand_probe(struct spi_device *spi_nand)
{
	struct mtd_info *mtd;
	struct nand_chip *chip;
	struct spinand_info *info;
	struct spinand_state *state;
	struct mtd_part_parser_data ppdata;

	info  = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info),
			GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->spi = spi_nand;

	spinand_lock_block(spi_nand, BL_ALL_UNLOCKED);

	state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state),
			GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	info->priv	= state;
	state->buf_ptr	= 0;
	state->buf	= devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL);
	if (!state->buf)
		return -ENOMEM;

	chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip),
			GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

#ifdef CONFIG_MTD_SPINAND_ONDIEECC
	chip->ecc.mode	= NAND_ECC_HW;
	chip->ecc.size	= 0x200;
	chip->ecc.bytes	= 0x6;
	chip->ecc.steps	= 0x4;

	chip->ecc.strength = 1;
	chip->ecc.total	= chip->ecc.steps * chip->ecc.bytes;
	chip->ecc.layout = &spinand_oob_64;
	chip->ecc.read_page = spinand_read_page_hwecc;
	chip->ecc.write_page = spinand_write_page_hwecc;
#else
	chip->ecc.mode	= NAND_ECC_SOFT;
	if (spinand_disable_ecc(spi_nand) < 0)
		pr_info("%s: disable ecc failed!\n", __func__);
#endif

	chip->priv	= info;
	chip->read_buf	= spinand_read_buf;
	chip->write_buf	= spinand_write_buf;
	chip->read_byte	= spinand_read_byte;
	chip->cmdfunc	= spinand_cmdfunc;
	chip->waitfunc	= spinand_wait;
	chip->options	|= NAND_CACHEPRG;
	chip->select_chip = spinand_select_chip;

	mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL);
	if (!mtd)
		return -ENOMEM;

	dev_set_drvdata(&spi_nand->dev, mtd);

	mtd->priv = chip;
	mtd->name = dev_name(&spi_nand->dev);
	mtd->owner = THIS_MODULE;
	mtd->oobsize = 64;

	if (nand_scan(mtd, 1))
		return -ENXIO;

	ppdata.of_node = spi_nand->dev.of_node;
	return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
}
Beispiel #21
0
static int
ltq_mtd_probe(struct platform_device *pdev)
{
	struct mtd_part_parser_data ppdata;
	struct ltq_mtd *ltq_mtd;
	struct cfi_private *cfi;
	int err;

	if (of_machine_is_compatible("lantiq,falcon") &&
			(ltq_boot_select() != BS_FLASH)) {
		dev_err(&pdev->dev, "invalid bootstrap options\n");
		return -ENODEV;
	}

	ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
	if (!ltq_mtd)
		return -ENOMEM;

	platform_set_drvdata(pdev, ltq_mtd);

	ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!ltq_mtd->res) {
		dev_err(&pdev->dev, "failed to get memory resource\n");
		return -ENOENT;
	}

	ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
				    GFP_KERNEL);
	if (!ltq_mtd->map)
		return -ENOMEM;

	ltq_mtd->map->phys = ltq_mtd->res->start;
	ltq_mtd->map->size = resource_size(ltq_mtd->res);
	ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
	if (IS_ERR(ltq_mtd->map->virt))
		return PTR_ERR(ltq_mtd->map->virt);

	ltq_mtd->map->name = ltq_map_name;
	ltq_mtd->map->bankwidth = 2;
	ltq_mtd->map->read = ltq_read16;
	ltq_mtd->map->write = ltq_write16;
	ltq_mtd->map->copy_from = ltq_copy_from;
	ltq_mtd->map->copy_to = ltq_copy_to;

	ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
	ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
	ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;

	if (!ltq_mtd->mtd) {
		dev_err(&pdev->dev, "probing failed\n");
		return -ENXIO;
	}

	ltq_mtd->mtd->owner = THIS_MODULE;

	cfi = ltq_mtd->map->fldrv_priv;
	cfi->addr_unlock1 ^= 1;
	cfi->addr_unlock2 ^= 1;

	ppdata.of_node = pdev->dev.of_node;
	err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types,
					&ppdata, NULL, 0);
	if (err) {
		dev_err(&pdev->dev, "failed to add partitions\n");
		goto err_destroy;
	}

	return 0;

err_destroy:
	map_destroy(ltq_mtd->mtd);
	return err;
}
Beispiel #22
0
static int tmio_probe(struct platform_device *dev)
{
	struct tmio_nand_data *data = dev_get_platdata(&dev->dev);
	struct resource *fcr = platform_get_resource(dev,
			IORESOURCE_MEM, 0);
	struct resource *ccr = platform_get_resource(dev,
			IORESOURCE_MEM, 1);
	int irq = platform_get_irq(dev, 0);
	struct tmio_nand *tmio;
	struct mtd_info *mtd;
	struct nand_chip *nand_chip;
	int retval;

	if (data == NULL)
		dev_warn(&dev->dev, "NULL platform data!\n");

	tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
	if (!tmio) {
		retval = -ENOMEM;
		goto err_kzalloc;
	}

	tmio->dev = dev;

	platform_set_drvdata(dev, tmio);
	mtd = &tmio->mtd;
	nand_chip = &tmio->chip;
	mtd->priv = nand_chip;
	mtd->name = "tmio-nand";

	tmio->ccr = ioremap(ccr->start, resource_size(ccr));
	if (!tmio->ccr) {
		retval = -EIO;
		goto err_iomap_ccr;
	}

	tmio->fcr_base = fcr->start & 0xfffff;
	tmio->fcr = ioremap(fcr->start, resource_size(fcr));
	if (!tmio->fcr) {
		retval = -EIO;
		goto err_iomap_fcr;
	}

	retval = tmio_hw_init(dev, tmio);
	if (retval)
		goto err_hwinit;

	/* Set address of NAND IO lines */
	nand_chip->IO_ADDR_R = tmio->fcr;
	nand_chip->IO_ADDR_W = tmio->fcr;

	/* Set address of hardware control function */
	nand_chip->cmd_ctrl = tmio_nand_hwcontrol;
	nand_chip->dev_ready = tmio_nand_dev_ready;
	nand_chip->read_byte = tmio_nand_read_byte;
	nand_chip->write_buf = tmio_nand_write_buf;
	nand_chip->read_buf = tmio_nand_read_buf;

	/* set eccmode using hardware ECC */
	nand_chip->ecc.mode = NAND_ECC_HW;
	nand_chip->ecc.size = 512;
	nand_chip->ecc.bytes = 6;
	nand_chip->ecc.strength = 2;
	nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
	nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
	nand_chip->ecc.correct = tmio_nand_correct_data;

	if (data)
		nand_chip->badblock_pattern = data->badblock_pattern;

	/* 15 us command delay time */
	nand_chip->chip_delay = 15;

	retval = request_irq(irq, &tmio_irq,
				IRQF_DISABLED, dev_name(&dev->dev), tmio);
	if (retval) {
		dev_err(&dev->dev, "request_irq error %d\n", retval);
		goto err_irq;
	}

	tmio->irq = irq;
	nand_chip->waitfunc = tmio_nand_wait;

	/* Scan to find existence of the device */
	if (nand_scan(mtd, 1)) {
		retval = -ENODEV;
		goto err_scan;
	}
	/* Register the partitions */
	retval = mtd_device_parse_register(mtd, NULL, NULL,
					   data ? data->partition : NULL,
					   data ? data->num_partitions : 0);
	if (!retval)
		return retval;

	nand_release(mtd);

err_scan:
	if (tmio->irq)
		free_irq(tmio->irq, tmio);
err_irq:
	tmio_hw_stop(dev, tmio);
err_hwinit:
	iounmap(tmio->fcr);
err_iomap_fcr:
	iounmap(tmio->ccr);
err_iomap_ccr:
	kfree(tmio);
err_kzalloc:
	return retval;
}
static int __init txx9ndfmc_probe(struct platform_device *dev)
{
	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
	int hold, spw;
	int i;
	struct txx9ndfmc_drvdata *drvdata;
	unsigned long gbusclk = plat->gbus_clock;
	struct resource *res;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;
	drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;
	drvdata->base = devm_ioremap_resource(&dev->dev, res);
	if (IS_ERR(drvdata->base))
		return PTR_ERR(drvdata->base);

	hold = plat->hold ?: 20; /* tDH */
	spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */

	hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
	spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
	if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
		hold -= 2;	/* actual hold time : (HOLD + 2) BUSCLK */
	spw -= 1;	/* actual wait time : (SPW + 1) BUSCLK */
	hold = clamp(hold, 1, 15);
	drvdata->hold = hold;
	spw = clamp(spw, 1, 15);
	drvdata->spw = spw;
	dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
		 (gbusclk + 500000) / 1000000, hold, spw);

	spin_lock_init(&drvdata->hw_control.lock);
	init_waitqueue_head(&drvdata->hw_control.wq);

	platform_set_drvdata(dev, drvdata);
	txx9ndfmc_initialize(dev);

	for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
		struct txx9ndfmc_priv *txx9_priv;
		struct nand_chip *chip;
		struct mtd_info *mtd;

		if (!(plat->ch_mask & (1 << i)))
			continue;
		txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
				    GFP_KERNEL);
		if (!txx9_priv) {
			dev_err(&dev->dev, "Unable to allocate "
				"TXx9 NDFMC MTD device structure.\n");
			continue;
		}
		chip = &txx9_priv->chip;
		mtd = &txx9_priv->mtd;
		mtd->owner = THIS_MODULE;

		mtd->priv = chip;

		chip->read_byte = txx9ndfmc_read_byte;
		chip->read_buf = txx9ndfmc_read_buf;
		chip->write_buf = txx9ndfmc_write_buf;
		chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
		chip->dev_ready = txx9ndfmc_dev_ready;
		chip->ecc.calculate = txx9ndfmc_calculate_ecc;
		chip->ecc.correct = txx9ndfmc_correct_data;
		chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
		chip->ecc.mode = NAND_ECC_HW;
		/* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */
		chip->ecc.size = 256;
		chip->ecc.bytes = 3;
		chip->ecc.strength = 1;
		chip->chip_delay = 100;
		chip->controller = &drvdata->hw_control;

		chip->priv = txx9_priv;
		txx9_priv->dev = dev;

		if (plat->ch_mask != 1) {
			txx9_priv->cs = i;
			txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u",
						       dev_name(&dev->dev), i);
		} else {
			txx9_priv->cs = -1;
			txx9_priv->mtdname = kstrdup(dev_name(&dev->dev),
						     GFP_KERNEL);
		}
		if (!txx9_priv->mtdname) {
			kfree(txx9_priv);
			dev_err(&dev->dev, "Unable to allocate MTD name.\n");
			continue;
		}
		if (plat->wide_mask & (1 << i))
			chip->options |= NAND_BUSWIDTH_16;

		if (txx9ndfmc_nand_scan(mtd)) {
			kfree(txx9_priv->mtdname);
			kfree(txx9_priv);
			continue;
		}
		mtd->name = txx9_priv->mtdname;

		mtd_device_parse_register(mtd, NULL, NULL, NULL, 0);
		drvdata->mtds[i] = mtd;
	}

	return 0;
}
Beispiel #24
0
/*
 * Probe for NAND controller
 */
static int lpc32xx_nand_probe(struct platform_device *pdev)
{
	struct lpc32xx_nand_host *host;
	struct mtd_info *mtd;
	struct nand_chip *chip;
	struct resource *rc;
	struct mtd_part_parser_data ppdata = {};
	int res;

	rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (rc == NULL) {
		dev_err(&pdev->dev, "No memory resource found for device\n");
		return -EBUSY;
	}

	/* Allocate memory for the device structure (and zero it) */
	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
	if (!host)
		return -ENOMEM;
	host->io_base_dma = rc->start;

	host->io_base = devm_ioremap_resource(&pdev->dev, rc);
	if (IS_ERR(host->io_base))
		return PTR_ERR(host->io_base);

	if (pdev->dev.of_node)
		host->ncfg = lpc32xx_parse_dt(&pdev->dev);
	if (!host->ncfg) {
		dev_err(&pdev->dev,
			"Missing or bad NAND config from device tree\n");
		return -ENOENT;
	}
	if (host->ncfg->wp_gpio == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev,
			host->ncfg->wp_gpio, "NAND WP")) {
		dev_err(&pdev->dev, "GPIO not available\n");
		return -EBUSY;
	}
	lpc32xx_wp_disable(host);

	host->pdata = dev_get_platdata(&pdev->dev);

	mtd = &host->mtd;
	chip = &host->nand_chip;
	chip->priv = host;
	mtd->priv = chip;
	mtd->owner = THIS_MODULE;
	mtd->dev.parent = &pdev->dev;

	/* Get NAND clock */
	host->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(host->clk)) {
		dev_err(&pdev->dev, "Clock failure\n");
		res = -ENOENT;
		goto err_exit1;
	}
	clk_enable(host->clk);

	/* Set NAND IO addresses and command/ready functions */
	chip->IO_ADDR_R = SLC_DATA(host->io_base);
	chip->IO_ADDR_W = SLC_DATA(host->io_base);
	chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
	chip->dev_ready = lpc32xx_nand_device_ready;
	chip->chip_delay = 20; /* 20us command delay time */

	/* Init NAND controller */
	lpc32xx_nand_setup(host);

	platform_set_drvdata(pdev, host);

	/* NAND callbacks for LPC32xx SLC hardware */
	chip->ecc.mode = NAND_ECC_HW_SYNDROME;
	chip->read_byte = lpc32xx_nand_read_byte;
	chip->read_buf = lpc32xx_nand_read_buf;
	chip->write_buf = lpc32xx_nand_write_buf;
	chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome;
	chip->ecc.read_page = lpc32xx_nand_read_page_syndrome;
	chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome;
	chip->ecc.write_page = lpc32xx_nand_write_page_syndrome;
	chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
	chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
	chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
	chip->ecc.correct = nand_correct_data;
	chip->ecc.strength = 1;
	chip->ecc.hwctl = lpc32xx_nand_ecc_enable;

	/*
	 * Allocate a large enough buffer for a single huge page plus
	 * extra space for the spare area and ECC storage area
	 */
	host->dma_buf_len = LPC32XX_DMA_DATA_SIZE + LPC32XX_ECC_SAVE_SIZE;
	host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len,
				      GFP_KERNEL);
	if (host->data_buf == NULL) {
		res = -ENOMEM;
		goto err_exit2;
	}

	res = lpc32xx_nand_dma_setup(host);
	if (res) {
		res = -EIO;
		goto err_exit2;
	}

	/* Find NAND device */
	if (nand_scan_ident(mtd, 1, NULL)) {
		res = -ENXIO;
		goto err_exit3;
	}

	/* OOB and ECC CPU and DMA work areas */
	host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE);

	/*
	 * Small page FLASH has a unique OOB layout, but large and huge
	 * page FLASH use the standard layout. Small page FLASH uses a
	 * custom BBT marker layout.
	 */
	if (mtd->writesize <= 512)
		chip->ecc.layout = &lpc32xx_nand_oob_16;

	/* These sizes remain the same regardless of page size */
	chip->ecc.size = 256;
	chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES;
	chip->ecc.prepad = chip->ecc.postpad = 0;

	/* Avoid extra scan if using BBT, setup BBT support */
	if (host->ncfg->use_bbt) {
		chip->bbt_options |= NAND_BBT_USE_FLASH;

		/*
		 * Use a custom BBT marker setup for small page FLASH that
		 * won't interfere with the ECC layout. Large and huge page
		 * FLASH use the standard layout.
		 */
		if (mtd->writesize <= 512) {
			chip->bbt_td = &bbt_smallpage_main_descr;
			chip->bbt_md = &bbt_smallpage_mirror_descr;
		}
	}

	/*
	 * Fills out all the uninitialized function pointers with the defaults
	 */
	if (nand_scan_tail(mtd)) {
		res = -ENXIO;
		goto err_exit3;
	}

	mtd->name = "nxp_lpc3220_slc";
	ppdata.of_node = pdev->dev.of_node;
	res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
					host->ncfg->num_parts);
	if (!res)
		return res;

	nand_release(mtd);

err_exit3:
	dma_release_channel(host->dma_chan);
err_exit2:
	clk_disable(host->clk);
err_exit1:
	lpc32xx_wp_enable(host);

	return res;
}
static int latch_addr_flash_probe(struct platform_device *dev)
{
	struct latch_addr_flash_data *latch_addr_data;
	struct latch_addr_flash_info *info;
	resource_size_t win_base = dev->resource->start;
	resource_size_t win_size = resource_size(dev->resource);
	char **probe_type;
	int chipsel;
	int err;

	latch_addr_data = dev->dev.platform_data;
	if (latch_addr_data == NULL)
		return -ENODEV;

	pr_notice("latch-addr platform flash device: %#llx byte "
		  "window at %#.8llx\n",
		  (unsigned long long)win_size, (unsigned long long)win_base);

	chipsel = dev->id;

	if (latch_addr_data->init) {
		err = latch_addr_data->init(latch_addr_data->data, chipsel);
		if (err != 0)
			return err;
	}

	info = kzalloc(sizeof(struct latch_addr_flash_info), GFP_KERNEL);
	if (info == NULL) {
		err = -ENOMEM;
		goto done;
	}

	platform_set_drvdata(dev, info);

	info->res = request_mem_region(win_base, win_size, DRIVER_NAME);
	if (info->res == NULL) {
		dev_err(&dev->dev, "Could not reserve memory region\n");
		err = -EBUSY;
		goto free_info;
	}

	info->map.name		= DRIVER_NAME;
	info->map.size		= latch_addr_data->size;
	info->map.bankwidth	= latch_addr_data->width;

	info->map.phys		= NO_XIP;
	info->map.virt		= ioremap(win_base, win_size);
	if (!info->map.virt) {
		err = -ENOMEM;
		goto free_res;
	}

	info->map.map_priv_1	= (unsigned long)info;

	info->map.read		= lf_read;
	info->map.copy_from	= lf_copy_from;
	info->map.write		= lf_write;
	info->set_window	= latch_addr_data->set_window;
	info->data		= latch_addr_data->data;
	info->win_mask		= win_size - 1;

	spin_lock_init(&info->lock);

	for (probe_type = rom_probe_types; !info->mtd && *probe_type;
		probe_type++)
		info->mtd = do_map_probe(*probe_type, &info->map);

	if (info->mtd == NULL) {
		dev_err(&dev->dev, "map_probe failed\n");
		err = -ENODEV;
		goto iounmap;
	}
	info->mtd->owner = THIS_MODULE;

	mtd_device_parse_register(info->mtd, NULL, NULL,
				  latch_addr_data->parts,
				  latch_addr_data->nr_parts);
	return 0;

iounmap:
	iounmap(info->map.virt);
free_res:
	release_mem_region(info->res->start, resource_size(info->res));
free_info:
	kfree(info);
done:
	if (latch_addr_data->done)
		latch_addr_data->done(latch_addr_data->data);
	return err;
}
static int __devinit gpio_flash_probe(struct platform_device *pdev)
{
	size_t i, arr_size;
	struct physmap_flash_data *pdata;
	struct resource *memory;
	struct resource *gpios;
	struct async_state *state;

	pdata = pdev->dev.platform_data;
	memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	gpios = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

	if (!memory || !gpios || !gpios->end)
		return -EINVAL;

	arr_size = sizeof(int) * gpios->end;
	state = kzalloc(sizeof(*state) + arr_size, GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	state->gpio_count     = gpios->end;
	state->gpio_addrs     = (void *)(unsigned long)gpios->start;
	state->gpio_values    = (void *)(state + 1);
	state->win_size       = resource_size(memory);
	memset(state->gpio_values, 0xff, arr_size);

	state->map.name       = DRIVER_NAME;
	state->map.read       = gf_read;
	state->map.copy_from  = gf_copy_from;
	state->map.write      = gf_write;
	state->map.copy_to    = gf_copy_to;
	state->map.bankwidth  = pdata->width;
	state->map.size       = state->win_size * (1 << state->gpio_count);
	state->map.virt       = ioremap_nocache(memory->start, state->map.size);
	state->map.phys       = NO_XIP;
	state->map.map_priv_1 = (unsigned long)state;

	platform_set_drvdata(pdev, state);

	i = 0;
	do {
		if (gpio_request(state->gpio_addrs[i], DRIVER_NAME)) {
			pr_devinit(KERN_ERR PFX "failed to request gpio %d\n",
				state->gpio_addrs[i]);
			while (i--)
				gpio_free(state->gpio_addrs[i]);
			kfree(state);
			return -EBUSY;
		}
		gpio_direction_output(state->gpio_addrs[i], 0);
	} while (++i < state->gpio_count);

	pr_devinit(KERN_NOTICE PFX "probing %d-bit flash bus\n",
		state->map.bankwidth * 8);
	state->mtd = do_map_probe(memory->name, &state->map);
	if (!state->mtd) {
		for (i = 0; i < state->gpio_count; ++i)
			gpio_free(state->gpio_addrs[i]);
		kfree(state);
		return -ENXIO;
	}


	mtd_device_parse_register(state->mtd, part_probe_types, NULL,
				  pdata->parts, pdata->nr_parts);

	return 0;
}
Beispiel #27
0
static int ixp4xx_flash_probe(struct platform_device *dev)
{
	struct flash_platform_data *plat = dev->dev.platform_data;
	struct ixp4xx_flash_info *info;
	int err = -1;

	if (!plat)
		return -ENODEV;

	if (plat->init) {
		err = plat->init();
		if (err)
			return err;
	}

	info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL);
	if(!info) {
		err = -ENOMEM;
		goto Error;
	}

	platform_set_drvdata(dev, info);

	/*
	 * Tell the MTD layer we're not 1:1 mapped so that it does
	 * not attempt to do a direct access on us.
	 */
	info->map.phys = NO_XIP;
	info->map.size = resource_size(dev->resource);

	/*
	 * We only support 16-bit accesses for now. If and when
	 * any board use 8-bit access, we'll fixup the driver to
	 * handle that.
	 */
	info->map.bankwidth = 2;
	info->map.name = dev_name(&dev->dev);
	info->map.read = ixp4xx_read16;
	info->map.write = ixp4xx_probe_write16;
	info->map.copy_from = ixp4xx_copy_from;

	info->res = request_mem_region(dev->resource->start,
			resource_size(dev->resource),
			"IXP4XXFlash");
	if (!info->res) {
		printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
		err = -ENOMEM;
		goto Error;
	}

	info->map.virt = ioremap(dev->resource->start,
				 resource_size(dev->resource));
	if (!info->map.virt) {
		printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
		err = -EIO;
		goto Error;
	}

	info->mtd = do_map_probe(plat->map_name, &info->map);
	if (!info->mtd) {
		printk(KERN_ERR "IXP4XXFlash: map_probe failed\n");
		err = -ENXIO;
		goto Error;
	}
	info->mtd->owner = THIS_MODULE;

	/* Use the fast version */
	info->map.write = ixp4xx_write16;

	err = mtd_device_parse_register(info->mtd, probes, dev->resource->start,
			plat->parts, plat->nr_parts);
	if (err) {
		printk(KERN_ERR "Could not parse partitions\n");
		goto Error;
	}

	return 0;

Error:
	ixp4xx_flash_remove(dev);
	return err;
}
Beispiel #28
0
static int omap2_onenand_probe(struct platform_device *pdev)
{
	struct omap_onenand_platform_data *pdata;
	struct omap2_onenand *c;
	struct onenand_chip *this;
	int r;
	struct resource *res;
	struct mtd_part_parser_data ppdata = {};

	pdata = dev_get_platdata(&pdev->dev);
	if (pdata == NULL) {
		dev_err(&pdev->dev, "platform data missing\n");
		return -ENODEV;
	}

	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
	if (!c)
		return -ENOMEM;

	init_completion(&c->irq_done);
	init_completion(&c->dma_done);
	c->flags = pdata->flags;
	c->gpmc_cs = pdata->cs;
	c->gpio_irq = pdata->gpio_irq;
	c->dma_channel = pdata->dma_channel;
	if (c->dma_channel < 0) {
		/* if -1, don't use DMA */
		c->gpio_irq = 0;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		r = -EINVAL;
		dev_err(&pdev->dev, "error getting memory resource\n");
		goto err_kfree;
	}

	c->phys_base = res->start;
	c->mem_size = resource_size(res);

	if (request_mem_region(c->phys_base, c->mem_size,
			       pdev->dev.driver->name) == NULL) {
		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
						c->phys_base, c->mem_size);
		r = -EBUSY;
		goto err_kfree;
	}
	c->onenand.base = ioremap(c->phys_base, c->mem_size);
	if (c->onenand.base == NULL) {
		r = -ENOMEM;
		goto err_release_mem_region;
	}

	if (pdata->onenand_setup != NULL) {
		r = pdata->onenand_setup(c->onenand.base, &c->freq);
		if (r < 0) {
			dev_err(&pdev->dev, "Onenand platform setup failed: "
				"%d\n", r);
			goto err_iounmap;
		}
		c->setup = pdata->onenand_setup;
	}

	if (c->gpio_irq) {
		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
				"OneNAND\n", c->gpio_irq);
			goto err_iounmap;
	}
	gpio_direction_input(c->gpio_irq);

	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
			     pdev->dev.driver->name, c)) < 0)
		goto err_release_gpio;
	}

	if (c->dma_channel >= 0) {
		r = omap_request_dma(0, pdev->dev.driver->name,
				     omap2_onenand_dma_cb, (void *) c,
				     &c->dma_channel);
		if (r == 0) {
			omap_set_dma_write_mode(c->dma_channel,
						OMAP_DMA_WRITE_NON_POSTED);
			omap_set_dma_src_data_pack(c->dma_channel, 1);
			omap_set_dma_src_burst_mode(c->dma_channel,
						    OMAP_DMA_DATA_BURST_8);
			omap_set_dma_dest_data_pack(c->dma_channel, 1);
			omap_set_dma_dest_burst_mode(c->dma_channel,
						     OMAP_DMA_DATA_BURST_8);
		} else {
			dev_info(&pdev->dev,
				 "failed to allocate DMA for OneNAND, "
				 "using PIO instead\n");
			c->dma_channel = -1;
		}
	}

	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
		 c->onenand.base, c->freq);

	c->pdev = pdev;
	c->mtd.name = dev_name(&pdev->dev);
	c->mtd.priv = &c->onenand;
	c->mtd.owner = THIS_MODULE;

	c->mtd.dev.parent = &pdev->dev;

	this = &c->onenand;
	if (c->dma_channel >= 0) {
		this->wait = omap2_onenand_wait;
		if (c->flags & ONENAND_IN_OMAP34XX) {
			this->read_bufferram = omap3_onenand_read_bufferram;
			this->write_bufferram = omap3_onenand_write_bufferram;
		} else {
			this->read_bufferram = omap2_onenand_read_bufferram;
			this->write_bufferram = omap2_onenand_write_bufferram;
		}
	}

	if (pdata->regulator_can_sleep) {
		c->regulator = regulator_get(&pdev->dev, "vonenand");
		if (IS_ERR(c->regulator)) {
			dev_err(&pdev->dev,  "Failed to get regulator\n");
			r = PTR_ERR(c->regulator);
			goto err_release_dma;
		}
		c->onenand.enable = omap2_onenand_enable;
		c->onenand.disable = omap2_onenand_disable;
	}

	if (pdata->skip_initial_unlocking)
		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;

	if ((r = onenand_scan(&c->mtd, 1)) < 0)
		goto err_release_regulator;

	ppdata.of_node = pdata->of_node;
	r = mtd_device_parse_register(&c->mtd, NULL, &ppdata,
				      pdata ? pdata->parts : NULL,
				      pdata ? pdata->nr_parts : 0);
	if (r)
		goto err_release_onenand;

	platform_set_drvdata(pdev, c);

	return 0;

err_release_onenand:
	onenand_release(&c->mtd);
err_release_regulator:
	regulator_put(c->regulator);
err_release_dma:
	if (c->dma_channel != -1)
		omap_free_dma(c->dma_channel);
	if (c->gpio_irq)
		free_irq(gpio_to_irq(c->gpio_irq), c);
err_release_gpio:
	if (c->gpio_irq)
		gpio_free(c->gpio_irq);
err_iounmap:
	iounmap(c->onenand.base);
err_release_mem_region:
	release_mem_region(c->phys_base, c->mem_size);
err_kfree:
	kfree(c);

	return r;
}
static int __init init_sbc82xx_flash(void)
{
	volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
	int bigflash;
	int i;

#ifdef CONFIG_SBC8560
	mc = ioremap(0xff700000 + 0x5000, sizeof(memctl_cpm2_t));
#else
	mc = &cpm2_immr->im_memctl;
#endif

	bigflash = 1;
	if ((mc->memc_br0 & 0x00001800) == 0x00001800)
		bigflash = 0;

	init_sbc82xx_one_flash(sbc82xx_flash_map[0], mc->memc_br0, mc->memc_or0);
	init_sbc82xx_one_flash(sbc82xx_flash_map[1], mc->memc_br6, mc->memc_or6);
	init_sbc82xx_one_flash(sbc82xx_flash_map[2], mc->memc_br1, mc->memc_or1);

#ifdef CONFIG_SBC8560
	iounmap((void *) mc);
#endif

	for (i=0; i<3; i++) {
		int8_t flashcs[3] = { 0, 6, 1 };
		int nr_parts;
		struct mtd_partition *defparts;

		printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
		       sbc82xx_flash_map[i].name,
		       (sbc82xx_flash_map[i].size >> 20),
		       flashcs[i]);
		if (!sbc82xx_flash_map[i].phys) {
			/* We know it can't be at zero. */
			printk("): disabled by bootloader.\n");
			continue;
		}
		printk(" at %08lx)\n",  sbc82xx_flash_map[i].phys);

		sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
						    sbc82xx_flash_map[i].size);

		if (!sbc82xx_flash_map[i].virt) {
			printk("Failed to ioremap\n");
			continue;
		}

		simple_map_init(&sbc82xx_flash_map[i]);

		sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]);

		if (!sbcmtd[i])
			continue;

		sbcmtd[i]->owner = THIS_MODULE;

		/* No partitioning detected. Use default */
		if (i == 2) {
			defparts = NULL;
			nr_parts = 0;
		} else if (i == bigflash) {
			defparts = bigflash_parts;
			nr_parts = ARRAY_SIZE(bigflash_parts);
		} else {
			defparts = smallflash_parts;
			nr_parts = ARRAY_SIZE(smallflash_parts);
		}

		mtd_device_parse_register(sbcmtd[i], part_probes, NULL,
					  defparts, nr_parts);
	}
	return 0;
}
Beispiel #30
0
static int nand_probe(struct platform_device *pdev)
{
	struct nxp_nand_plat_data *pdata = dev_get_platdata(&pdev->dev);
	struct nxp_nand  *nxp;
	struct mtd_info  *mtd;
	struct nand_chip *chip;
	int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
	int chip_delay = !pdata ? 15 : (pdata->chip_delay ? pdata->chip_delay : 15);
#ifdef CFG_NAND_ECCIRQ_MODE
	int irq = 0; /* platform_get_irq(pdev, 0); */
#endif
	int ret = 0;

	if (pdata == NULL)
		dev_warn(&pdev->dev, "NULL platform data!\n");

	nxp = kzalloc(sizeof (*nxp), GFP_KERNEL);
	if (!nxp) {
		printk(KERN_ERR "NAND: failed to allocate device structure.\n");
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	nxp->pdev = pdev;

	platform_set_drvdata(pdev, nxp);
	mtd = &nxp->mtd;
	chip = &nxp->chip;
	mtd->priv = chip;
	mtd->name = DEV_NAME_NAND;
	mtd->owner = THIS_MODULE;

	nand_dev_init(mtd);

	/* insert callbacks */
	chip->IO_ADDR_R 	= (void __iomem *)__PB_IO_MAP_NAND_VIRT;
	chip->IO_ADDR_W 	= (void __iomem *)__PB_IO_MAP_NAND_VIRT;
	chip->cmd_ctrl 		= nand_cmd_ctrl;
	chip->dev_ready 	= nand_dev_ready;
	chip->select_chip 	= nand_select_chip;
	chip->chip_delay 	= chip_delay;
//	chip->read_buf 		= nand_read_buf;
//	chip->write_buf 	= nand_write_buf;
#if defined (CONFIG_MTD_NAND_ECC_BCH)
//	chip->write_page	= nand_bch_write_page;
#endif

#if defined (CONFIG_MTD_NAND_ECC_HW)
	ret = nand_hw_ecc_init_device(mtd);
	printk(KERN_INFO "NAND ecc: Hardware (delay %d)\n", chip_delay);
#elif defined (CONFIG_MTD_NAND_ECC_BCH)
	chip->ecc.mode 	 = NAND_ECC_SOFT_BCH;

	/* refer to nand_ecc.c */
	switch (ECC_BCH_BITS) {
	case  4: chip->ecc.bytes =   7; chip->ecc.size  =  512; break;
	case  8: chip->ecc.bytes =  13; chip->ecc.size  =  512; break;
	case 12: chip->ecc.bytes =  20; chip->ecc.size  =  512; break;
	case 16: chip->ecc.bytes =  26; chip->ecc.size  =  512; break;
	case 24: chip->ecc.bytes =  42; chip->ecc.size  = 1024; break;
	case 40: chip->ecc.bytes =  70; chip->ecc.size  = 1024; break;
//	case 60: chip->ecc.bytes = 105; chip->ecc.size  = 1024; break;	/* not test */
	default:
		printk("Fail: not supoort bch ecc %d mode !!!\n", ECC_BCH_BITS);
		ret = -1;
		goto err_something;
	}
	printk(KERN_INFO "NAND ecc: Software BCH (delay %d)\n", chip_delay);
#else
	chip->ecc.mode  = NAND_ECC_SOFT;
	printk(KERN_INFO "NAND ecc: Software (delay %d)\n", chip_delay);
#endif

	printk(KERN_NOTICE "Scanning NAND device ...\n");
	if (nand_scan(mtd, maxchips)) {
		ret = -ENXIO;
		goto err_something;
	}

	if (nand_ecc_layout_check(mtd)){
		ret = -ENXIO;
		goto err_something;
	}

#ifdef CFG_NAND_ECCIRQ_MODE
	ret = request_irq(irq, nxp_irq, 0, DEV_NAME_NAND, nxp);
    if (ret < 0) {
        pr_err("%s: failed to request_irq(%d)\n", __func__, 0);
		ret = -ENODEV;
		goto err_something;
    }

	nxp->irq = irq;
#endif

	/* set command partition */
	ret = mtd_device_parse_register(mtd, NULL, 0, pdata->parts, pdata->nr_parts);
	if (ret) {
		nand_release(mtd);
		goto err_something;
	} else {
//		platform_set_drvdata(pdev, chip);
	}

#ifdef CONFIG_NAND_RANDOMIZER
	nxp->pages_per_block_mask = (mtd->erasesize/mtd->writesize) - 1;
	if (!nxp->randomize_buf)
		nxp->randomize_buf = kzalloc(mtd->writesize, GFP_KERNEL);
	if (!nxp->randomize_buf) {
		ERROUT("randomize buffer alloc failed\n");
		goto err_something;
	}
#endif
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
	if (!nxp->verify_page)
		nxp->verify_page = kzalloc(NAND_MAX_PAGESIZE, GFP_KERNEL);
	if (!nxp->verify_page) {
		ERROUT("verify buffer alloc failed\n");
		goto err_something;
	}
#endif

	nxp_nand_timing_set(mtd);

	printk(KERN_NOTICE "%s: Nand partition \n", ret?"FAIL":"DONE");
	return ret;

err_something:
#ifdef CONFIG_NAND_RANDOMIZER
	if (nxp->randomize_buf)
		kfree (nxp->randomize_buf);
#endif
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
	if (nxp->verify_page)
		kfree (nxp->verify_page);
#endif
	kfree(nxp);
err_kzalloc:
	return ret;
}