wil6210: fix wil->platform_ops.suspend failure handling

Current handling of wil->platform_ops.suspend can lead to
bad cases, as wil_status_suspending was cleared before
wil_status_resuming was set and bus request voting was restored
too late.
In addition, bus voting in suspend should be done only at the end
of he suspend flow.

Change-Id: I8856d393c1796a2bd8fd5e07b233a5d61efc80c0
Signed-off-by: Maya Erez <merez@codeaurora.org>
This commit is contained in:
Maya Erez 2017-05-28 10:21:47 +03:00
parent d07260bed5
commit 60c1eb0d65

View file

@ -175,38 +175,35 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
/* Disable device reset on PERST */ /* Disable device reset on PERST */
wil_s(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); wil_s(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
/* Save the current bus request to return to the same in resume */
wil->bus_request_kbps_pre_suspend = wil->bus_request_kbps;
wil6210_bus_request(wil, 0);
if (wil->platform_ops.suspend) { if (wil->platform_ops.suspend) {
rc = wil->platform_ops.suspend(wil->platform_handle, true); rc = wil->platform_ops.suspend(wil->platform_handle, true);
if (rc) { if (rc) {
wil_err(wil, "platform device failed to suspend (%d)\n", wil_err(wil, "platform device failed to suspend (%d)\n",
rc); rc);
wil->suspend_stats.failed_suspends++; wil->suspend_stats.failed_suspends++;
clear_bit(wil_status_suspending, wil->status); wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
rc = wil_resume_keep_radio_on(wil); wil_unmask_irq(wil);
/* if resume succeeded, reject the suspend */ goto resume_after_fail;
if (!rc)
rc = -EBUSY;
goto out;
} }
} }
/* Save the current bus request to return to the same in resume */
wil->bus_request_kbps_pre_suspend = wil->bus_request_kbps;
wil6210_bus_request(wil, 0);
set_bit(wil_status_suspended, wil->status); set_bit(wil_status_suspended, wil->status);
clear_bit(wil_status_suspending, wil->status); clear_bit(wil_status_suspending, wil->status);
return rc; return rc;
resume_after_fail: resume_after_fail:
set_bit(wil_status_resuming, wil->status);
clear_bit(wil_status_suspending, wil->status); clear_bit(wil_status_suspending, wil->status);
rc = wmi_resume(wil); rc = wmi_resume(wil);
/* if resume succeeded, reject the suspend */ /* if resume succeeded, reject the suspend */
if (!rc) if (!rc)
rc = -EBUSY; rc = -EBUSY;
out:
return rc; return rc;
reject_suspend: reject_suspend: