Commit d8298d26 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'devicetree-fixes-for-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux

Pull DeviceTree fixes from Rob Herring:

 - a couple of DT node ref counting fixes

 - fix __unflatten_device_tree for PPC PCI hotplug case

 - rework marking irq controllers as OF_POPULATED in cases where real
   driver is used.

 - disable of_platform_default_populate_init on PPC.  The change in
   initcall order causes problems which need to be sorted out later.

* tag 'devicetree-fixes-for-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux:
  of: fix reference counting in of_graph_get_endpoint_by_regs
  of/platform: disable the of_platform_default_populate_init() for all the ppc boards
  ARM: imx6: mark GPC node as not populated after irq init to probe pm domain driver
  of/irq: Mark interrupt controllers as populated before initialisation
  drivers/of: Validate device node in __unflatten_device_tree()
  of: Delete an unnecessary check before the function call "of_node_put"
parents 5cae6fe2 34276bb0
...@@ -271,6 +271,12 @@ static int __init imx_gpc_init(struct device_node *node, ...@@ -271,6 +271,12 @@ static int __init imx_gpc_init(struct device_node *node,
for (i = 0; i < IMR_NUM; i++) for (i = 0; i < IMR_NUM; i++)
writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4); writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
/*
* Clear the OF_POPULATED flag set in of_irq_init so that
* later the GPC power domain driver will not be skipped.
*/
of_node_clear_flag(node, OF_POPULATED);
return 0; return 0;
} }
IRQCHIP_DECLARE(imx_gpc, "fsl,imx6q-gpc", imx_gpc_init); IRQCHIP_DECLARE(imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
......
...@@ -1631,7 +1631,6 @@ static int __of_parse_phandle_with_args(const struct device_node *np, ...@@ -1631,7 +1631,6 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
*/ */
err: err:
if (it.node)
of_node_put(it.node); of_node_put(it.node);
return rc; return rc;
} }
...@@ -2343,20 +2342,13 @@ struct device_node *of_graph_get_endpoint_by_regs( ...@@ -2343,20 +2342,13 @@ struct device_node *of_graph_get_endpoint_by_regs(
const struct device_node *parent, int port_reg, int reg) const struct device_node *parent, int port_reg, int reg)
{ {
struct of_endpoint endpoint; struct of_endpoint endpoint;
struct device_node *node, *prev_node = NULL; struct device_node *node = NULL;
while (1) {
node = of_graph_get_next_endpoint(parent, prev_node);
of_node_put(prev_node);
if (!node)
break;
for_each_endpoint_of_node(parent, node) {
of_graph_parse_endpoint(node, &endpoint); of_graph_parse_endpoint(node, &endpoint);
if (((port_reg == -1) || (endpoint.port == port_reg)) && if (((port_reg == -1) || (endpoint.port == port_reg)) &&
((reg == -1) || (endpoint.id == reg))) ((reg == -1) || (endpoint.id == reg)))
return node; return node;
prev_node = node;
} }
return NULL; return NULL;
......
...@@ -517,7 +517,7 @@ static void *__unflatten_device_tree(const void *blob, ...@@ -517,7 +517,7 @@ static void *__unflatten_device_tree(const void *blob,
pr_warning("End of tree marker overwritten: %08x\n", pr_warning("End of tree marker overwritten: %08x\n",
be32_to_cpup(mem + size)); be32_to_cpup(mem + size));
if (detached) { if (detached && mynodes) {
of_node_set_flag(*mynodes, OF_DETACHED); of_node_set_flag(*mynodes, OF_DETACHED);
pr_debug("unflattened tree is detached\n"); pr_debug("unflattened tree is detached\n");
} }
......
...@@ -544,12 +544,15 @@ void __init of_irq_init(const struct of_device_id *matches) ...@@ -544,12 +544,15 @@ void __init of_irq_init(const struct of_device_id *matches)
list_del(&desc->list); list_del(&desc->list);
of_node_set_flag(desc->dev, OF_POPULATED);
pr_debug("of_irq_init: init %s (%p), parent %p\n", pr_debug("of_irq_init: init %s (%p), parent %p\n",
desc->dev->full_name, desc->dev->full_name,
desc->dev, desc->interrupt_parent); desc->dev, desc->interrupt_parent);
ret = desc->irq_init_cb(desc->dev, ret = desc->irq_init_cb(desc->dev,
desc->interrupt_parent); desc->interrupt_parent);
if (ret) { if (ret) {
of_node_clear_flag(desc->dev, OF_POPULATED);
kfree(desc); kfree(desc);
continue; continue;
} }
...@@ -559,8 +562,6 @@ void __init of_irq_init(const struct of_device_id *matches) ...@@ -559,8 +562,6 @@ void __init of_irq_init(const struct of_device_id *matches)
* its children can get processed in a subsequent pass. * its children can get processed in a subsequent pass.
*/ */
list_add_tail(&desc->list, &intc_parent_list); list_add_tail(&desc->list, &intc_parent_list);
of_node_set_flag(desc->dev, OF_POPULATED);
} }
/* Get the next pending parent that might have children */ /* Get the next pending parent that might have children */
......
...@@ -497,6 +497,7 @@ int of_platform_default_populate(struct device_node *root, ...@@ -497,6 +497,7 @@ int of_platform_default_populate(struct device_node *root,
} }
EXPORT_SYMBOL_GPL(of_platform_default_populate); EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
static int __init of_platform_default_populate_init(void) static int __init of_platform_default_populate_init(void)
{ {
struct device_node *node; struct device_node *node;
...@@ -521,6 +522,7 @@ static int __init of_platform_default_populate_init(void) ...@@ -521,6 +522,7 @@ static int __init of_platform_default_populate_init(void)
return 0; return 0;
} }
arch_initcall_sync(of_platform_default_populate_init); arch_initcall_sync(of_platform_default_populate_init);
#endif
static int of_platform_device_destroy(struct device *dev, void *data) static int of_platform_device_destroy(struct device *dev, void *data)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment