mmc: core: Convert to mmc_poll_for_busy() for HPI commands
authorUlf Hansson <ulf.hansson@linaro.org>
Tue, 4 Feb 2020 08:54:47 +0000 (09:54 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 24 Mar 2020 13:35:40 +0000 (14:35 +0100)
Rather than open coding the polling loop in mmc_interrupt_hpi(), let's
convert to use mmc_poll_for_busy().

Note that, moving to mmc_poll_for_busy() for HPI also improves the
behaviour according to below.

- Adds support for polling via the optional ->card_busy() host ops.
- Require R1_READY_FOR_DATA to be set in the CMD13 response before exiting
  the polling loop.
- Adds a throttling mechanism to avoid CPU hogging when polling.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Baolin Wang <baolin.wang7@gmail.com>
Tested-by: Ludovic Barre <ludovic.barre@st.com>
Reviewed-by: Ludovic Barre <ludovic.barre@st.com>
Link: https://lore.kernel.org/r/20200204085449.32585-11-ulf.hansson@linaro.org
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/mmc_ops.h

index 7d150e6..0099f39 100644 (file)
@@ -471,6 +471,8 @@ static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err,
        case MMC_BUSY_ERASE:
                err = R1_STATUS(status) ? -EIO : 0;
                break;
+       case MMC_BUSY_HPI:
+               break;
        default:
                err = -EINVAL;
        }
@@ -831,6 +833,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width)
 
 static int mmc_send_hpi_cmd(struct mmc_card *card)
 {
+       unsigned int busy_timeout_ms = card->ext_csd.out_of_int_time;
        struct mmc_command cmd = {};
        unsigned int opcode;
        int err;
@@ -852,7 +855,8 @@ static int mmc_send_hpi_cmd(struct mmc_card *card)
                return err;
        }
 
-       return 0;
+       /* Let's poll to find out when the HPI request completes. */
+       return mmc_poll_for_busy(card, busy_timeout_ms, MMC_BUSY_HPI);
 }
 
 /**
@@ -866,7 +870,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
 {
        int err;
        u32 status;
-       unsigned long prg_wait;
 
        if (!card->ext_csd.hpi_en) {
                pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host));
@@ -900,19 +903,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
        }
 
        err = mmc_send_hpi_cmd(card);
-       if (err)
-               goto out;
-
-       prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time);
-       do {
-               err = mmc_send_status(card, &status);
-
-               if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN)
-                       break;
-               if (time_after(jiffies, prg_wait))
-                       err = -ETIMEDOUT;
-       } while (!err);
-
 out:
        return err;
 }
index 8cd05fb..38dcfee 100644 (file)
@@ -13,6 +13,7 @@
 enum mmc_busy_cmd {
        MMC_BUSY_CMD6,
        MMC_BUSY_ERASE,
+       MMC_BUSY_HPI,
 };
 
 struct mmc_host;