summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorTony Truong <truong@codeaurora.org>2016-12-07 11:41:54 -0800
committerTony Truong <truong@codeaurora.org>2016-12-22 15:51:18 -0800
commit9edb4da273705735361bf7153ef2141d3147066b (patch)
treec57e0c53d8fad567883025f22de623f9f3d19f17 /drivers/pci
parentba4fdd9852b5a61b6a22385a9e6cab9ea78346b9 (diff)
msm: pcie: add mutex for PCIe enumeration
PCIe bus driver supports a few ways for clients to trigger enumeration. To prevent race conditions, add a mutex to secure the enumeration process. Change-Id: Ifa4f6d2b4edee85e750e6e44626c89ec0de966cf Signed-off-by: Tony Truong <truong@codeaurora.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-msm.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 9a6f1aed82e8..7c8b5e3e57a1 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -589,6 +589,7 @@ struct msm_pcie_dev_t {
bool cfg_access;
spinlock_t cfg_lock;
unsigned long irqsave_flags;
+ struct mutex enumerate_lock;
struct mutex setup_lock;
struct irq_domain *irq_domain;
@@ -4964,12 +4965,15 @@ int msm_pcie_enumerate(u32 rc_idx)
int ret = 0, bus_ret = 0, scan_ret = 0;
struct msm_pcie_dev_t *dev = &msm_pcie_dev[rc_idx];
+ mutex_lock(&dev->enumerate_lock);
+
PCIE_DBG(dev, "Enumerate RC%d\n", rc_idx);
if (!dev->drv_ready) {
PCIE_DBG(dev, "RC%d has not been successfully probed yet\n",
rc_idx);
- return -EPROBE_DEFER;
+ ret = -EPROBE_DEFER;
+ goto out;
}
if (!dev->enumerated) {
@@ -4996,8 +5000,7 @@ int msm_pcie_enumerate(u32 rc_idx)
PCIE_ERR(dev,
"PCIe: failed to get host bridge resources for RC%d: %d\n",
dev->rc_idx, ret);
-
- return ret;
+ goto out;
}
bus = pci_create_root_bus(&dev->pdev->dev, 0,
@@ -5008,8 +5011,8 @@ int msm_pcie_enumerate(u32 rc_idx)
PCIE_ERR(dev,
"PCIe: failed to create root bus for RC%d\n",
dev->rc_idx);
-
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
scan_ret = pci_scan_child_bus(bus);
@@ -5057,7 +5060,8 @@ int msm_pcie_enumerate(u32 rc_idx)
PCIE_ERR(dev,
"PCIe: Did not find PCI device for RC%d.\n",
dev->rc_idx);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out;
}
bus_ret = bus_for_each_dev(&pci_bus_type, NULL, dev,
@@ -5067,7 +5071,8 @@ int msm_pcie_enumerate(u32 rc_idx)
PCIE_ERR(dev,
"PCIe: Failed to set up device table for RC%d\n",
dev->rc_idx);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out;
}
} else {
PCIE_ERR(dev, "PCIe: failed to enable RC%d.\n",
@@ -5078,6 +5083,9 @@ int msm_pcie_enumerate(u32 rc_idx)
dev->rc_idx);
}
+out:
+ mutex_unlock(&dev->enumerate_lock);
+
return ret;
}
EXPORT_SYMBOL(msm_pcie_enumerate);
@@ -6436,6 +6444,7 @@ int __init pcie_init(void)
rc_name, i);
spin_lock_init(&msm_pcie_dev[i].cfg_lock);
msm_pcie_dev[i].cfg_access = true;
+ mutex_init(&msm_pcie_dev[i].enumerate_lock);
mutex_init(&msm_pcie_dev[i].setup_lock);
mutex_init(&msm_pcie_dev[i].recovery_lock);
spin_lock_init(&msm_pcie_dev[i].linkdown_lock);