mmc: core: Don't use ->card_busy() and CMD13 in combination when polling
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 19 Oct 2016 14:15:31 +0000 (16:15 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 29 Nov 2016 08:00:35 +0000 (09:00 +0100)
When polling for busy after sending a MMC_SWITCH command, both the optional
->card_busy() callback and CMD13 are being used in conjunction.

This doesn't make sense. Instead it's more reasonable to rely solely on the
->card_busy() callback when it exists. Let's change that and instead use
the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's
really needed.

Within this context, let's also take the opportunity to make some
additional clean-ups and clarifications to the related code.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
drivers/mmc/core/mmc_ops.c

index a84a880c986f7dc8d8a06eb04101047c15a6103f..481bbdbae6e7c8865e743e3070f3850e87da6f1a 100644 (file)
@@ -495,34 +495,32 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
        timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1;
        do {
                /*
-                * Due to the possibility of being preempted after
-                * sending the status command, check the expiration
-                * time first.
+                * Due to the possibility of being preempted while polling,
+                * check the expiration time first.
                 */
                expired = time_after(jiffies, timeout);
-               if (send_status) {
+
+               if (host->ops->card_busy) {
+                       busy = host->ops->card_busy(host);
+               } else {
                        err = __mmc_send_status(card, &status, ignore_crc);
                        if (err)
                                return err;
-               }
-               if (host->ops->card_busy) {
-                       if (!host->ops->card_busy(host))
-                               break;
-                       busy = true;
+                       busy = R1_CURRENT_STATE(status) == R1_STATE_PRG;
                }
 
-               /* Timeout if the device never leaves the program state. */
-               if (expired &&
-                   (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy)) {
-                       pr_err("%s: Card stuck in programming state! %s\n",
+               /* Timeout if the device still remains busy. */
+               if (expired && busy) {
+                       pr_err("%s: Card stuck being busy! %s\n",
                                mmc_hostname(host), __func__);
                        return -ETIMEDOUT;
                }
-       } while (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy);
+       } while (busy);
 
-       err = mmc_switch_status_error(host, status);
+       if (host->ops->card_busy && send_status)
+               return mmc_switch_status(card);
 
-       return err;
+       return mmc_switch_status_error(host, status);
 }
 
 /**