diff options
Diffstat (limited to 'drivers/mtd/nand/orion_nand.c')
| -rw-r--r-- | drivers/mtd/nand/orion_nand.c | 47 | 
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 1d3bfb26080..0f50ef38b87 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -13,6 +13,7 @@  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <linux/mtd/mtd.h>  #include <linux/mtd/nand.h>  #include <linux/mtd/partitions.h> @@ -74,11 +75,13 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  static int __init orion_nand_probe(struct platform_device *pdev)  {  	struct mtd_info *mtd; +	struct mtd_part_parser_data ppdata = {};  	struct nand_chip *nc;  	struct orion_nand_data *board;  	struct resource *res;  	void __iomem *io_base;  	int ret = 0; +	u32 val = 0;  	nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);  	if (!nc) { @@ -101,7 +104,32 @@ static int __init orion_nand_probe(struct platform_device *pdev)  		goto no_res;  	} -	board = pdev->dev.platform_data; +	if (pdev->dev.of_node) { +		board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data), +					GFP_KERNEL); +		if (!board) { +			printk(KERN_ERR "orion_nand: failed to allocate board structure.\n"); +			ret = -ENOMEM; +			goto no_res; +		} +		if (!of_property_read_u32(pdev->dev.of_node, "cle", &val)) +			board->cle = (u8)val; +		else +			board->cle = 0; +		if (!of_property_read_u32(pdev->dev.of_node, "ale", &val)) +			board->ale = (u8)val; +		else +			board->ale = 1; +		if (!of_property_read_u32(pdev->dev.of_node, +						"bank-width", &val)) +			board->width = (u8)val * 8; +		else +			board->width = 8; +		if (!of_property_read_u32(pdev->dev.of_node, +						"chip-delay", &val)) +			board->chip_delay = (u8)val; +	} else +		board = pdev->dev.platform_data;  	mtd->priv = nc;  	mtd->owner = THIS_MODULE; @@ -115,6 +143,10 @@ static int __init orion_nand_probe(struct platform_device *pdev)  	if (board->chip_delay)  		nc->chip_delay = board->chip_delay; +	WARN(board->width > 16, +		"%d bit bus width out of range", +		board->width); +  	if (board->width == 16)  		nc->options |= NAND_BUSWIDTH_16; @@ -129,8 +161,9 @@ static int __init orion_nand_probe(struct platform_device *pdev)  	}  	mtd->name = "orion_nand"; -	ret = mtd_device_parse_register(mtd, NULL, NULL, board->parts, -					board->nr_parts); +	ppdata.of_node = pdev->dev.of_node; +	ret = mtd_device_parse_register(mtd, NULL, &ppdata, +			board->parts, board->nr_parts);  	if (ret) {  		nand_release(mtd);  		goto no_dev; @@ -161,11 +194,19 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)  	return 0;  } +#ifdef CONFIG_OF +static struct of_device_id orion_nand_of_match_table[] = { +	{ .compatible = "mrvl,orion-nand", }, +	{}, +}; +#endif +  static struct platform_driver orion_nand_driver = {  	.remove		= __devexit_p(orion_nand_remove),  	.driver		= {  		.name	= "orion_nand",  		.owner	= THIS_MODULE, +		.of_match_table = of_match_ptr(orion_nand_of_match_table),  	},  };  |