aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2012-03-16 06:42:11 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-03-26 20:01:21 -0400
commit6551ab5d30d6bf0cea0c6cb294686ce3c7fc6042 (patch)
treeba88add42bc6bf9d72feeb142afd601782051cdc /drivers/mtd/devices
parentf7e3dd8f48faad24334f7bea048ea59a2c766587 (diff)
mtd: add device-tree support to spear_smi
This patch adds support to configure the SPEAr SMI driver 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/devices')
-rw-r--r--drivers/mtd/devices/spear_smi.c111
1 files changed, 99 insertions, 12 deletions
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index f7f34fd1a3e5..797d43cd3550 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -33,9 +33,8 @@
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/wait.h> 35#include <linux/wait.h>
36 36#include <linux/of.h>
37/* max possible slots for serial-nor flash chip in the SMI controller */ 37#include <linux/of_address.h>
38#define MAX_NUM_FLASH_CHIP 4
39 38
40/* SMI clock rate */ 39/* SMI clock rate */
41#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */ 40#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */
@@ -748,9 +747,63 @@ err_probe:
748 return ret; 747 return ret;
749} 748}
750 749
751static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank) 750
751#ifdef CONFIG_OF
752static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
753 struct device_node *np)
754{
755 struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev);
756 struct device_node *pp = NULL;
757 const __be32 *addr;
758 u32 val;
759 int len;
760 int i = 0;
761
762 if (!np)
763 return -ENODEV;
764
765 of_property_read_u32(np, "clock-rate", &val);
766 pdata->clk_rate = val;
767
768 pdata->board_flash_info = devm_kzalloc(&pdev->dev,
769 sizeof(*pdata->board_flash_info),
770 GFP_KERNEL);
771
772 /* Fill structs for each subnode (flash device) */
773 while ((pp = of_get_next_child(np, pp))) {
774 struct spear_smi_flash_info *flash_info;
775
776 flash_info = &pdata->board_flash_info[i];
777 pdata->np[i] = pp;
778
779 /* Read base-addr and size from DT */
780 addr = of_get_property(pp, "reg", &len);
781 pdata->board_flash_info->mem_base = be32_to_cpup(&addr[0]);
782 pdata->board_flash_info->size = be32_to_cpup(&addr[1]);
783
784 if (of_get_property(pp, "st,smi-fast-mode", NULL))
785 pdata->board_flash_info->fast_mode = 1;
786
787 i++;
788 }
789
790 pdata->num_flashes = i;
791
792 return 0;
793}
794#else
795static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
796 struct device_node *np)
797{
798 return -ENOSYS;
799}
800#endif
801
802static int spear_smi_setup_banks(struct platform_device *pdev,
803 u32 bank, struct device_node *np)
752{ 804{
753 struct spear_smi *dev = platform_get_drvdata(pdev); 805 struct spear_smi *dev = platform_get_drvdata(pdev);
806 struct mtd_part_parser_data ppdata = {};
754 struct spear_smi_flash_info *flash_info; 807 struct spear_smi_flash_info *flash_info;
755 struct spear_smi_plat_data *pdata; 808 struct spear_smi_plat_data *pdata;
756 struct spear_snor_flash *flash; 809 struct spear_snor_flash *flash;
@@ -816,11 +869,16 @@ static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank)
816 dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n", 869 dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
817 flash->mtd.erasesize, flash->mtd.erasesize / 1024); 870 flash->mtd.erasesize, flash->mtd.erasesize / 1024);
818 871
872#ifndef CONFIG_OF
819 if (flash_info->partitions) { 873 if (flash_info->partitions) {
820 parts = flash_info->partitions; 874 parts = flash_info->partitions;
821 count = flash_info->nr_partitions; 875 count = flash_info->nr_partitions;
822 } 876 }
823 ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, parts, count); 877#endif
878 ppdata.of_node = np;
879
880 ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts,
881 count);
824 if (ret) { 882 if (ret) {
825 dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); 883 dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
826 goto err_map; 884 goto err_map;
@@ -847,17 +905,34 @@ err_probe:
847 */ 905 */
848static int __devinit spear_smi_probe(struct platform_device *pdev) 906static int __devinit spear_smi_probe(struct platform_device *pdev)
849{ 907{
850 struct spear_smi_plat_data *pdata; 908 struct device_node *np = pdev->dev.of_node;
909 struct spear_smi_plat_data *pdata = NULL;
851 struct spear_smi *dev; 910 struct spear_smi *dev;
852 struct resource *smi_base; 911 struct resource *smi_base;
853 int irq, ret = 0; 912 int irq, ret = 0;
854 int i; 913 int i;
855 914
856 pdata = dev_get_platdata(&pdev->dev); 915 if (np) {
857 if (pdata < 0) { 916 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
858 ret = -ENODEV; 917 if (!pdata) {
859 dev_err(&pdev->dev, "no platform data\n"); 918 pr_err("%s: ERROR: no memory", __func__);
860 goto err; 919 ret = -ENOMEM;
920 goto err;
921 }
922 pdev->dev.platform_data = pdata;
923 ret = spear_smi_probe_config_dt(pdev, np);
924 if (ret) {
925 ret = -ENODEV;
926 dev_err(&pdev->dev, "no platform data\n");
927 goto err;
928 }
929 } else {
930 pdata = dev_get_platdata(&pdev->dev);
931 if (pdata < 0) {
932 ret = -ENODEV;
933 dev_err(&pdev->dev, "no platform data\n");
934 goto err;
935 }
861 } 936 }
862 937
863 smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); 938 smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -932,7 +1007,7 @@ static int __devinit spear_smi_probe(struct platform_device *pdev)
932 1007
933 /* loop for each serial nor-flash which is connected to smi */ 1008 /* loop for each serial nor-flash which is connected to smi */
934 for (i = 0; i < dev->num_flashes; i++) { 1009 for (i = 0; i < dev->num_flashes; i++) {
935 ret = spear_smi_setup_banks(pdev, i); 1010 ret = spear_smi_setup_banks(pdev, i, pdata->np[i]);
936 if (ret) { 1011 if (ret) {
937 dev_err(&dev->pdev->dev, "bank setup failed\n"); 1012 dev_err(&dev->pdev->dev, "bank setup failed\n");
938 goto err_bank_setup; 1013 goto err_bank_setup;
@@ -967,6 +1042,7 @@ err:
967static int __devexit spear_smi_remove(struct platform_device *pdev) 1042static int __devexit spear_smi_remove(struct platform_device *pdev)
968{ 1043{
969 struct spear_smi *dev; 1044 struct spear_smi *dev;
1045 struct spear_smi_plat_data *pdata;
970 struct spear_snor_flash *flash; 1046 struct spear_snor_flash *flash;
971 struct resource *smi_base; 1047 struct resource *smi_base;
972 int ret; 1048 int ret;
@@ -978,6 +1054,8 @@ static int __devexit spear_smi_remove(struct platform_device *pdev)
978 return -ENODEV; 1054 return -ENODEV;
979 } 1055 }
980 1056
1057 pdata = dev_get_platdata(&pdev->dev);
1058
981 /* clean up for all nor flash */ 1059 /* clean up for all nor flash */
982 for (i = 0; i < dev->num_flashes; i++) { 1060 for (i = 0; i < dev->num_flashes; i++) {
983 flash = dev->flash[i]; 1061 flash = dev->flash[i];
@@ -1031,11 +1109,20 @@ int spear_smi_resume(struct platform_device *pdev)
1031 return ret; 1109 return ret;
1032} 1110}
1033 1111
1112#ifdef CONFIG_OF
1113static const struct of_device_id spear_smi_id_table[] = {
1114 { .compatible = "st,spear600-smi" },
1115 {}
1116};
1117MODULE_DEVICE_TABLE(of, spear_smi_id_table);
1118#endif
1119
1034static struct platform_driver spear_smi_driver = { 1120static struct platform_driver spear_smi_driver = {
1035 .driver = { 1121 .driver = {
1036 .name = "smi", 1122 .name = "smi",
1037 .bus = &platform_bus_type, 1123 .bus = &platform_bus_type,
1038 .owner = THIS_MODULE, 1124 .owner = THIS_MODULE,
1125 .of_match_table = of_match_ptr(spear_smi_id_table),
1039 }, 1126 },
1040 .probe = spear_smi_probe, 1127 .probe = spear_smi_probe,
1041 .remove = __devexit_p(spear_smi_remove), 1128 .remove = __devexit_p(spear_smi_remove),