diff options
author | Marek Puzyniak <marek.puzyniak@tieto.com> | 2014-02-10 11:14:23 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-02-13 10:24:01 -0500 |
commit | 9042e17df8340247ebed9c67f4b64228f16b4c36 (patch) | |
tree | 903ccc649de979ee8412b27b0b8a2f39dabfaa9f | |
parent | fc36e3ffcdd0ef214008d459bf8d8bff159ce16f (diff) |
ath10k: refactor suspend/resume functions
Suspend/resume callbacks are not protected by configuration mutex
so adding such protection. Also in order to simplify implemetation
of suspend function wait queue is replaced by completion.
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.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 39 |
3 files changed, 28 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 56048b1bbca5..0d161cf90608 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -55,8 +55,7 @@ static void ath10k_send_suspend_complete(struct ath10k *ar) | |||
55 | { | 55 | { |
56 | ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); | 56 | ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); |
57 | 57 | ||
58 | ar->is_target_paused = true; | 58 | complete(&ar->target_suspend); |
59 | wake_up(&ar->event_queue); | ||
60 | } | 59 | } |
61 | 60 | ||
62 | static int ath10k_init_connect_htc(struct ath10k *ar) | 61 | static int ath10k_init_connect_htc(struct ath10k *ar) |
@@ -703,6 +702,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | |||
703 | init_completion(&ar->scan.started); | 702 | init_completion(&ar->scan.started); |
704 | init_completion(&ar->scan.completed); | 703 | init_completion(&ar->scan.completed); |
705 | init_completion(&ar->scan.on_channel); | 704 | init_completion(&ar->scan.on_channel); |
705 | init_completion(&ar->target_suspend); | ||
706 | 706 | ||
707 | init_completion(&ar->install_key_done); | 707 | init_completion(&ar->install_key_done); |
708 | init_completion(&ar->vdev_setup_done); | 708 | init_completion(&ar->vdev_setup_done); |
@@ -726,8 +726,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | |||
726 | INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); | 726 | INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); |
727 | skb_queue_head_init(&ar->wmi_mgmt_tx_queue); | 727 | skb_queue_head_init(&ar->wmi_mgmt_tx_queue); |
728 | 728 | ||
729 | init_waitqueue_head(&ar->event_queue); | ||
730 | |||
731 | INIT_WORK(&ar->restart_work, ath10k_core_restart); | 729 | INIT_WORK(&ar->restart_work, ath10k_core_restart); |
732 | 730 | ||
733 | return ar; | 731 | return ar; |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index c0b00e1f7562..4f7ff9bd7813 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -375,8 +375,7 @@ struct ath10k { | |||
375 | const struct ath10k_hif_ops *ops; | 375 | const struct ath10k_hif_ops *ops; |
376 | } hif; | 376 | } hif; |
377 | 377 | ||
378 | wait_queue_head_t event_queue; | 378 | struct completion target_suspend; |
379 | bool is_target_paused; | ||
380 | 379 | ||
381 | struct ath10k_bmi bmi; | 380 | struct ath10k_bmi bmi; |
382 | struct ath10k_wmi wmi; | 381 | struct ath10k_wmi wmi; |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index e6bf2e8da770..3d905932b5a2 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -3440,21 +3440,20 @@ static int ath10k_suspend(struct ieee80211_hw *hw, | |||
3440 | struct ath10k *ar = hw->priv; | 3440 | struct ath10k *ar = hw->priv; |
3441 | int ret; | 3441 | int ret; |
3442 | 3442 | ||
3443 | ar->is_target_paused = false; | 3443 | mutex_lock(&ar->conf_mutex); |
3444 | |||
3445 | reinit_completion(&ar->target_suspend); | ||
3444 | 3446 | ||
3445 | ret = ath10k_wmi_pdev_suspend_target(ar); | 3447 | ret = ath10k_wmi_pdev_suspend_target(ar); |
3446 | if (ret) { | 3448 | if (ret) { |
3447 | ath10k_warn("could not suspend target (%d)\n", ret); | 3449 | ath10k_warn("could not suspend target (%d)\n", ret); |
3448 | return 1; | 3450 | ret = 1; |
3451 | goto exit; | ||
3449 | } | 3452 | } |
3450 | 3453 | ||
3451 | ret = wait_event_interruptible_timeout(ar->event_queue, | 3454 | ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ); |
3452 | ar->is_target_paused == true, | 3455 | |
3453 | 1 * HZ); | 3456 | if (ret == 0) { |
3454 | if (ret < 0) { | ||
3455 | ath10k_warn("suspend interrupted (%d)\n", ret); | ||
3456 | goto resume; | ||
3457 | } else if (ret == 0) { | ||
3458 | ath10k_warn("suspend timed out - target pause event never came\n"); | 3457 | ath10k_warn("suspend timed out - target pause event never came\n"); |
3459 | goto resume; | 3458 | goto resume; |
3460 | } | 3459 | } |
@@ -3465,12 +3464,17 @@ static int ath10k_suspend(struct ieee80211_hw *hw, | |||
3465 | goto resume; | 3464 | goto resume; |
3466 | } | 3465 | } |
3467 | 3466 | ||
3468 | return 0; | 3467 | ret = 0; |
3468 | goto exit; | ||
3469 | resume: | 3469 | resume: |
3470 | ret = ath10k_wmi_pdev_resume_target(ar); | 3470 | ret = ath10k_wmi_pdev_resume_target(ar); |
3471 | if (ret) | 3471 | if (ret) |
3472 | ath10k_warn("could not resume target (%d)\n", ret); | 3472 | ath10k_warn("could not resume target (%d)\n", ret); |
3473 | return 1; | 3473 | |
3474 | ret = 1; | ||
3475 | exit: | ||
3476 | mutex_unlock(&ar->conf_mutex); | ||
3477 | return ret; | ||
3474 | } | 3478 | } |
3475 | 3479 | ||
3476 | static int ath10k_resume(struct ieee80211_hw *hw) | 3480 | static int ath10k_resume(struct ieee80211_hw *hw) |
@@ -3478,19 +3482,26 @@ static int ath10k_resume(struct ieee80211_hw *hw) | |||
3478 | struct ath10k *ar = hw->priv; | 3482 | struct ath10k *ar = hw->priv; |
3479 | int ret; | 3483 | int ret; |
3480 | 3484 | ||
3485 | mutex_lock(&ar->conf_mutex); | ||
3486 | |||
3481 | ret = ath10k_hif_resume(ar); | 3487 | ret = ath10k_hif_resume(ar); |
3482 | if (ret) { | 3488 | if (ret) { |
3483 | ath10k_warn("could not resume hif (%d)\n", ret); | 3489 | ath10k_warn("could not resume hif (%d)\n", ret); |
3484 | return 1; | 3490 | ret = 1; |
3491 | goto exit; | ||
3485 | } | 3492 | } |
3486 | 3493 | ||
3487 | ret = ath10k_wmi_pdev_resume_target(ar); | 3494 | ret = ath10k_wmi_pdev_resume_target(ar); |
3488 | if (ret) { | 3495 | if (ret) { |
3489 | ath10k_warn("could not resume target (%d)\n", ret); | 3496 | ath10k_warn("could not resume target (%d)\n", ret); |
3490 | return 1; | 3497 | ret = 1; |
3498 | goto exit; | ||
3491 | } | 3499 | } |
3492 | 3500 | ||
3493 | return 0; | 3501 | ret = 0; |
3502 | exit: | ||
3503 | mutex_unlock(&ar->conf_mutex); | ||
3504 | return ret; | ||
3494 | } | 3505 | } |
3495 | #endif | 3506 | #endif |
3496 | 3507 | ||