mmc: core: Prevent too long response times for suspend
authorUlf Hansson <ulf.hansson@stericsson.com>
Thu, 13 Oct 2011 14:03:58 +0000 (16:03 +0200)
committerChris Ball <cjb@laptop.org>
Wed, 26 Oct 2011 20:32:31 +0000 (16:32 -0400)
While trying to suspend the mmc host there could still be
ongoing requests that we need to wait for. At the same time
a device driver must respond to a suspend request rather quickly.

Instead of potentially wait "forever" by claiming the host we now
"try" to claim the host instead. If it fails, -EBUSY is returned.

Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Reviewed-by: Sujit Reddy Thumma <sthumma@codeaurora.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/core/core.c

index fe65bb3..5278ffb 100644 (file)
@@ -2294,21 +2294,33 @@ int mmc_suspend_host(struct mmc_host *host)
 
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
-               if (host->bus_ops->suspend)
-                       err = host->bus_ops->suspend(host);
-               if (err == -ENOSYS || !host->bus_ops->resume) {
-                       /*
-                        * We simply "remove" the card in this case.
-                        * It will be redetected on resume.
-                        */
-                       if (host->bus_ops->remove)
-                               host->bus_ops->remove(host);
-                       mmc_claim_host(host);
-                       mmc_detach_bus(host);
-                       mmc_power_off(host);
-                       mmc_release_host(host);
-                       host->pm_flags = 0;
-                       err = 0;
+
+               /*
+                * A long response time is not acceptable for device drivers
+                * when doing suspend. Prevent mmc_claim_host in the suspend
+                * sequence, to potentially wait "forever" by trying to
+                * pre-claim the host.
+                */
+               if (mmc_try_claim_host(host)) {
+                       if (host->bus_ops->suspend)
+                               err = host->bus_ops->suspend(host);
+                       if (err == -ENOSYS || !host->bus_ops->resume) {
+                               /*
+                                * We simply "remove" the card in this case.
+                                * It will be redetected on resume.
+                                */
+                               if (host->bus_ops->remove)
+                                       host->bus_ops->remove(host);
+                               mmc_claim_host(host);
+                               mmc_detach_bus(host);
+                               mmc_power_off(host);
+                               mmc_release_host(host);
+                               host->pm_flags = 0;
+                               err = 0;
+                       }
+                       mmc_do_release_host(host);
+               } else {
+                       err = -EBUSY;
                }
        }
        mmc_bus_put(host);