Skip to content

Commit

Permalink
ath10k: suspend hardware before reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Marek Puzyniak authored and Kalle Valo committed Feb 13, 2014
1 parent 9042e17 commit 00f5482
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
24 changes: 24 additions & 0 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,10 +858,34 @@ int ath10k_core_start(struct ath10k *ar)
}
EXPORT_SYMBOL(ath10k_core_start);

int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
{
int ret;

reinit_completion(&ar->target_suspend);

ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
if (ret) {
ath10k_warn("could not suspend target (%d)\n", ret);
return ret;
}

ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);

if (ret == 0) {
ath10k_warn("suspend timed out - target pause event never came\n");
return -ETIMEDOUT;
}

return 0;
}

void ath10k_core_stop(struct ath10k *ar)
{
lockdep_assert_held(&ar->conf_mutex);

/* try to suspend target */
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
ath10k_debug_stop(ar);
ath10k_htc_stop(&ar->htc);
ath10k_htt_detach(&ar->htt);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
void ath10k_core_destroy(struct ath10k *ar);

int ath10k_core_start(struct ath10k *ar);
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt);
void ath10k_core_stop(struct ath10k *ar);
int ath10k_core_register(struct ath10k *ar, u32 chip_id);
void ath10k_core_unregister(struct ath10k *ar);
Expand Down
14 changes: 3 additions & 11 deletions drivers/net/wireless/ath/ath10k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -3442,22 +3442,14 @@ static int ath10k_suspend(struct ieee80211_hw *hw,

mutex_lock(&ar->conf_mutex);

reinit_completion(&ar->target_suspend);

ret = ath10k_wmi_pdev_suspend_target(ar);
ret = ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND);
if (ret) {
ath10k_warn("could not suspend target (%d)\n", ret);
if (ret == -ETIMEDOUT)
goto resume;
ret = 1;
goto exit;
}

ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);

if (ret == 0) {
ath10k_warn("suspend timed out - target pause event never came\n");
goto resume;
}

ret = ath10k_hif_suspend(ar);
if (ret) {
ath10k_warn("could not suspend hif (%d)\n", ret);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath10k/wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2443,7 +2443,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
ar->wmi.cmd->pdev_set_channel_cmdid);
}

int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
{
struct wmi_pdev_suspend_cmd *cmd;
struct sk_buff *skb;
Expand All @@ -2453,7 +2453,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
return -ENOMEM;

cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
cmd->suspend_opt = WMI_PDEV_SUSPEND;
cmd->suspend_opt = __cpu_to_le32(suspend_opt);

return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath10k/wmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4193,7 +4193,7 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
int ath10k_wmi_connect_htc_service(struct ath10k *ar);
int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
const struct wmi_channel_arg *);
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar);
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
u16 rd5g, u16 ctl2g, u16 ctl5g);
Expand Down

0 comments on commit 00f5482

Please sign in to comment.