summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorTony Truong <truong@codeaurora.org>2016-08-19 17:55:46 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-28 15:16:13 -0700
commit5278f4749152eeefc11705497872179946cf35b6 (patch)
tree392df06420002d01f21cde3998fdcac5e6ec6ee6 /drivers/pci
parent626caf4e54864d90e8d104277f9a1446e487c7e1 (diff)
msm: pcie: verify EP is accessible before conf restore
When attempting to restore multiple endpoint's configuration space over a switch or bridge, only restore for the ones that are accessible and powered on. Change-Id: Ie6234ae30ad47a063982e5cc50f4ecedf1f61de2 Signed-off-by: Tony Truong <truong@codeaurora.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-msm.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 87f4b641201c..4ef349540f43 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -1758,7 +1758,8 @@ static inline int msm_pcie_check_align(struct msm_pcie_dev_t *dev,
static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev,
bool check_sw_stts,
- bool check_ep)
+ bool check_ep,
+ void __iomem *ep_conf)
{
u32 val;
@@ -1785,7 +1786,7 @@ static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev,
}
if (check_ep) {
- val = readl_relaxed(dev->conf);
+ val = readl_relaxed(ep_conf);
PCIE_DBG(dev,
"PCIe: device ID and vender ID of EP of RC %d are 0x%x.\n",
dev->rc_idx, val);
@@ -1814,6 +1815,10 @@ static void msm_pcie_cfg_recover(struct msm_pcie_dev_t *dev, bool rc)
cfg = dev->dm_core;
shadow = dev->rc_shadow;
} else {
+ if (!msm_pcie_confirm_linkup(dev, false, true,
+ dev->pcidev_table[i].conf_base))
+ continue;
+
shadow = dev->ep_shadow[i];
PCIE_DBG(dev,
"PCIe Device: %02x:%02x.%01x\n",
@@ -4561,11 +4566,11 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
usleep_range(LINK_UP_TIMEOUT_US_MIN, LINK_UP_TIMEOUT_US_MAX);
val = readl_relaxed(dev->elbi + PCIE20_ELBI_SYS_STTS);
} while ((!(val & XMLH_LINK_UP) ||
- !msm_pcie_confirm_linkup(dev, false, false))
+ !msm_pcie_confirm_linkup(dev, false, false, NULL))
&& (link_check_count++ < LINK_UP_CHECK_MAX_COUNT));
if ((val & XMLH_LINK_UP) &&
- msm_pcie_confirm_linkup(dev, false, false)) {
+ msm_pcie_confirm_linkup(dev, false, false, NULL)) {
PCIE_DBG(dev, "Link is up after %d checkings\n",
link_check_count);
PCIE_INFO(dev, "PCIe RC%d link initialized\n", dev->rc_idx);
@@ -6451,7 +6456,8 @@ static int msm_pcie_pm_suspend(struct pci_dev *dev,
}
if (dev && !(options & MSM_PCIE_CONFIG_NO_CFG_RESTORE)
- && msm_pcie_confirm_linkup(pcie_dev, true, true)) {
+ && msm_pcie_confirm_linkup(pcie_dev, true, true,
+ pcie_dev->conf)) {
ret = pci_save_state(dev);
pcie_dev->saved_state = pci_store_saved_state(dev);
}
@@ -6960,7 +6966,7 @@ int msm_pcie_recover_config(struct pci_dev *dev)
return -ENODEV;
}
- if (msm_pcie_confirm_linkup(pcie_dev, true, true)) {
+ if (msm_pcie_confirm_linkup(pcie_dev, true, true, pcie_dev->conf)) {
PCIE_DBG(pcie_dev,
"Recover config space of RC%d and its EP\n",
pcie_dev->rc_idx);