Loading drivers/net/wireless/cnss2/pci.c +75 −6 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ static DEFINE_SPINLOCK(pci_reg_window_lock); #define WINDOW_START MAX_UNWINDOWED_ADDRESS #define WINDOW_RANGE_MASK 0x7FFFF #define FORCE_WAKE_DELAY_MIN_US 4000 #define FORCE_WAKE_DELAY_MAX_US 6000 #define FORCE_WAKE_DELAY_TIMEOUT_US 60000 #define QCA6390_TIME_SYNC_ENABLE 0x80000000 #define QCA6390_TIME_SYNC_CLEAR 0x0 Loading Loading @@ -266,6 +270,44 @@ static int cnss_pci_reg_write(struct cnss_pci_data *pci_priv, u32 offset, return 0; } static int cnss_pci_force_wake_get(struct cnss_pci_data *pci_priv) { struct device *dev = &pci_priv->pci_dev->dev; u32 timeout = 0; int ret; ret = cnss_pci_force_wake_request(dev); if (ret) { cnss_pr_err("Failed to request force wake\n"); return ret; } while (!cnss_pci_is_device_awake(dev) && timeout <= FORCE_WAKE_DELAY_TIMEOUT_US) { usleep_range(FORCE_WAKE_DELAY_MIN_US, FORCE_WAKE_DELAY_MAX_US); timeout += FORCE_WAKE_DELAY_MAX_US; } if (cnss_pci_is_device_awake(dev) != true) { cnss_pr_err("Timed out to request force wake\n"); return -ETIMEDOUT; } return 0; } static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) { struct device *dev = &pci_priv->pci_dev->dev; int ret; ret = cnss_pci_force_wake_release(dev); if (ret) cnss_pr_err("Failed to release force wake\n"); return ret; } static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) { struct pci_dev *pci_dev = pci_priv->pci_dev; Loading Loading @@ -491,22 +533,23 @@ static int cnss_pci_update_timestamp(struct cnss_pci_data *pci_priv) u32 low, high; int ret; ret = cnss_pci_is_device_down(&pci_priv->pci_dev->dev); ret = cnss_pci_check_link_status(pci_priv); if (ret) return ret; ret = cnss_pci_check_link_status(pci_priv); ret = cnss_pci_force_wake_get(pci_priv); if (ret) return ret; host_time_us = cnss_get_host_timestamp(plat_priv); ret = cnss_pci_get_device_timestamp(pci_priv, &device_time_us); if (ret) return ret; goto force_wake_put; if (host_time_us < device_time_us) { cnss_pr_err("Host time (%llu us) is smaller than device time (%llu us), stop\n"); return -EINVAL; ret = -EINVAL; goto force_wake_put; } offset = host_time_us - device_time_us; Loading @@ -519,7 +562,17 @@ static int cnss_pci_update_timestamp(struct cnss_pci_data *pci_priv) cnss_pci_reg_write(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_34, low); cnss_pci_reg_write(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_35, high); return 0; cnss_pci_reg_read(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_34, &low); cnss_pci_reg_read(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_35, &high); cnss_pr_dbg("Updated time sync regs [0x%x] = 0x%x, [0x%x] = 0x%x\n", QCA6390_PCIE_SHADOW_REG_VALUE_34, low, QCA6390_PCIE_SHADOW_REG_VALUE_35, high); force_wake_put: cnss_pci_force_wake_put(pci_priv); return ret; } static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) Loading @@ -527,9 +580,17 @@ static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) struct cnss_pci_data *pci_priv = container_of(work, struct cnss_pci_data, time_sync_work.work); cnss_pci_update_timestamp(pci_priv); if (cnss_pci_is_device_down(&pci_priv->pci_dev->dev)) return; if (cnss_pci_pm_runtime_get_sync(pci_priv) < 0) return; cnss_pci_update_timestamp(pci_priv); schedule_delayed_work(&pci_priv->time_sync_work, TIME_SYNC_PERIOD_JF); cnss_pci_pm_runtime_mark_last_busy(pci_priv); cnss_pci_pm_runtime_put_autosuspend(pci_priv); } static int cnss_pci_start_time_sync_update(struct cnss_pci_data *pci_priv) Loading Loading @@ -1585,6 +1646,14 @@ int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv) return pm_runtime_get(&pci_priv->pci_dev->dev); } int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv) { if (!pci_priv) return -ENODEV; return pm_runtime_get_sync(&pci_priv->pci_dev->dev); } void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv) { if (!pci_priv) Loading drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv); int cnss_pci_pm_request_resume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_resume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv); Loading Loading
drivers/net/wireless/cnss2/pci.c +75 −6 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ static DEFINE_SPINLOCK(pci_reg_window_lock); #define WINDOW_START MAX_UNWINDOWED_ADDRESS #define WINDOW_RANGE_MASK 0x7FFFF #define FORCE_WAKE_DELAY_MIN_US 4000 #define FORCE_WAKE_DELAY_MAX_US 6000 #define FORCE_WAKE_DELAY_TIMEOUT_US 60000 #define QCA6390_TIME_SYNC_ENABLE 0x80000000 #define QCA6390_TIME_SYNC_CLEAR 0x0 Loading Loading @@ -266,6 +270,44 @@ static int cnss_pci_reg_write(struct cnss_pci_data *pci_priv, u32 offset, return 0; } static int cnss_pci_force_wake_get(struct cnss_pci_data *pci_priv) { struct device *dev = &pci_priv->pci_dev->dev; u32 timeout = 0; int ret; ret = cnss_pci_force_wake_request(dev); if (ret) { cnss_pr_err("Failed to request force wake\n"); return ret; } while (!cnss_pci_is_device_awake(dev) && timeout <= FORCE_WAKE_DELAY_TIMEOUT_US) { usleep_range(FORCE_WAKE_DELAY_MIN_US, FORCE_WAKE_DELAY_MAX_US); timeout += FORCE_WAKE_DELAY_MAX_US; } if (cnss_pci_is_device_awake(dev) != true) { cnss_pr_err("Timed out to request force wake\n"); return -ETIMEDOUT; } return 0; } static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv) { struct device *dev = &pci_priv->pci_dev->dev; int ret; ret = cnss_pci_force_wake_release(dev); if (ret) cnss_pr_err("Failed to release force wake\n"); return ret; } static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) { struct pci_dev *pci_dev = pci_priv->pci_dev; Loading Loading @@ -491,22 +533,23 @@ static int cnss_pci_update_timestamp(struct cnss_pci_data *pci_priv) u32 low, high; int ret; ret = cnss_pci_is_device_down(&pci_priv->pci_dev->dev); ret = cnss_pci_check_link_status(pci_priv); if (ret) return ret; ret = cnss_pci_check_link_status(pci_priv); ret = cnss_pci_force_wake_get(pci_priv); if (ret) return ret; host_time_us = cnss_get_host_timestamp(plat_priv); ret = cnss_pci_get_device_timestamp(pci_priv, &device_time_us); if (ret) return ret; goto force_wake_put; if (host_time_us < device_time_us) { cnss_pr_err("Host time (%llu us) is smaller than device time (%llu us), stop\n"); return -EINVAL; ret = -EINVAL; goto force_wake_put; } offset = host_time_us - device_time_us; Loading @@ -519,7 +562,17 @@ static int cnss_pci_update_timestamp(struct cnss_pci_data *pci_priv) cnss_pci_reg_write(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_34, low); cnss_pci_reg_write(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_35, high); return 0; cnss_pci_reg_read(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_34, &low); cnss_pci_reg_read(pci_priv, QCA6390_PCIE_SHADOW_REG_VALUE_35, &high); cnss_pr_dbg("Updated time sync regs [0x%x] = 0x%x, [0x%x] = 0x%x\n", QCA6390_PCIE_SHADOW_REG_VALUE_34, low, QCA6390_PCIE_SHADOW_REG_VALUE_35, high); force_wake_put: cnss_pci_force_wake_put(pci_priv); return ret; } static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) Loading @@ -527,9 +580,17 @@ static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) struct cnss_pci_data *pci_priv = container_of(work, struct cnss_pci_data, time_sync_work.work); cnss_pci_update_timestamp(pci_priv); if (cnss_pci_is_device_down(&pci_priv->pci_dev->dev)) return; if (cnss_pci_pm_runtime_get_sync(pci_priv) < 0) return; cnss_pci_update_timestamp(pci_priv); schedule_delayed_work(&pci_priv->time_sync_work, TIME_SYNC_PERIOD_JF); cnss_pci_pm_runtime_mark_last_busy(pci_priv); cnss_pci_pm_runtime_put_autosuspend(pci_priv); } static int cnss_pci_start_time_sync_update(struct cnss_pci_data *pci_priv) Loading Loading @@ -1585,6 +1646,14 @@ int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv) return pm_runtime_get(&pci_priv->pci_dev->dev); } int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv) { if (!pci_priv) return -ENODEV; return pm_runtime_get_sync(&pci_priv->pci_dev->dev); } void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv) { if (!pci_priv) Loading
drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv); int cnss_pci_pm_request_resume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_resume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv); Loading