msm: pcie : Notify client driver on reading FF's
Disable access to PCIE config space registers and notify client driver to recover link on reading PCIE endpoint config registers as FF's. Change-Id: Iea6b25036bc6d967d6598d08348bb41fc18ef304 Signed-off-by: Vivek Pernamitta <vpernami@codeaurora.org>
This commit is contained in:
@@ -762,6 +762,8 @@ struct msm_pcie_dev_t {
|
|||||||
struct pinctrl_state *pins_default;
|
struct pinctrl_state *pins_default;
|
||||||
struct pinctrl_state *pins_sleep;
|
struct pinctrl_state *pins_sleep;
|
||||||
struct msm_pcie_device_info pcidev_table[MAX_DEVICE_NUM];
|
struct msm_pcie_device_info pcidev_table[MAX_DEVICE_NUM];
|
||||||
|
bool config_recovery;
|
||||||
|
struct work_struct link_recover_wq;
|
||||||
|
|
||||||
struct msm_pcie_drv_info *drv_info;
|
struct msm_pcie_drv_info *drv_info;
|
||||||
|
|
||||||
@@ -2946,14 +2948,22 @@ static inline int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
|
|||||||
|
|
||||||
if (dev->shadow_en) {
|
if (dev->shadow_en) {
|
||||||
if (rd_val == PCIE_LINK_DOWN &&
|
if (rd_val == PCIE_LINK_DOWN &&
|
||||||
(readl_relaxed(config_base) == PCIE_LINK_DOWN))
|
(readl_relaxed(config_base) == PCIE_LINK_DOWN)) {
|
||||||
PCIE_ERR(dev,
|
PCIE_ERR(dev,
|
||||||
"Read of RC%d %d:0x%02x + 0x%04x[%d] is all FFs\n",
|
"Read of RC%d %d:0x%02x + 0x%04x[%d] is all FFs\n",
|
||||||
rc_idx, bus->number, devfn,
|
rc_idx, bus->number, devfn,
|
||||||
where, size);
|
where, size);
|
||||||
else
|
if (dev->config_recovery) {
|
||||||
|
PCIE_ERR(dev,
|
||||||
|
"RC%d link recovery schedule\n",
|
||||||
|
rc_idx);
|
||||||
|
dev->cfg_access = false;
|
||||||
|
schedule_work(&dev->link_recover_wq);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
msm_pcie_save_shadow(dev, word_offset, wr_val,
|
msm_pcie_save_shadow(dev, word_offset, wr_val,
|
||||||
bdf, rc);
|
bdf, rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIE_DBG3(dev,
|
PCIE_DBG3(dev,
|
||||||
@@ -4859,6 +4869,16 @@ static void handle_wake_func(struct work_struct *work)
|
|||||||
mutex_unlock(&dev->recovery_lock);
|
mutex_unlock(&dev->recovery_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_link_recover(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct msm_pcie_dev_t *dev = container_of(work, struct msm_pcie_dev_t,
|
||||||
|
link_recover_wq);
|
||||||
|
|
||||||
|
PCIE_DBG(dev, "PCIe: link recover start for RC%d\n", dev->rc_idx);
|
||||||
|
|
||||||
|
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINK_RECOVER);
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t handle_aer_irq(int irq, void *data)
|
static irqreturn_t handle_aer_irq(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct msm_pcie_dev_t *dev = data;
|
struct msm_pcie_dev_t *dev = data;
|
||||||
@@ -6000,6 +6020,14 @@ static int msm_pcie_probe(struct platform_device *pdev)
|
|||||||
msm_pcie_gpio_deinit(pcie_dev);
|
msm_pcie_gpio_deinit(pcie_dev);
|
||||||
goto decrease_rc_num;
|
goto decrease_rc_num;
|
||||||
}
|
}
|
||||||
|
pcie_dev->config_recovery = of_property_read_bool(of_node,
|
||||||
|
"qcom,config-recovery");
|
||||||
|
if (pcie_dev->config_recovery) {
|
||||||
|
PCIE_DUMP(pcie_dev,
|
||||||
|
"PCIe RC%d config space recovery enabled\n",
|
||||||
|
pcie_dev->rc_idx);
|
||||||
|
INIT_WORK(&pcie_dev->link_recover_wq, handle_link_recover);
|
||||||
|
}
|
||||||
|
|
||||||
drv_supported = of_property_read_bool(of_node, "qcom,drv-supported");
|
drv_supported = of_property_read_bool(of_node, "qcom,drv-supported");
|
||||||
if (drv_supported) {
|
if (drv_supported) {
|
||||||
@@ -6755,6 +6783,15 @@ static int msm_pcie_pm_suspend(struct pci_dev *dev,
|
|||||||
pcie_dev->suspending = true;
|
pcie_dev->suspending = true;
|
||||||
spin_unlock_irqrestore(&pcie_dev->irq_lock, irqsave_flags);
|
spin_unlock_irqrestore(&pcie_dev->irq_lock, irqsave_flags);
|
||||||
|
|
||||||
|
if (pcie_dev->config_recovery) {
|
||||||
|
if (work_pending(&pcie_dev->link_recover_wq)) {
|
||||||
|
PCIE_DBG(pcie_dev,
|
||||||
|
"RC%d: cancel link_recover_wq at pm suspend\n",
|
||||||
|
pcie_dev->rc_idx);
|
||||||
|
cancel_work_sync(&pcie_dev->link_recover_wq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pcie_dev->power_on) {
|
if (!pcie_dev->power_on) {
|
||||||
PCIE_DBG(pcie_dev,
|
PCIE_DBG(pcie_dev,
|
||||||
"PCIe: power of RC%d has been turned off.\n",
|
"PCIe: power of RC%d has been turned off.\n",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ enum msm_pcie_event {
|
|||||||
MSM_PCIE_EVENT_L1SS_TIMEOUT = BIT(3),
|
MSM_PCIE_EVENT_L1SS_TIMEOUT = BIT(3),
|
||||||
MSM_PCIE_EVENT_DRV_CONNECT = BIT(4),
|
MSM_PCIE_EVENT_DRV_CONNECT = BIT(4),
|
||||||
MSM_PCIE_EVENT_DRV_DISCONNECT = BIT(5),
|
MSM_PCIE_EVENT_DRV_DISCONNECT = BIT(5),
|
||||||
|
MSM_PCIE_EVENT_LINK_RECOVER = BIT(6),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum msm_pcie_trigger {
|
enum msm_pcie_trigger {
|
||||||
|
|||||||
Reference in New Issue
Block a user