diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index e7c6ba369380..f2d980fe0571 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -912,19 +912,12 @@ void cnss_pci_allow_l1(struct device *dev) } EXPORT_SYMBOL(cnss_pci_allow_l1); -int cnss_pci_link_down(struct device *dev) +static void cnss_pci_handle_linkdown(struct cnss_pci_data *pci_priv) { + struct cnss_plat_data *plat_priv = pci_priv->plat_priv; + struct pci_dev *pci_dev = pci_priv->pci_dev; unsigned long flags; - struct pci_dev *pci_dev = to_pci_dev(dev); - struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev); - struct cnss_plat_data *plat_priv; - if (!pci_priv) { - cnss_pr_err("pci_priv is NULL\n"); - return -EINVAL; - } - - plat_priv = pci_priv->plat_priv; if (test_bit(ENABLE_PCI_LINK_DOWN_PANIC, &plat_priv->ctrl_params.quirks)) panic("cnss: PCI link is down\n"); @@ -933,17 +926,40 @@ int cnss_pci_link_down(struct device *dev) if (pci_priv->pci_link_down_ind) { cnss_pr_dbg("PCI link down recovery is in progress, ignore\n"); spin_unlock_irqrestore(&pci_link_down_lock, flags); - return -EINVAL; + return; } pci_priv->pci_link_down_ind = true; spin_unlock_irqrestore(&pci_link_down_lock, flags); reinit_completion(&pci_priv->wake_event); - cnss_pr_err("PCI link down is detected, schedule recovery\n"); - cnss_schedule_recovery(dev, CNSS_REASON_LINK_DOWN); + if (pci_dev->device == QCA6174_DEVICE_ID) + disable_irq(pci_dev->irq); - return 0; + cnss_fatal_err("PCI link down, schedule recovery\n"); + cnss_schedule_recovery(&pci_dev->dev, CNSS_REASON_LINK_DOWN); +} + +int cnss_pci_link_down(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev); + int ret; + + if (!pci_priv) { + cnss_pr_err("pci_priv is NULL\n"); + return -EINVAL; + } + + cnss_pr_err("PCI link down is detected by drivers\n"); + + ret = msm_pcie_pm_control(MSM_PCIE_HANDLE_LINKDOWN, + pci_dev->bus->number, pci_dev, NULL, + PM_OPTIONS_DEFAULT); + if (ret) + cnss_pci_handle_linkdown(pci_priv); + + return ret; } EXPORT_SYMBOL(cnss_pci_link_down); @@ -2400,10 +2416,8 @@ static bool cnss_pci_is_drv_supported(struct cnss_pci_data *pci_priv) static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { - unsigned long flags; struct pci_dev *pci_dev; struct cnss_pci_data *pci_priv; - struct cnss_plat_data *plat_priv; if (!notify) return; @@ -2416,27 +2430,9 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) if (!pci_priv) return; - plat_priv = pci_priv->plat_priv; switch (notify->event) { case MSM_PCIE_EVENT_LINKDOWN: - if (test_bit(ENABLE_PCI_LINK_DOWN_PANIC, - &plat_priv->ctrl_params.quirks)) - panic("cnss: PCI link is down\n"); - - spin_lock_irqsave(&pci_link_down_lock, flags); - if (pci_priv->pci_link_down_ind) { - cnss_pr_dbg("PCI link down recovery is in progress, ignore\n"); - spin_unlock_irqrestore(&pci_link_down_lock, flags); - return; - } - pci_priv->pci_link_down_ind = true; - spin_unlock_irqrestore(&pci_link_down_lock, flags); - - reinit_completion(&pci_priv->wake_event); - cnss_fatal_err("PCI link down, schedule recovery\n"); - if (pci_dev->device == QCA6174_DEVICE_ID) - disable_irq(pci_dev->irq); - cnss_schedule_recovery(&pci_dev->dev, CNSS_REASON_LINK_DOWN); + cnss_pci_handle_linkdown(pci_priv); break; case MSM_PCIE_EVENT_WAKEUP: complete(&pci_priv->wake_event);