ath6kl: Invoke WOW suspend/resume calls during PM operation
authorRaja Mani <rmani@qca.qualcomm.com>
Mon, 7 Nov 2011 20:52:46 +0000 (22:52 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Fri, 11 Nov 2011 11:00:00 +0000 (13:00 +0200)
Link ath6kl's wow suspend/resume functions with the actual suspend/resume path.

WOW mode is selected when the host sdio controller supports both
MMC_PM_KEEP_POWER and MMC_PM_WAKE_SDIO_IRQ capabilities.

kvalo: also adds a missing break in ath6kl_cfg80211_resume(), luckily
it didn't have any effect on functionality.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/sdio.c

index 8249a8c76df368eebc223b634a8b45c86dfcdf72..0e3ecf814635c8ba0ab24c737cb529e5fbcd4821 100644 (file)
@@ -1760,6 +1760,21 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
        int ret;
 
        switch (mode) {
+       case ATH6KL_CFG_SUSPEND_WOW:
+
+               ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
+
+               /* Flush all non control pkts in TX path */
+               ath6kl_tx_data_cleanup(ar);
+
+               ret = ath6kl_wow_suspend(ar, wow);
+               if (ret) {
+                       ath6kl_err("wow suspend failed: %d\n", ret);
+                       return ret;
+               }
+               ar->state = ATH6KL_STATE_WOW;
+               break;
+
        case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
 
                ath6kl_cfg80211_stop(ar);
@@ -1811,6 +1826,18 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
        int ret;
 
        switch (ar->state) {
+       case  ATH6KL_STATE_WOW:
+               ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
+
+               ret = ath6kl_wow_resume(ar);
+               if (ret) {
+                       ath6kl_warn("wow mode resume failed: %d\n", ret);
+                       return ret;
+               }
+
+               ar->state = ATH6KL_STATE_ON;
+               break;
+
        case ATH6KL_STATE_DEEPSLEEP:
                if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
                        ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
@@ -1833,6 +1860,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
                        ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
                        return ret;
                }
+               break;
 
        default:
                break;
index b576b7667b6d364ca15dd9f8cfedb65d4c6e30c6..0586b3b3ab54be9a20273fb852ca9fd7f115cbb4 100644 (file)
@@ -798,6 +798,23 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
                return ret;
        }
 
+       if ((flags & MMC_PM_WAKE_SDIO_IRQ) && wow) {
+               /*
+                * The host sdio controller is capable of keep power and
+                * sdio irq wake up at this point. It's fine to continue
+                * wow suspend operation.
+                */
+               ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
+               if (ret)
+                       return ret;
+
+               ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+               if (ret)
+                       ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+
+               return ret;
+       }
+
        return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL);
 }
 
@@ -820,6 +837,9 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
 
        case ATH6KL_STATE_DEEPSLEEP:
                break;
+
+       case ATH6KL_STATE_WOW:
+               break;
        }
 
        ath6kl_cfg80211_resume(ar);