Loading drivers/net/wireless/cnss2/debug.c +3 −0 Original line number Diff line number Diff line Loading @@ -601,6 +601,9 @@ static int cnss_show_quirks_state(struct seq_file *s, case ENABLE_DAEMON_SUPPORT: seq_puts(s, "DAEMON_SUPPORT"); continue; case DISABLE_DRV: seq_puts(s, "DISABLE_DRV"); continue; } seq_printf(s, "UNKNOWN-%d", i); Loading drivers/net/wireless/cnss2/main.c +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ #define FW_ASSERT_TIMEOUT 5000 #define CNSS_EVENT_PENDING 2989 #define CNSS_QUIRKS_DEFAULT 0 #define CNSS_QUIRKS_DEFAULT 512 #ifdef CONFIG_CNSS_EMULATION #define CNSS_MHI_TIMEOUT_DEFAULT 90000 #else Loading drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,7 @@ enum cnss_debug_quirks { ENABLE_PCI_LINK_DOWN_PANIC, FBC_BYPASS, ENABLE_DAEMON_SUPPORT, DISABLE_DRV, }; enum cnss_bdf_type { Loading drivers/net/wireless/cnss2/pci.c +161 −16 Original line number Diff line number Diff line Loading @@ -341,25 +341,91 @@ static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) return 0; } static int cnss_pci_get_link_status(struct cnss_pci_data *pci_priv) { u16 link_status; int ret; ret = pcie_capability_read_word(pci_priv->pci_dev, PCI_EXP_LNKSTA, &link_status); if (ret) return ret; cnss_pr_dbg("Get PCI link status register: %u\n", link_status); pci_priv->def_link_speed = link_status & PCI_EXP_LNKSTA_CLS; pci_priv->def_link_width = (link_status & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; cnss_pr_dbg("Default PCI link speed is 0x%x, link width is 0x%x\n", pci_priv->def_link_speed, pci_priv->def_link_width); return 0; } static int cnss_set_pci_link_status(struct cnss_pci_data *pci_priv, enum pci_link_status status) { u16 link_speed, link_width; cnss_pr_dbg("Set PCI link status to: %u\n", status); switch (status) { case PCI_GEN1: link_speed = PCI_EXP_LNKSTA_CLS_2_5GB; link_width = PCI_EXP_LNKSTA_NLW_X1 >> PCI_EXP_LNKSTA_NLW_SHIFT; break; case PCI_GEN2: link_speed = PCI_EXP_LNKSTA_CLS_5_0GB; link_width = PCI_EXP_LNKSTA_NLW_X1 >> PCI_EXP_LNKSTA_NLW_SHIFT; break; case PCI_DEF: link_speed = pci_priv->def_link_speed; link_width = pci_priv->def_link_width; if (!link_speed && !link_width) { cnss_pr_err("PCI link speed or width is not valid\n"); return -EINVAL; } break; default: cnss_pr_err("Unknown PCI link status config: %u\n", status); return -EINVAL; } return msm_pcie_set_link_bandwidth(pci_priv->pci_dev, link_speed, link_width); } static int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up) { int ret = 0; struct pci_dev *pci_dev = pci_priv->pci_dev; enum msm_pcie_pm_opt pm_ops; cnss_pr_dbg("%s PCI link\n", link_up ? "Resuming" : "Suspending"); ret = msm_pcie_pm_control(link_up ? MSM_PCIE_RESUME : MSM_PCIE_SUSPEND, pci_dev->bus->number, pci_dev, NULL, PM_OPTIONS_DEFAULT); if (ret) { if (link_up) { pm_ops = MSM_PCIE_RESUME; } else { if (pci_priv->drv_connected_last) { cnss_pr_dbg("Use PCIe DRV suspend\n"); pm_ops = MSM_PCIE_DRV_SUSPEND; cnss_set_pci_link_status(pci_priv, PCI_GEN1); } else { pm_ops = MSM_PCIE_SUSPEND; } } ret = msm_pcie_pm_control(pm_ops, pci_dev->bus->number, pci_dev, NULL, PM_OPTIONS_DEFAULT); if (ret) cnss_pr_err("Failed to %s PCI link with default option, err = %d\n", link_up ? "resume" : "suspend", ret); return ret; } return 0; if ((link_up || (!link_up && ret)) && pci_priv->drv_connected_last) cnss_set_pci_link_status(pci_priv, PCI_DEF); return ret; } int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv) Loading Loading @@ -1279,6 +1345,22 @@ int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) return 0; } static bool cnss_pci_is_drv_supported(struct cnss_pci_data *pci_priv) { struct pci_dev *root_port = pci_find_pcie_root_port(pci_priv->pci_dev); struct device_node *root_of_node = root_port->dev.of_node; bool drv_supported = false; if (root_of_node->parent) drv_supported = of_property_read_bool(root_of_node->parent, "qcom,drv-supported"); cnss_pr_dbg("PCIe DRV is %s\n", drv_supported ? "supported" : "not supported"); return drv_supported; } static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { unsigned long flags; Loading Loading @@ -1325,6 +1407,14 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) cnss_pci_pm_request_resume(pci_priv); } break; case MSM_PCIE_EVENT_DRV_CONNECT: cnss_pr_dbg("DRV subsystem is connected\n"); cnss_pci_set_drv_connected(pci_priv, 1); break; case MSM_PCIE_EVENT_DRV_DISCONNECT: cnss_pr_dbg("DRV subsystem is disconnected\n"); cnss_pci_set_drv_connected(pci_priv, 0); break; default: cnss_pr_err("Received invalid PCI event: %d\n", notify->event); } Loading @@ -1338,6 +1428,12 @@ static int cnss_reg_pci_event(struct cnss_pci_data *pci_priv) pci_event = &pci_priv->msm_pci_event; pci_event->events = MSM_PCIE_EVENT_LINKDOWN | MSM_PCIE_EVENT_WAKEUP; if (cnss_pci_is_drv_supported(pci_priv)) pci_event->events = pci_event->events | MSM_PCIE_EVENT_DRV_CONNECT | MSM_PCIE_EVENT_DRV_DISCONNECT; pci_event->user = pci_priv->pci_dev; pci_event->mode = MSM_PCIE_TRIGGER_CALLBACK; pci_event->callback = cnss_pci_event_cb; Loading @@ -1361,6 +1457,7 @@ static int cnss_pci_suspend(struct device *dev) int ret = 0; 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; struct cnss_wlan_driver *driver_ops; pm_message_t state = { .event = PM_EVENT_SUSPEND }; Loading @@ -1368,6 +1465,14 @@ static int cnss_pci_suspend(struct device *dev) if (!pci_priv) goto out; plat_priv = pci_priv->plat_priv; if (!plat_priv) goto out; if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks)) pci_priv->drv_connected_last = cnss_pci_get_drv_connected(pci_priv); driver_ops = pci_priv->driver_ops; if (driver_ops && driver_ops->suspend) { ret = driver_ops->suspend(pci_dev, state); Loading @@ -1385,16 +1490,18 @@ static int cnss_pci_suspend(struct device *dev) goto resume_driver; } if (pci_priv->drv_connected_last) goto skip_disable_pci; pci_clear_master(pci_dev); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); pci_disable_device(pci_dev); ret = pci_set_power_state(pci_dev, PCI_D3hot); if (ret) cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); skip_disable_pci: if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) { ret = -EAGAIN; goto resume_mhi; Loading @@ -1416,6 +1523,7 @@ static int cnss_pci_suspend(struct device *dev) resume_driver: if (driver_ops && driver_ops->resume) driver_ops->resume(pci_dev); pci_priv->drv_connected_last = 0; out: return ret; } Loading Loading @@ -1443,6 +1551,9 @@ static int cnss_pci_resume(struct device *dev) } pci_priv->pci_link_state = PCI_LINK_UP; if (pci_priv->drv_connected_last) goto skip_enable_pci; ret = pci_enable_device(pci_dev); if (ret) cnss_pr_err("Failed to enable PCI device, err = %d\n", Loading @@ -1451,8 +1562,9 @@ static int cnss_pci_resume(struct device *dev) if (pci_priv->saved_state) cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); pci_set_master(pci_dev); skip_enable_pci: cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME); } Loading @@ -1464,6 +1576,8 @@ static int cnss_pci_resume(struct device *dev) ret); } pci_priv->drv_connected_last = 0; return 0; out: Loading Loading @@ -1512,11 +1626,16 @@ static int cnss_pci_runtime_suspend(struct device *dev) int ret = 0; 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; struct cnss_wlan_driver *driver_ops; if (!pci_priv) return -EAGAIN; plat_priv = pci_priv->plat_priv; if (!plat_priv) return -EAGAIN; if (pci_priv->pci_link_down_ind) { cnss_pr_dbg("PCI link down recovery is in progress!\n"); return -EAGAIN; Loading @@ -1524,6 +1643,10 @@ static int cnss_pci_runtime_suspend(struct device *dev) cnss_pr_dbg("Runtime suspend start\n"); if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks)) pci_priv->drv_connected_last = cnss_pci_get_drv_connected(pci_priv); driver_ops = pci_priv->driver_ops; if (driver_ops && driver_ops->runtime_ops && driver_ops->runtime_ops->runtime_suspend) Loading @@ -1531,6 +1654,9 @@ static int cnss_pci_runtime_suspend(struct device *dev) else ret = cnss_auto_suspend(dev); if (ret) pci_priv->drv_connected_last = 0; cnss_pr_info("Runtime suspend status: %d\n", ret); return ret; Loading Loading @@ -1560,6 +1686,9 @@ static int cnss_pci_runtime_resume(struct device *dev) else ret = cnss_auto_resume(dev); if (!ret) pci_priv->drv_connected_last = 0; cnss_pr_info("Runtime resume status: %d\n", ret); return ret; Loading Loading @@ -1707,6 +1836,9 @@ int cnss_auto_suspend(struct device *dev) goto out; } if (pci_priv->drv_connected_last) goto skip_disable_pci; pci_clear_master(pci_dev); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); pci_disable_device(pci_dev); Loading @@ -1715,6 +1847,7 @@ int cnss_auto_suspend(struct device *dev) if (ret) cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); skip_disable_pci: if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) { ret = -EAGAIN; goto resume_mhi; Loading Loading @@ -1765,6 +1898,9 @@ int cnss_auto_resume(struct device *dev) } pci_priv->pci_link_state = PCI_LINK_UP; if (pci_priv->drv_connected_last) goto skip_enable_pci; ret = pci_enable_device(pci_dev); if (ret) cnss_pr_err("Failed to enable PCI device, err = %d\n", Loading @@ -1772,6 +1908,8 @@ int cnss_auto_resume(struct device *dev) cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); pci_set_master(pci_dev); skip_enable_pci: cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME); } Loading Loading @@ -3054,9 +3192,15 @@ int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, ret = 0; break; case CNSS_MHI_SUSPEND: if (pci_priv->drv_connected_last) ret = mhi_pm_fast_suspend(pci_priv->mhi_ctrl, true); else ret = mhi_pm_suspend(pci_priv->mhi_ctrl); break; case CNSS_MHI_RESUME: if (pci_priv->drv_connected_last) ret = mhi_pm_fast_resume(pci_priv->mhi_ctrl, true); else ret = mhi_pm_resume(pci_priv->mhi_ctrl); break; case CNSS_MHI_TRIGGER_RDDM: Loading Loading @@ -3219,6 +3363,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_disable_msi(pci_priv); goto disable_bus; } cnss_pci_get_link_status(pci_priv); if (EMULATION_HW) break; ret = cnss_suspend_pci_link(pci_priv); Loading drivers/net/wireless/cnss2/pci.h +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ enum cnss_mhi_state { CNSS_MHI_RDDM_DONE, }; enum pci_link_status { PCI_GEN1, PCI_GEN2, PCI_DEF, }; struct cnss_msi_user { char *name; int num_vectors; Loading Loading @@ -60,7 +66,10 @@ struct cnss_pci_data { struct pci_saved_state *default_state; struct msm_pcie_register_event msm_pci_event; atomic_t auto_suspended; atomic_t drv_connected; u8 drv_connected_last; u16 def_link_speed; u16 def_link_width; u8 monitor_wake_intr; struct dma_iommu_mapping smmu_mapping; struct iommu_domain *iommu_domain; Loading Loading @@ -126,6 +135,20 @@ static inline int cnss_pci_get_auto_suspended(void *bus_priv) return atomic_read(&pci_priv->auto_suspended); } static inline void cnss_pci_set_drv_connected(void *bus_priv, int val) { struct cnss_pci_data *pci_priv = bus_priv; atomic_set(&pci_priv->drv_connected, val); } static inline int cnss_pci_get_drv_connected(void *bus_priv) { struct cnss_pci_data *pci_priv = bus_priv; return atomic_read(&pci_priv->drv_connected); } int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); Loading Loading
drivers/net/wireless/cnss2/debug.c +3 −0 Original line number Diff line number Diff line Loading @@ -601,6 +601,9 @@ static int cnss_show_quirks_state(struct seq_file *s, case ENABLE_DAEMON_SUPPORT: seq_puts(s, "DAEMON_SUPPORT"); continue; case DISABLE_DRV: seq_puts(s, "DISABLE_DRV"); continue; } seq_printf(s, "UNKNOWN-%d", i); Loading
drivers/net/wireless/cnss2/main.c +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ #define FW_ASSERT_TIMEOUT 5000 #define CNSS_EVENT_PENDING 2989 #define CNSS_QUIRKS_DEFAULT 0 #define CNSS_QUIRKS_DEFAULT 512 #ifdef CONFIG_CNSS_EMULATION #define CNSS_MHI_TIMEOUT_DEFAULT 90000 #else Loading
drivers/net/wireless/cnss2/main.h +1 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,7 @@ enum cnss_debug_quirks { ENABLE_PCI_LINK_DOWN_PANIC, FBC_BYPASS, ENABLE_DAEMON_SUPPORT, DISABLE_DRV, }; enum cnss_bdf_type { Loading
drivers/net/wireless/cnss2/pci.c +161 −16 Original line number Diff line number Diff line Loading @@ -341,25 +341,91 @@ static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) return 0; } static int cnss_pci_get_link_status(struct cnss_pci_data *pci_priv) { u16 link_status; int ret; ret = pcie_capability_read_word(pci_priv->pci_dev, PCI_EXP_LNKSTA, &link_status); if (ret) return ret; cnss_pr_dbg("Get PCI link status register: %u\n", link_status); pci_priv->def_link_speed = link_status & PCI_EXP_LNKSTA_CLS; pci_priv->def_link_width = (link_status & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; cnss_pr_dbg("Default PCI link speed is 0x%x, link width is 0x%x\n", pci_priv->def_link_speed, pci_priv->def_link_width); return 0; } static int cnss_set_pci_link_status(struct cnss_pci_data *pci_priv, enum pci_link_status status) { u16 link_speed, link_width; cnss_pr_dbg("Set PCI link status to: %u\n", status); switch (status) { case PCI_GEN1: link_speed = PCI_EXP_LNKSTA_CLS_2_5GB; link_width = PCI_EXP_LNKSTA_NLW_X1 >> PCI_EXP_LNKSTA_NLW_SHIFT; break; case PCI_GEN2: link_speed = PCI_EXP_LNKSTA_CLS_5_0GB; link_width = PCI_EXP_LNKSTA_NLW_X1 >> PCI_EXP_LNKSTA_NLW_SHIFT; break; case PCI_DEF: link_speed = pci_priv->def_link_speed; link_width = pci_priv->def_link_width; if (!link_speed && !link_width) { cnss_pr_err("PCI link speed or width is not valid\n"); return -EINVAL; } break; default: cnss_pr_err("Unknown PCI link status config: %u\n", status); return -EINVAL; } return msm_pcie_set_link_bandwidth(pci_priv->pci_dev, link_speed, link_width); } static int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up) { int ret = 0; struct pci_dev *pci_dev = pci_priv->pci_dev; enum msm_pcie_pm_opt pm_ops; cnss_pr_dbg("%s PCI link\n", link_up ? "Resuming" : "Suspending"); ret = msm_pcie_pm_control(link_up ? MSM_PCIE_RESUME : MSM_PCIE_SUSPEND, pci_dev->bus->number, pci_dev, NULL, PM_OPTIONS_DEFAULT); if (ret) { if (link_up) { pm_ops = MSM_PCIE_RESUME; } else { if (pci_priv->drv_connected_last) { cnss_pr_dbg("Use PCIe DRV suspend\n"); pm_ops = MSM_PCIE_DRV_SUSPEND; cnss_set_pci_link_status(pci_priv, PCI_GEN1); } else { pm_ops = MSM_PCIE_SUSPEND; } } ret = msm_pcie_pm_control(pm_ops, pci_dev->bus->number, pci_dev, NULL, PM_OPTIONS_DEFAULT); if (ret) cnss_pr_err("Failed to %s PCI link with default option, err = %d\n", link_up ? "resume" : "suspend", ret); return ret; } return 0; if ((link_up || (!link_up && ret)) && pci_priv->drv_connected_last) cnss_set_pci_link_status(pci_priv, PCI_DEF); return ret; } int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv) Loading Loading @@ -1279,6 +1345,22 @@ int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) return 0; } static bool cnss_pci_is_drv_supported(struct cnss_pci_data *pci_priv) { struct pci_dev *root_port = pci_find_pcie_root_port(pci_priv->pci_dev); struct device_node *root_of_node = root_port->dev.of_node; bool drv_supported = false; if (root_of_node->parent) drv_supported = of_property_read_bool(root_of_node->parent, "qcom,drv-supported"); cnss_pr_dbg("PCIe DRV is %s\n", drv_supported ? "supported" : "not supported"); return drv_supported; } static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { unsigned long flags; Loading Loading @@ -1325,6 +1407,14 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) cnss_pci_pm_request_resume(pci_priv); } break; case MSM_PCIE_EVENT_DRV_CONNECT: cnss_pr_dbg("DRV subsystem is connected\n"); cnss_pci_set_drv_connected(pci_priv, 1); break; case MSM_PCIE_EVENT_DRV_DISCONNECT: cnss_pr_dbg("DRV subsystem is disconnected\n"); cnss_pci_set_drv_connected(pci_priv, 0); break; default: cnss_pr_err("Received invalid PCI event: %d\n", notify->event); } Loading @@ -1338,6 +1428,12 @@ static int cnss_reg_pci_event(struct cnss_pci_data *pci_priv) pci_event = &pci_priv->msm_pci_event; pci_event->events = MSM_PCIE_EVENT_LINKDOWN | MSM_PCIE_EVENT_WAKEUP; if (cnss_pci_is_drv_supported(pci_priv)) pci_event->events = pci_event->events | MSM_PCIE_EVENT_DRV_CONNECT | MSM_PCIE_EVENT_DRV_DISCONNECT; pci_event->user = pci_priv->pci_dev; pci_event->mode = MSM_PCIE_TRIGGER_CALLBACK; pci_event->callback = cnss_pci_event_cb; Loading @@ -1361,6 +1457,7 @@ static int cnss_pci_suspend(struct device *dev) int ret = 0; 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; struct cnss_wlan_driver *driver_ops; pm_message_t state = { .event = PM_EVENT_SUSPEND }; Loading @@ -1368,6 +1465,14 @@ static int cnss_pci_suspend(struct device *dev) if (!pci_priv) goto out; plat_priv = pci_priv->plat_priv; if (!plat_priv) goto out; if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks)) pci_priv->drv_connected_last = cnss_pci_get_drv_connected(pci_priv); driver_ops = pci_priv->driver_ops; if (driver_ops && driver_ops->suspend) { ret = driver_ops->suspend(pci_dev, state); Loading @@ -1385,16 +1490,18 @@ static int cnss_pci_suspend(struct device *dev) goto resume_driver; } if (pci_priv->drv_connected_last) goto skip_disable_pci; pci_clear_master(pci_dev); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); pci_disable_device(pci_dev); ret = pci_set_power_state(pci_dev, PCI_D3hot); if (ret) cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); skip_disable_pci: if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) { ret = -EAGAIN; goto resume_mhi; Loading @@ -1416,6 +1523,7 @@ static int cnss_pci_suspend(struct device *dev) resume_driver: if (driver_ops && driver_ops->resume) driver_ops->resume(pci_dev); pci_priv->drv_connected_last = 0; out: return ret; } Loading Loading @@ -1443,6 +1551,9 @@ static int cnss_pci_resume(struct device *dev) } pci_priv->pci_link_state = PCI_LINK_UP; if (pci_priv->drv_connected_last) goto skip_enable_pci; ret = pci_enable_device(pci_dev); if (ret) cnss_pr_err("Failed to enable PCI device, err = %d\n", Loading @@ -1451,8 +1562,9 @@ static int cnss_pci_resume(struct device *dev) if (pci_priv->saved_state) cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); pci_set_master(pci_dev); skip_enable_pci: cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME); } Loading @@ -1464,6 +1576,8 @@ static int cnss_pci_resume(struct device *dev) ret); } pci_priv->drv_connected_last = 0; return 0; out: Loading Loading @@ -1512,11 +1626,16 @@ static int cnss_pci_runtime_suspend(struct device *dev) int ret = 0; 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; struct cnss_wlan_driver *driver_ops; if (!pci_priv) return -EAGAIN; plat_priv = pci_priv->plat_priv; if (!plat_priv) return -EAGAIN; if (pci_priv->pci_link_down_ind) { cnss_pr_dbg("PCI link down recovery is in progress!\n"); return -EAGAIN; Loading @@ -1524,6 +1643,10 @@ static int cnss_pci_runtime_suspend(struct device *dev) cnss_pr_dbg("Runtime suspend start\n"); if (!test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks)) pci_priv->drv_connected_last = cnss_pci_get_drv_connected(pci_priv); driver_ops = pci_priv->driver_ops; if (driver_ops && driver_ops->runtime_ops && driver_ops->runtime_ops->runtime_suspend) Loading @@ -1531,6 +1654,9 @@ static int cnss_pci_runtime_suspend(struct device *dev) else ret = cnss_auto_suspend(dev); if (ret) pci_priv->drv_connected_last = 0; cnss_pr_info("Runtime suspend status: %d\n", ret); return ret; Loading Loading @@ -1560,6 +1686,9 @@ static int cnss_pci_runtime_resume(struct device *dev) else ret = cnss_auto_resume(dev); if (!ret) pci_priv->drv_connected_last = 0; cnss_pr_info("Runtime resume status: %d\n", ret); return ret; Loading Loading @@ -1707,6 +1836,9 @@ int cnss_auto_suspend(struct device *dev) goto out; } if (pci_priv->drv_connected_last) goto skip_disable_pci; pci_clear_master(pci_dev); cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); pci_disable_device(pci_dev); Loading @@ -1715,6 +1847,7 @@ int cnss_auto_suspend(struct device *dev) if (ret) cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); skip_disable_pci: if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) { ret = -EAGAIN; goto resume_mhi; Loading Loading @@ -1765,6 +1898,9 @@ int cnss_auto_resume(struct device *dev) } pci_priv->pci_link_state = PCI_LINK_UP; if (pci_priv->drv_connected_last) goto skip_enable_pci; ret = pci_enable_device(pci_dev); if (ret) cnss_pr_err("Failed to enable PCI device, err = %d\n", Loading @@ -1772,6 +1908,8 @@ int cnss_auto_resume(struct device *dev) cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); pci_set_master(pci_dev); skip_enable_pci: cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME); } Loading Loading @@ -3054,9 +3192,15 @@ int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, ret = 0; break; case CNSS_MHI_SUSPEND: if (pci_priv->drv_connected_last) ret = mhi_pm_fast_suspend(pci_priv->mhi_ctrl, true); else ret = mhi_pm_suspend(pci_priv->mhi_ctrl); break; case CNSS_MHI_RESUME: if (pci_priv->drv_connected_last) ret = mhi_pm_fast_resume(pci_priv->mhi_ctrl, true); else ret = mhi_pm_resume(pci_priv->mhi_ctrl); break; case CNSS_MHI_TRIGGER_RDDM: Loading Loading @@ -3219,6 +3363,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_disable_msi(pci_priv); goto disable_bus; } cnss_pci_get_link_status(pci_priv); if (EMULATION_HW) break; ret = cnss_suspend_pci_link(pci_priv); Loading
drivers/net/wireless/cnss2/pci.h +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ enum cnss_mhi_state { CNSS_MHI_RDDM_DONE, }; enum pci_link_status { PCI_GEN1, PCI_GEN2, PCI_DEF, }; struct cnss_msi_user { char *name; int num_vectors; Loading Loading @@ -60,7 +66,10 @@ struct cnss_pci_data { struct pci_saved_state *default_state; struct msm_pcie_register_event msm_pci_event; atomic_t auto_suspended; atomic_t drv_connected; u8 drv_connected_last; u16 def_link_speed; u16 def_link_width; u8 monitor_wake_intr; struct dma_iommu_mapping smmu_mapping; struct iommu_domain *iommu_domain; Loading Loading @@ -126,6 +135,20 @@ static inline int cnss_pci_get_auto_suspended(void *bus_priv) return atomic_read(&pci_priv->auto_suspended); } static inline void cnss_pci_set_drv_connected(void *bus_priv, int val) { struct cnss_pci_data *pci_priv = bus_priv; atomic_set(&pci_priv->drv_connected, val); } static inline int cnss_pci_get_drv_connected(void *bus_priv) { struct cnss_pci_data *pci_priv = bus_priv; return atomic_read(&pci_priv->drv_connected); } int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); Loading