diff options
Diffstat (limited to 'drivers/mtd/nand/plat_nand.c')
| -rw-r--r-- | drivers/mtd/nand/plat_nand.c | 125 | 
1 files changed, 43 insertions, 82 deletions
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 317aff428e4..0b068a5c0bf 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -9,6 +9,7 @@   *   */ +#include <linux/err.h>  #include <linux/io.h>  #include <linux/module.h>  #include <linux/platform_device.h> @@ -21,51 +22,42 @@ struct plat_nand_data {  	struct nand_chip	chip;  	struct mtd_info		mtd;  	void __iomem		*io_base; -#ifdef CONFIG_MTD_PARTITIONS -	int			nr_parts; -	struct mtd_partition	*parts; -#endif  }; +static const char *part_probe_types[] = { "cmdlinepart", NULL }; +  /*   * Probe for the NAND device.   */ -static int __devinit plat_nand_probe(struct platform_device *pdev) +static int plat_nand_probe(struct platform_device *pdev)  { -	struct platform_nand_data *pdata = pdev->dev.platform_data; +	struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); +	struct mtd_part_parser_data ppdata;  	struct plat_nand_data *data;  	struct resource *res; +	const char **part_types;  	int err = 0; +	if (!pdata) { +		dev_err(&pdev->dev, "platform_nand_data is missing\n"); +		return -EINVAL; +	} +  	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"); +	data = devm_kzalloc(&pdev->dev, sizeof(struct plat_nand_data), +			    GFP_KERNEL); +	if (!data)  		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; -	} +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	data->io_base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(data->io_base)) +		return PTR_ERR(data->io_base);  	data->chip.priv = &data;  	data->mtd.priv = &data->chip; @@ -79,8 +71,10 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)  	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.read_byte = pdata->ctrl.read_byte;  	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; @@ -95,31 +89,18 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)  			goto out;  	} -	/* Scan to find existance of the device */ +	/* Scan to find existence of the device */  	if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {  		err = -ENXIO;  		goto out;  	} -#ifdef CONFIG_MTD_PARTITIONS -	if (pdata->chip.part_probe_types) { -		err = parse_mtd_partitions(&data->mtd, -					pdata->chip.part_probe_types, -					&data->parts, 0); -		if (err > 0) { -			add_mtd_partitions(&data->mtd, data->parts, err); -			return 0; -		} -	} -	if (pdata->chip.set_parts) -		pdata->chip.set_parts(data->mtd.size, &pdata->chip); -	if (pdata->chip.partitions) { -		data->parts = pdata->chip.partitions; -		err = add_mtd_partitions(&data->mtd, data->parts, -			pdata->chip.nr_partitions); -	} else -#endif -	err = add_mtd_device(&data->mtd); +	part_types = pdata->chip.part_probe_types ? : part_probe_types; + +	ppdata.of_node = pdev->dev.of_node; +	err = mtd_device_parse_register(&data->mtd, part_types, &ppdata, +					pdata->chip.partitions, +					pdata->chip.nr_partitions);  	if (!err)  		return err; @@ -128,61 +109,41 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)  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;  }  /*   * Remove a NAND device.   */ -static int __devexit plat_nand_remove(struct platform_device *pdev) +static int plat_nand_remove(struct platform_device *pdev)  {  	struct plat_nand_data *data = platform_get_drvdata(pdev); -	struct platform_nand_data *pdata = pdev->dev.platform_data; -	struct resource *res; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev);  	nand_release(&data->mtd); -#ifdef CONFIG_MTD_PARTITIONS -	if (data->parts && data->parts != pdata->chip.partitions) -		kfree(data->parts); -#endif  	if (pdata->ctrl.remove)  		pdata->ctrl.remove(pdev); -	iounmap(data->io_base); -	release_mem_region(res->start, resource_size(res)); -	kfree(data);  	return 0;  } +static const struct of_device_id plat_nand_match[] = { +	{ .compatible = "gen_nand" }, +	{}, +}; +MODULE_DEVICE_TABLE(of, plat_nand_match); +  static struct platform_driver plat_nand_driver = { -	.probe		= plat_nand_probe, -	.remove		= __devexit_p(plat_nand_remove), -	.driver		= { -		.name	= "gen_nand", -		.owner	= THIS_MODULE, +	.probe	= plat_nand_probe, +	.remove	= plat_nand_remove, +	.driver	= { +		.name		= "gen_nand", +		.owner		= THIS_MODULE, +		.of_match_table = plat_nand_match,  	},  }; -static int __init plat_nand_init(void) -{ -	return platform_driver_register(&plat_nand_driver); -} - -static void __exit plat_nand_exit(void) -{ -	platform_driver_unregister(&plat_nand_driver); -} - -module_init(plat_nand_init); -module_exit(plat_nand_exit); +module_platform_driver(plat_nand_driver);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Vitaly Wool");  | 
