Commit aa6cffc1 authored by Chilam Ng's avatar Chilam Ng Committed by Kalle Valo

ath6kl: make sure WLAN power save is enabled during suspend

Power save is enabled during ath6kl init. But when user space disables power
save, the system will go into suspend with power save disabled. The ath6kl
driver will now explicitly enable power save prior to entering suspend and
restore its previous setting upon resume
Signed-off-by: default avatarChilam Ng <chilamng@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 4533d901
...@@ -1421,6 +1421,13 @@ static int ar6k_cfg80211_suspend(struct wiphy *wiphy, ...@@ -1421,6 +1421,13 @@ static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
return ath6kl_hif_suspend(ar); return ath6kl_hif_suspend(ar);
} }
static int ar6k_cfg80211_resume(struct wiphy *wiphy)
{
struct ath6kl *ar = wiphy_priv(wiphy);
return ath6kl_hif_resume(ar);
}
#endif #endif
static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
...@@ -1832,6 +1839,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { ...@@ -1832,6 +1839,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
CFG80211_TESTMODE_CMD(ath6kl_tm_cmd) CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = ar6k_cfg80211_suspend, .suspend = ar6k_cfg80211_suspend,
.resume = ar6k_cfg80211_resume,
#endif #endif
.set_channel = ath6kl_set_channel, .set_channel = ath6kl_set_channel,
.add_beacon = ath6kl_add_beacon, .add_beacon = ath6kl_add_beacon,
......
...@@ -74,4 +74,8 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar) ...@@ -74,4 +74,8 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar)
return ar->hif_ops->suspend(ar); return ar->hif_ops->suspend(ar);
} }
static inline int ath6kl_hif_resume(struct ath6kl *ar)
{
return ar->hif_ops->resume(ar);
}
#endif #endif
...@@ -203,6 +203,7 @@ struct ath6kl_hif_ops { ...@@ -203,6 +203,7 @@ struct ath6kl_hif_ops {
struct hif_scatter_req *scat_req); struct hif_scatter_req *scat_req);
void (*cleanup_scatter)(struct ath6kl *ar); void (*cleanup_scatter)(struct ath6kl *ar);
int (*suspend)(struct ath6kl *ar); int (*suspend)(struct ath6kl *ar);
int (*resume)(struct ath6kl *ar);
}; };
#endif #endif
...@@ -959,6 +959,13 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar) ...@@ -959,6 +959,13 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
"during suspend\n"); "during suspend\n");
ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED); ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
/* save the current power mode before enabling power save */
ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
if (ath6kl_wmi_powermode_cmd(ar->wmi, REC_POWER) != 0)
ath6kl_warn("ath6kl_deep_sleep_enable: "
"wmi_powermode_cmd failed\n");
} }
/* WMI Event handlers */ /* WMI Event handlers */
......
...@@ -743,6 +743,18 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar) ...@@ -743,6 +743,18 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar)
return 0; return 0;
} }
static int ath6kl_sdio_resume(struct ath6kl *ar)
{
if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
if (ath6kl_wmi_powermode_cmd(ar->wmi,
ar->wmi->saved_pwr_mode) != 0)
ath6kl_warn("ath6kl_sdio_resume: "
"wmi_powermode_cmd failed\n");
}
return 0;
}
static const struct ath6kl_hif_ops ath6kl_sdio_ops = { static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
.read_write_sync = ath6kl_sdio_read_write_sync, .read_write_sync = ath6kl_sdio_read_write_sync,
.write_async = ath6kl_sdio_write_async, .write_async = ath6kl_sdio_write_async,
...@@ -754,6 +766,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = { ...@@ -754,6 +766,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
.scat_req_rw = ath6kl_sdio_async_rw_scatter, .scat_req_rw = ath6kl_sdio_async_rw_scatter,
.cleanup_scatter = ath6kl_sdio_cleanup_scatter, .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
.suspend = ath6kl_sdio_suspend, .suspend = ath6kl_sdio_suspend,
.resume = ath6kl_sdio_resume,
}; };
static int ath6kl_sdio_probe(struct sdio_func *func, static int ath6kl_sdio_probe(struct sdio_func *func,
......
...@@ -132,6 +132,7 @@ struct wmi { ...@@ -132,6 +132,7 @@ struct wmi {
u8 *last_mgmt_tx_frame; u8 *last_mgmt_tx_frame;
size_t last_mgmt_tx_frame_len; size_t last_mgmt_tx_frame_len;
u8 saved_pwr_mode;
}; };
struct host_app_area { struct host_app_area {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment