| From c8d1f6b2f4b0eb9b3d4f024b41ad1725ec42bd6c Mon Sep 17 00:00:00 2001 |
| From: Marek Vasut <marek.vasut@gmail.com> |
| Date: Thu, 24 May 2018 16:36:20 +0200 |
| Subject: [PATCH 1437/1795] PCI: rcar: Add missing irq_dispose_mapping() into |
| failpath |
| |
| The rcar_pcie_get_resources() is another misnomer with a side effect. |
| The function does not only get resources, but also maps MSI IRQs via |
| irq_of_parse_and_map(). In case anything fails afterward, the IRQ |
| mapping must be disposed through irq_dispose_mapping() which is not |
| done. |
| |
| This patch handles irq_of_parse_and_map() failures in by disposing |
| of the mapping in rcar_pcie_get_resources() as well as in probe. |
| |
| Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> |
| Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
| Reviewed-by: Simon Horman <horms+renesas@verge.net.au> |
| Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Cc: Geert Uytterhoeven <geert+renesas@glider.be> |
| Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
| Cc: Phil Edworthy <phil.edworthy@renesas.com> |
| Cc: Simon Horman <horms+renesas@verge.net.au> |
| Cc: Wolfram Sang <wsa@the-dreams.de> |
| Cc: linux-renesas-soc@vger.kernel.org |
| (cherry picked from commit 53f1aebfbe46ffe422138758c9d015502740f714) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/pci/host/pcie-rcar.c | 17 ++++++++++++++--- |
| 1 file changed, 14 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c |
| index 3da458b953c3..382780353f64 100644 |
| --- a/drivers/pci/host/pcie-rcar.c |
| +++ b/drivers/pci/host/pcie-rcar.c |
| @@ -954,18 +954,25 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie) |
| i = irq_of_parse_and_map(dev->of_node, 0); |
| if (!i) { |
| dev_err(dev, "cannot get platform resources for msi interrupt\n"); |
| - return -ENOENT; |
| + err = -ENOENT; |
| + goto err_irq1; |
| } |
| pcie->msi.irq1 = i; |
| |
| i = irq_of_parse_and_map(dev->of_node, 1); |
| if (!i) { |
| dev_err(dev, "cannot get platform resources for msi interrupt\n"); |
| - return -ENOENT; |
| + err = -ENOENT; |
| + goto err_irq2; |
| } |
| pcie->msi.irq2 = i; |
| |
| return 0; |
| + |
| +err_irq2: |
| + irq_dispose_mapping(pcie->msi.irq1); |
| +err_irq1: |
| + return err; |
| } |
| |
| static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie, |
| @@ -1112,7 +1119,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) |
| err = clk_prepare_enable(pcie->bus_clk); |
| if (err) { |
| dev_err(dev, "failed to enable bus clock: %d\n", err); |
| - goto err_pm_put; |
| + goto err_unmap_msi_irqs; |
| } |
| |
| err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); |
| @@ -1155,6 +1162,10 @@ static int rcar_pcie_probe(struct platform_device *pdev) |
| err_clk_disable: |
| clk_disable_unprepare(pcie->bus_clk); |
| |
| +err_unmap_msi_irqs: |
| + irq_dispose_mapping(pcie->msi.irq2); |
| + irq_dispose_mapping(pcie->msi.irq1); |
| + |
| err_pm_put: |
| pm_runtime_put(dev); |
| |
| -- |
| 2.19.0 |
| |