diff options
author | Shawn Lin <shawn.lin@rock-chips.com> | 2017-02-10 01:52:02 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-02-10 16:42:01 -0500 |
commit | f1d722b607d610b66785f7f00d2e1d457260647c (patch) | |
tree | fe8b6d0d7125ec24b41cfaba0b583aacdd4d9a10 | |
parent | 0b351c986a5ffedb502632c1b27690c9730d79c4 (diff) |
PCI: rockchip: Fix rockchip_pcie_probe() error path to free resource list
rockchip_pcie_probe() calls of_pci_get_host_bridge_resources() to parse
resources from DT and build a resource list. The caller is responsible for
disposing of the resource list. This is normally done by
pci_release_host_bridge_dev() when the host bridge is removed.
If the host bridge probe fails, dispose of the resource list in the probe
error path.
[bhelgaas: changelog]
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/host/pcie-rockchip.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index ff43a7e96c22..c0b3b6513a47 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c | |||
@@ -1343,7 +1343,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1343 | 1343 | ||
1344 | err = devm_request_pci_bus_resources(dev, &res); | 1344 | err = devm_request_pci_bus_resources(dev, &res); |
1345 | if (err) | 1345 | if (err) |
1346 | goto err_vpcie; | 1346 | goto err_free_res; |
1347 | 1347 | ||
1348 | /* Get the I/O and memory ranges from DT */ | 1348 | /* Get the I/O and memory ranges from DT */ |
1349 | resource_list_for_each_entry(win, &res) { | 1349 | resource_list_for_each_entry(win, &res) { |
@@ -1376,19 +1376,19 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1376 | 1376 | ||
1377 | err = rockchip_cfg_atu(rockchip); | 1377 | err = rockchip_cfg_atu(rockchip); |
1378 | if (err) | 1378 | if (err) |
1379 | goto err_vpcie; | 1379 | goto err_free_res; |
1380 | 1380 | ||
1381 | rockchip->msg_region = devm_ioremap(rockchip->dev, | 1381 | rockchip->msg_region = devm_ioremap(rockchip->dev, |
1382 | rockchip->msg_bus_addr, SZ_1M); | 1382 | rockchip->msg_bus_addr, SZ_1M); |
1383 | if (!rockchip->msg_region) { | 1383 | if (!rockchip->msg_region) { |
1384 | err = -ENOMEM; | 1384 | err = -ENOMEM; |
1385 | goto err_vpcie; | 1385 | goto err_free_res; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); | 1388 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); |
1389 | if (!bus) { | 1389 | if (!bus) { |
1390 | err = -ENOMEM; | 1390 | err = -ENOMEM; |
1391 | goto err_vpcie; | 1391 | goto err_free_res; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | pci_bus_size_bridges(bus); | 1394 | pci_bus_size_bridges(bus); |
@@ -1399,6 +1399,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1399 | pci_bus_add_devices(bus); | 1399 | pci_bus_add_devices(bus); |
1400 | return err; | 1400 | return err; |
1401 | 1401 | ||
1402 | err_free_res: | ||
1403 | pci_free_resource_list(&res); | ||
1402 | err_vpcie: | 1404 | err_vpcie: |
1403 | if (!IS_ERR(rockchip->vpcie3v3)) | 1405 | if (!IS_ERR(rockchip->vpcie3v3)) |
1404 | regulator_disable(rockchip->vpcie3v3); | 1406 | regulator_disable(rockchip->vpcie3v3); |