Loading drivers/pci/controller/pci-msm.c +39 −2 Original line number Original line Diff line number Diff line Loading @@ -835,6 +835,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; Loading Loading @@ -3217,15 +3219,23 @@ 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, "RC%d %d:0x%02x + 0x%04x[%d] <- 0x%08x; rd 0x%08x val 0x%08x\n", "RC%d %d:0x%02x + 0x%04x[%d] <- 0x%08x; rd 0x%08x val 0x%08x\n", Loading Loading @@ -5236,6 +5246,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; Loading Loading @@ -6444,6 +6464,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) { Loading Loading @@ -7241,6 +7269,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", Loading include/linux/msm_pcie.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading Loading
drivers/pci/controller/pci-msm.c +39 −2 Original line number Original line Diff line number Diff line Loading @@ -835,6 +835,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; Loading Loading @@ -3217,15 +3219,23 @@ 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, "RC%d %d:0x%02x + 0x%04x[%d] <- 0x%08x; rd 0x%08x val 0x%08x\n", "RC%d %d:0x%02x + 0x%04x[%d] <- 0x%08x; rd 0x%08x val 0x%08x\n", Loading Loading @@ -5236,6 +5246,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; Loading Loading @@ -6444,6 +6464,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) { Loading Loading @@ -7241,6 +7269,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", Loading
include/linux/msm_pcie.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading