aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Puzyniak <marek.puzyniak@tieto.com>2014-02-10 11:14:24 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2014-02-13 10:24:17 -0500
commit00f5482bcd940c11b9b81e7c399fd5f4f6667bd0 (patch)
tree1209170c2d7692f5345fdb5a22bd5ce91037fa59
parent9042e17df8340247ebed9c67f4b64228f16b4c36 (diff)
ath10k: suspend hardware before reset
In case of warm reset target need to be suspended. Suspend function is extented to handle both cases with disabling interrupts and without disabling interrupts. Warm target reset requires suspend with all interrupts disabled. This patch depends on ath10k: fix device initialization routine Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c24
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c14
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h2
5 files changed, 31 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 0d161cf90608..ebc5fc2ede75 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -858,10 +858,34 @@ err:
858} 858}
859EXPORT_SYMBOL(ath10k_core_start); 859EXPORT_SYMBOL(ath10k_core_start);
860 860
861int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
862{
863 int ret;
864
865 reinit_completion(&ar->target_suspend);
866
867 ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
868 if (ret) {
869 ath10k_warn("could not suspend target (%d)\n", ret);
870 return ret;
871 }
872
873 ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
874
875 if (ret == 0) {
876 ath10k_warn("suspend timed out - target pause event never came\n");
877 return -ETIMEDOUT;
878 }
879
880 return 0;
881}
882
861void ath10k_core_stop(struct ath10k *ar) 883void ath10k_core_stop(struct ath10k *ar)
862{ 884{
863 lockdep_assert_held(&ar->conf_mutex); 885 lockdep_assert_held(&ar->conf_mutex);
864 886
887 /* try to suspend target */
888 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
865 ath10k_debug_stop(ar); 889 ath10k_debug_stop(ar);
866 ath10k_htc_stop(&ar->htc); 890 ath10k_htc_stop(&ar->htc);
867 ath10k_htt_detach(&ar->htt); 891 ath10k_htt_detach(&ar->htt);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 4f7ff9bd7813..fae53f909550 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -492,6 +492,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
492void ath10k_core_destroy(struct ath10k *ar); 492void ath10k_core_destroy(struct ath10k *ar);
493 493
494int ath10k_core_start(struct ath10k *ar); 494int ath10k_core_start(struct ath10k *ar);
495int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt);
495void ath10k_core_stop(struct ath10k *ar); 496void ath10k_core_stop(struct ath10k *ar);
496int ath10k_core_register(struct ath10k *ar, u32 chip_id); 497int ath10k_core_register(struct ath10k *ar, u32 chip_id);
497void ath10k_core_unregister(struct ath10k *ar); 498void ath10k_core_unregister(struct ath10k *ar);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3d905932b5a2..b2c65904449c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3442,22 +3442,14 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
3442 3442
3443 mutex_lock(&ar->conf_mutex); 3443 mutex_lock(&ar->conf_mutex);
3444 3444
3445 reinit_completion(&ar->target_suspend); 3445 ret = ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND);
3446
3447 ret = ath10k_wmi_pdev_suspend_target(ar);
3448 if (ret) { 3446 if (ret) {
3449 ath10k_warn("could not suspend target (%d)\n", ret); 3447 if (ret == -ETIMEDOUT)
3448 goto resume;
3450 ret = 1; 3449 ret = 1;
3451 goto exit; 3450 goto exit;
3452 } 3451 }
3453 3452
3454 ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
3455
3456 if (ret == 0) {
3457 ath10k_warn("suspend timed out - target pause event never came\n");
3458 goto resume;
3459 }
3460
3461 ret = ath10k_hif_suspend(ar); 3453 ret = ath10k_hif_suspend(ar);
3462 if (ret) { 3454 if (ret) {
3463 ath10k_warn("could not suspend hif (%d)\n", ret); 3455 ath10k_warn("could not suspend hif (%d)\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index b3c5a1faad43..91e501b5499e 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2443,7 +2443,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
2443 ar->wmi.cmd->pdev_set_channel_cmdid); 2443 ar->wmi.cmd->pdev_set_channel_cmdid);
2444} 2444}
2445 2445
2446int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) 2446int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
2447{ 2447{
2448 struct wmi_pdev_suspend_cmd *cmd; 2448 struct wmi_pdev_suspend_cmd *cmd;
2449 struct sk_buff *skb; 2449 struct sk_buff *skb;
@@ -2453,7 +2453,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
2453 return -ENOMEM; 2453 return -ENOMEM;
2454 2454
2455 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 2455 cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
2456 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2456 cmd->suspend_opt = __cpu_to_le32(suspend_opt);
2457 2457
2458 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); 2458 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
2459} 2459}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 083079f3fdd4..fc1093a51ab1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4193,7 +4193,7 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
4193int ath10k_wmi_connect_htc_service(struct ath10k *ar); 4193int ath10k_wmi_connect_htc_service(struct ath10k *ar);
4194int ath10k_wmi_pdev_set_channel(struct ath10k *ar, 4194int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
4195 const struct wmi_channel_arg *); 4195 const struct wmi_channel_arg *);
4196int ath10k_wmi_pdev_suspend_target(struct ath10k *ar); 4196int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
4197int ath10k_wmi_pdev_resume_target(struct ath10k *ar); 4197int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
4198int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, 4198int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
4199 u16 rd5g, u16 ctl2g, u16 ctl5g); 4199 u16 rd5g, u16 ctl2g, u16 ctl5g);