diff options
author | Wen Yang <wen.yang99@zte.com.cn> | 2019-02-26 23:40:40 -0500 |
---|---|---|
committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2019-04-01 05:42:58 -0400 |
commit | 3842f5166bf1ef286fe7a39f262b5c9581308366 (patch) | |
tree | f5a2b86961ea908f800811426d148eb61e1a3bd2 | |
parent | 69adea738eb2be70b4753dbb60eb1de9abbfb4dc (diff) |
PCI: aardvark: Fix a leaked reference by adding missing of_node_put()
The call to of_get_next_child() returns a node pointer with refcount
incremented thus it must be explicitly decremented after the last
usage.
irq_domain_add_linear() also calls of_node_get() to increase refcount,
so irq_domain will not be affected when it is released.
Detected by coccinelle with the following warnings:
./drivers/pci/controller/pci-aardvark.c:826:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 798, but without a corresponding object release within this function.
Signed-off-by: Wen Yang <wen.yang99@zte.com.cn>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
-rw-r--r-- | drivers/pci/controller/pci-aardvark.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index eb58dfdaba1b..134e0306ff00 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c | |||
@@ -794,6 +794,7 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | |||
794 | struct device_node *node = dev->of_node; | 794 | struct device_node *node = dev->of_node; |
795 | struct device_node *pcie_intc_node; | 795 | struct device_node *pcie_intc_node; |
796 | struct irq_chip *irq_chip; | 796 | struct irq_chip *irq_chip; |
797 | int ret = 0; | ||
797 | 798 | ||
798 | pcie_intc_node = of_get_next_child(node, NULL); | 799 | pcie_intc_node = of_get_next_child(node, NULL); |
799 | if (!pcie_intc_node) { | 800 | if (!pcie_intc_node) { |
@@ -806,8 +807,8 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | |||
806 | irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", | 807 | irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", |
807 | dev_name(dev)); | 808 | dev_name(dev)); |
808 | if (!irq_chip->name) { | 809 | if (!irq_chip->name) { |
809 | of_node_put(pcie_intc_node); | 810 | ret = -ENOMEM; |
810 | return -ENOMEM; | 811 | goto out_put_node; |
811 | } | 812 | } |
812 | 813 | ||
813 | irq_chip->irq_mask = advk_pcie_irq_mask; | 814 | irq_chip->irq_mask = advk_pcie_irq_mask; |
@@ -819,11 +820,13 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | |||
819 | &advk_pcie_irq_domain_ops, pcie); | 820 | &advk_pcie_irq_domain_ops, pcie); |
820 | if (!pcie->irq_domain) { | 821 | if (!pcie->irq_domain) { |
821 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 822 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
822 | of_node_put(pcie_intc_node); | 823 | ret = -ENOMEM; |
823 | return -ENOMEM; | 824 | goto out_put_node; |
824 | } | 825 | } |
825 | 826 | ||
826 | return 0; | 827 | out_put_node: |
828 | of_node_put(pcie_intc_node); | ||
829 | return ret; | ||
827 | } | 830 | } |
828 | 831 | ||
829 | static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) | 832 | static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) |