提交 c5b40c31 编写于 作者: T Thierry Reding 提交者: Arnd Bergmann

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: f780429a ("soc: brcmstb: biuctrl: Move to early_initcall")
Signed-off-by: NThierry Reding <treding@nvidia.com>
[florian: Combine all of Thierry's patch in one go for easier review]
Signed-off-by: NFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: NArnd Bergmann <arnd@arndb.de>
上级 a7818298
...@@ -70,30 +70,49 @@ static int __init brcmstb_soc_device_early_init(void) ...@@ -70,30 +70,49 @@ static int __init brcmstb_soc_device_early_init(void)
{ {
struct device_node *sun_top_ctrl; struct device_node *sun_top_ctrl;
void __iomem *sun_top_ctrl_base; void __iomem *sun_top_ctrl_base;
int ret = 0;
/* We could be on a multi-platform kernel, don't make this fatal but
* bail out early
*/
sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
if (!sun_top_ctrl) if (!sun_top_ctrl)
return -ENODEV; return ret;
sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0); sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0);
if (!sun_top_ctrl_base) if (!sun_top_ctrl_base) {
return -ENODEV; ret = -ENODEV;
goto out;
}
family_id = readl(sun_top_ctrl_base); family_id = readl(sun_top_ctrl_base);
product_id = readl(sun_top_ctrl_base + 0x4); product_id = readl(sun_top_ctrl_base + 0x4);
iounmap(sun_top_ctrl_base); iounmap(sun_top_ctrl_base);
return 0; out:
of_node_put(sun_top_ctrl);
return ret;
} }
early_initcall(brcmstb_soc_device_early_init); early_initcall(brcmstb_soc_device_early_init);
static int __init brcmstb_soc_device_init(void) static int __init brcmstb_soc_device_init(void)
{ {
struct soc_device_attribute *soc_dev_attr; struct soc_device_attribute *soc_dev_attr;
struct device_node *sun_top_ctrl;
struct soc_device *soc_dev; struct soc_device *soc_dev;
int ret = 0;
/* We could be on a multi-platform kernel, don't make this fatal but
* bail out early
*/
sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
if (!sun_top_ctrl)
return ret;
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr) if (!soc_dev_attr) {
return -ENOMEM; ret = -ENOMEM;
goto out;
}
soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",
family_id >> 28 ? family_id >> 28 ?
...@@ -111,9 +130,10 @@ static int __init brcmstb_soc_device_init(void) ...@@ -111,9 +130,10 @@ static int __init brcmstb_soc_device_init(void)
kfree(soc_dev_attr->soc_id); kfree(soc_dev_attr->soc_id);
kfree(soc_dev_attr->revision); kfree(soc_dev_attr->revision);
kfree(soc_dev_attr); kfree(soc_dev_attr);
return -ENOMEM; ret = -ENOMEM;
} }
out:
return 0; of_node_put(sun_top_ctrl);
return ret;
} }
arch_initcall(brcmstb_soc_device_init); arch_initcall(brcmstb_soc_device_init);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册