diff options
author | Stefan Roese <sr@denx.de> | 2012-03-16 05:19:31 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-03-26 20:01:07 -0400 |
commit | eea628199d5b12429c47db17035a954b0062e554 (patch) | |
tree | ea2ddcd6df17d3c459f7d40477d06ddbc96abc7d /drivers/mtd | |
parent | 30053b87d5b97aca28dd7a59982cbb161eaf01c6 (diff) |
mtd: Add device-tree support to fsmc_nand
This patch adds support to configure the FSMC NAND driver (used amongst
others on SPEAr platforms) via device-tree instead of platform_data.
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 04901821309..1b8330e1155 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mtd/nand.h> | 31 | #include <linux/mtd/nand.h> |
32 | #include <linux/mtd/nand_ecc.h> | 32 | #include <linux/mtd/nand_ecc.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/of.h> | ||
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
35 | #include <linux/io.h> | 36 | #include <linux/io.h> |
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
@@ -854,6 +855,38 @@ static bool filter(struct dma_chan *chan, void *slave) | |||
854 | return true; | 855 | return true; |
855 | } | 856 | } |
856 | 857 | ||
858 | #ifdef CONFIG_OF | ||
859 | static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, | ||
860 | struct device_node *np) | ||
861 | { | ||
862 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
863 | u32 val; | ||
864 | |||
865 | /* Set default NAND width to 8 bits */ | ||
866 | pdata->width = 8; | ||
867 | if (!of_property_read_u32(np, "bank-width", &val)) { | ||
868 | if (val == 2) { | ||
869 | pdata->width = 16; | ||
870 | } else if (val != 1) { | ||
871 | dev_err(&pdev->dev, "invalid bank-width %u\n", val); | ||
872 | return -EINVAL; | ||
873 | } | ||
874 | } | ||
875 | of_property_read_u32(np, "st,ale-off", &pdata->ale_off); | ||
876 | of_property_read_u32(np, "st,cle-off", &pdata->cle_off); | ||
877 | if (of_get_property(np, "nand-skip-bbtscan", NULL)) | ||
878 | pdata->options = NAND_SKIP_BBTSCAN; | ||
879 | |||
880 | return 0; | ||
881 | } | ||
882 | #else | ||
883 | static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, | ||
884 | struct device_node *np) | ||
885 | { | ||
886 | return -ENOSYS; | ||
887 | } | ||
888 | #endif | ||
889 | |||
857 | /* | 890 | /* |
858 | * fsmc_nand_probe - Probe function | 891 | * fsmc_nand_probe - Probe function |
859 | * @pdev: platform device structure | 892 | * @pdev: platform device structure |
@@ -861,6 +894,8 @@ static bool filter(struct dma_chan *chan, void *slave) | |||
861 | static int __init fsmc_nand_probe(struct platform_device *pdev) | 894 | static int __init fsmc_nand_probe(struct platform_device *pdev) |
862 | { | 895 | { |
863 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | 896 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); |
897 | struct device_node __maybe_unused *np = pdev->dev.of_node; | ||
898 | struct mtd_part_parser_data ppdata = {}; | ||
864 | struct fsmc_nand_data *host; | 899 | struct fsmc_nand_data *host; |
865 | struct mtd_info *mtd; | 900 | struct mtd_info *mtd; |
866 | struct nand_chip *nand; | 901 | struct nand_chip *nand; |
@@ -870,6 +905,16 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
870 | u32 pid; | 905 | u32 pid; |
871 | int i; | 906 | int i; |
872 | 907 | ||
908 | if (np) { | ||
909 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
910 | pdev->dev.platform_data = pdata; | ||
911 | ret = fsmc_nand_probe_config_dt(pdev, np); | ||
912 | if (ret) { | ||
913 | dev_err(&pdev->dev, "no platform data\n"); | ||
914 | return -ENODEV; | ||
915 | } | ||
916 | } | ||
917 | |||
873 | if (!pdata) { | 918 | if (!pdata) { |
874 | dev_err(&pdev->dev, "platform data is NULL\n"); | 919 | dev_err(&pdev->dev, "platform data is NULL\n"); |
875 | return -EINVAL; | 920 | return -EINVAL; |
@@ -1113,7 +1158,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1113 | * Check for partition info passed | 1158 | * Check for partition info passed |
1114 | */ | 1159 | */ |
1115 | host->mtd.name = "nand"; | 1160 | host->mtd.name = "nand"; |
1116 | ret = mtd_device_parse_register(&host->mtd, NULL, NULL, | 1161 | ppdata.of_node = np; |
1162 | ret = mtd_device_parse_register(&host->mtd, NULL, &ppdata, | ||
1117 | host->partitions, host->nr_partitions); | 1163 | host->partitions, host->nr_partitions); |
1118 | if (ret) | 1164 | if (ret) |
1119 | goto err_probe; | 1165 | goto err_probe; |
@@ -1183,11 +1229,20 @@ static int fsmc_nand_resume(struct device *dev) | |||
1183 | static SIMPLE_DEV_PM_OPS(fsmc_nand_pm_ops, fsmc_nand_suspend, fsmc_nand_resume); | 1229 | static SIMPLE_DEV_PM_OPS(fsmc_nand_pm_ops, fsmc_nand_suspend, fsmc_nand_resume); |
1184 | #endif | 1230 | #endif |
1185 | 1231 | ||
1232 | #ifdef CONFIG_OF | ||
1233 | static const struct of_device_id fsmc_nand_id_table[] = { | ||
1234 | { .compatible = "st,spear600-fsmc-nand" }, | ||
1235 | {} | ||
1236 | }; | ||
1237 | MODULE_DEVICE_TABLE(of, fsmc_nand_id_table); | ||
1238 | #endif | ||
1239 | |||
1186 | static struct platform_driver fsmc_nand_driver = { | 1240 | static struct platform_driver fsmc_nand_driver = { |
1187 | .remove = fsmc_nand_remove, | 1241 | .remove = fsmc_nand_remove, |
1188 | .driver = { | 1242 | .driver = { |
1189 | .owner = THIS_MODULE, | 1243 | .owner = THIS_MODULE, |
1190 | .name = "fsmc-nand", | 1244 | .name = "fsmc-nand", |
1245 | .of_match_table = of_match_ptr(fsmc_nand_id_table), | ||
1191 | #ifdef CONFIG_PM | 1246 | #ifdef CONFIG_PM |
1192 | .pm = &fsmc_nand_pm_ops, | 1247 | .pm = &fsmc_nand_pm_ops, |
1193 | #endif | 1248 | #endif |