From 60c1eb0d65f42481d99fa891ee80a8b3209c6702 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Sun, 28 May 2017 10:21:47 +0300 Subject: [PATCH] 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 --- drivers/net/wireless/ath/wil6210/pm.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 53722a6219a7..b4faf8212348 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -175,38 +175,35 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) /* Disable device reset on PERST */ 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) { rc = wil->platform_ops.suspend(wil->platform_handle, true); if (rc) { wil_err(wil, "platform device failed to suspend (%d)\n", rc); wil->suspend_stats.failed_suspends++; - clear_bit(wil_status_suspending, wil->status); - rc = wil_resume_keep_radio_on(wil); - /* if resume succeeded, reject the suspend */ - if (!rc) - rc = -EBUSY; - goto out; + wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); + wil_unmask_irq(wil); + goto resume_after_fail; } } + /* 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); clear_bit(wil_status_suspending, wil->status); return rc; resume_after_fail: + set_bit(wil_status_resuming, wil->status); clear_bit(wil_status_suspending, wil->status); rc = wmi_resume(wil); /* if resume succeeded, reject the suspend */ if (!rc) rc = -EBUSY; -out: return rc; reject_suspend: