From cdeadd712f52b16a9285386d61ee26fd14eb4085 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 30 Jul 2012 09:22:24 +0200 Subject: mtd: nand: davinci: add OF support for davinci nand controller add OF support for the davinci nand controller. Signed-off-by: Heiko Schocher Acked-by: Sekhar Nori Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/davinci_nand.c | 72 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index d94b03c207af..f386b3c55031 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -518,9 +519,75 @@ static struct nand_ecclayout hwecc4_2048 __initconst = { }, }; +#if defined(CONFIG_OF) +static const struct of_device_id davinci_nand_of_match[] = { + {.compatible = "ti,davinci-nand", }, + {}, +} +MODULE_DEVICE_TABLE(of, davinci_nand_of_match); + +static struct davinci_nand_pdata + *nand_davinci_get_pdata(struct platform_device *pdev) +{ + if (!pdev->dev.platform_data && pdev->dev.of_node) { + struct davinci_nand_pdata *pdata; + const char *mode; + u32 prop; + int len; + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct davinci_nand_pdata), + GFP_KERNEL); + pdev->dev.platform_data = pdata; + if (!pdata) + return NULL; + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-chipselect", &prop)) + pdev->id = prop; + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-mask-ale", &prop)) + pdata->mask_ale = prop; + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-mask-cle", &prop)) + pdata->mask_cle = prop; + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-mask-chipsel", &prop)) + pdata->mask_chipsel = prop; + if (!of_property_read_string(pdev->dev.of_node, + "ti,davinci-ecc-mode", &mode)) { + if (!strncmp("none", mode, 4)) + pdata->ecc_mode = NAND_ECC_NONE; + if (!strncmp("soft", mode, 4)) + pdata->ecc_mode = NAND_ECC_SOFT; + if (!strncmp("hw", mode, 2)) + pdata->ecc_mode = NAND_ECC_HW; + } + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-ecc-bits", &prop)) + pdata->ecc_bits = prop; + if (!of_property_read_u32(pdev->dev.of_node, + "ti,davinci-nand-buswidth", &prop)) + if (prop == 16) + pdata->options |= NAND_BUSWIDTH_16; + if (of_find_property(pdev->dev.of_node, + "ti,davinci-nand-use-bbt", &len)) + pdata->bbt_options = NAND_BBT_USE_FLASH; + } + + return pdev->dev.platform_data; +} +#else +#define davinci_nand_of_match NULL +static struct davinci_nand_pdata + *nand_davinci_get_pdata(struct platform_device *pdev) +{ + return pdev->dev.platform_data; +} +#endif + static int __init nand_davinci_probe(struct platform_device *pdev) { - struct davinci_nand_pdata *pdata = pdev->dev.platform_data; + struct davinci_nand_pdata *pdata; struct davinci_nand_info *info; struct resource *res1; struct resource *res2; @@ -530,6 +597,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) uint32_t val; nand_ecc_modes_t ecc_mode; + pdata = nand_davinci_get_pdata(pdev); /* insist on board-specific configuration */ if (!pdata) return -ENODEV; @@ -816,6 +884,8 @@ static struct platform_driver nand_davinci_driver = { .remove = __exit_p(nand_davinci_remove), .driver = { .name = "davinci_nand", + .owner = THIS_MODULE, + .of_match_table = davinci_nand_of_match, }, }; MODULE_ALIAS("platform:davinci_nand"); -- cgit v1.2.3