aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2018-01-12 16:08:15 -0500
committerArnd Bergmann <arnd@arndb.de>2018-01-15 09:47:07 -0500
commitc5b40c315a8671da99b35ace2484d6fa11a18ab9 (patch)
tree9a46689c9e8ef4cdee2b518d0c1460d4d80e5aab
parenta78182980a2a0045d5971a656248a62d62237234 (diff)
soc: bcm: brcmstb: Be multi-platform compatible
We were making a bunch of wrong assumptions that turned out to blow out on non-Broadcom STB platforms: - we would return -ENODEV from brcmstb_soc_device_early_init() if we could not find the sun_top_ctrl device node, this is not an error in the context of a multi-platform kernel - we would still try to register the Broadcom STB SoC device, even if we are not running on such a platform While at it, also fix the sun_top_ctrl device_node leaks while we change the flow of brcmstb_soc_device_init() and brcmstb_soc_device_early_init(). Fixes: f780429adfbc ("soc: brcmstb: biuctrl: Move to early_initcall") Signed-off-by: Thierry Reding <treding@nvidia.com> [florian: Combine all of Thierry's patch in one go for easier review] Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--drivers/soc/bcm/brcmstb/common.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/soc/bcm/brcmstb/common.c b/drivers/soc/bcm/brcmstb/common.c
index 781ada62d0a3..14185451901d 100644
--- a/drivers/soc/bcm/brcmstb/common.c
+++ b/drivers/soc/bcm/brcmstb/common.c
@@ -70,30 +70,49 @@ static int __init brcmstb_soc_device_early_init(void)
70{ 70{
71 struct device_node *sun_top_ctrl; 71 struct device_node *sun_top_ctrl;
72 void __iomem *sun_top_ctrl_base; 72 void __iomem *sun_top_ctrl_base;
73 int ret = 0;
73 74
75 /* We could be on a multi-platform kernel, don't make this fatal but
76 * bail out early
77 */
74 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); 78 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
75 if (!sun_top_ctrl) 79 if (!sun_top_ctrl)
76 return -ENODEV; 80 return ret;
77 81
78 sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0); 82 sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0);
79 if (!sun_top_ctrl_base) 83 if (!sun_top_ctrl_base) {
80 return -ENODEV; 84 ret = -ENODEV;
85 goto out;
86 }
81 87
82 family_id = readl(sun_top_ctrl_base); 88 family_id = readl(sun_top_ctrl_base);
83 product_id = readl(sun_top_ctrl_base + 0x4); 89 product_id = readl(sun_top_ctrl_base + 0x4);
84 iounmap(sun_top_ctrl_base); 90 iounmap(sun_top_ctrl_base);
85 return 0; 91out:
92 of_node_put(sun_top_ctrl);
93 return ret;
86} 94}
87early_initcall(brcmstb_soc_device_early_init); 95early_initcall(brcmstb_soc_device_early_init);
88 96
89static int __init brcmstb_soc_device_init(void) 97static int __init brcmstb_soc_device_init(void)
90{ 98{
91 struct soc_device_attribute *soc_dev_attr; 99 struct soc_device_attribute *soc_dev_attr;
100 struct device_node *sun_top_ctrl;
92 struct soc_device *soc_dev; 101 struct soc_device *soc_dev;
102 int ret = 0;
103
104 /* We could be on a multi-platform kernel, don't make this fatal but
105 * bail out early
106 */
107 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
108 if (!sun_top_ctrl)
109 return ret;
93 110
94 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 111 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
95 if (!soc_dev_attr) 112 if (!soc_dev_attr) {
96 return -ENOMEM; 113 ret = -ENOMEM;
114 goto out;
115 }
97 116
98 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", 117 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",
99 family_id >> 28 ? 118 family_id >> 28 ?
@@ -111,9 +130,10 @@ static int __init brcmstb_soc_device_init(void)
111 kfree(soc_dev_attr->soc_id); 130 kfree(soc_dev_attr->soc_id);
112 kfree(soc_dev_attr->revision); 131 kfree(soc_dev_attr->revision);
113 kfree(soc_dev_attr); 132 kfree(soc_dev_attr);
114 return -ENOMEM; 133 ret = -ENOMEM;
115 } 134 }
116 135out:
117 return 0; 136 of_node_put(sun_top_ctrl);
137 return ret;
118} 138}
119arch_initcall(brcmstb_soc_device_init); 139arch_initcall(brcmstb_soc_device_init);