OSDN Git Service

wil6210: fix wil->platform_ops.suspend failure handling
authorMaya Erez <merez@codeaurora.org>
Sun, 28 May 2017 07:21:47 +0000 (10:21 +0300)
committerMaya Erez <merez@codeaurora.org>
Sun, 28 May 2017 07:45:19 +0000 (10:45 +0300)
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>
drivers/net/wireless/ath/wil6210/pm.c

index 53722a6..b4faf82 100644 (file)
@@ -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: