| From eac56aa3bc8af3d9b9850345d0f2da9d83529134 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Fri, 17 Nov 2017 14:38:31 +0100 |
| Subject: PCI: keystone: Fix interrupt-controller-node lookup |
| |
| From: Johan Hovold <johan@kernel.org> |
| |
| commit eac56aa3bc8af3d9b9850345d0f2da9d83529134 upstream. |
| |
| Fix child-node lookup during initialisation which was using the wrong |
| OF-helper and ended up searching the whole device tree depth-first |
| starting at the parent rather than just matching on its children. |
| |
| To make things worse, the parent pci node could end up being prematurely |
| freed as of_find_node_by_name() drops a reference to its first argument. |
| Any matching child interrupt-controller node was also leaked. |
| |
| Fixes: 0c4ffcfe1fbc ("PCI: keystone: Add TI Keystone PCIe driver") |
| Cc: stable <stable@vger.kernel.org> # 3.18 |
| Acked-by: Murali Karicheri <m-karicheri2@ti.com> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| [lorenzo.pieralisi@arm.com: updated commit subject] |
| Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
| [johan: backport to 4.4] |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/pci/host/pci-keystone.c | 9 +++++++-- |
| 1 file changed, 7 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/pci/host/pci-keystone.c |
| +++ b/drivers/pci/host/pci-keystone.c |
| @@ -179,14 +179,16 @@ static int ks_pcie_get_irq_controller_in |
| } |
| |
| /* interrupt controller is in a child node */ |
| - *np_temp = of_find_node_by_name(np_pcie, controller); |
| + *np_temp = of_get_child_by_name(np_pcie, controller); |
| if (!(*np_temp)) { |
| dev_err(dev, "Node for %s is absent\n", controller); |
| goto out; |
| } |
| temp = of_irq_count(*np_temp); |
| - if (!temp) |
| + if (!temp) { |
| + of_node_put(*np_temp); |
| goto out; |
| + } |
| if (temp > max_host_irqs) |
| dev_warn(dev, "Too many %s interrupts defined %u\n", |
| (legacy ? "legacy" : "MSI"), temp); |
| @@ -200,6 +202,9 @@ static int ks_pcie_get_irq_controller_in |
| if (host_irqs[temp] < 0) |
| break; |
| } |
| + |
| + of_node_put(*np_temp); |
| + |
| if (temp) { |
| *num_irqs = temp; |
| ret = 0; |