提交 00f5482b 编写于 作者: M Marek Puzyniak 提交者: Kalle Valo

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: NMarek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: NKalle Valo <kvalo@qca.qualcomm.com>
上级 9042e17d
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......@@ -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);
}
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册