Commit 490ff95f authored by Ulf Hansson's avatar Ulf Hansson

mmc: core: Convert to mmc_poll_for_busy() for HPI commands

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: default avatarUlf Hansson <ulf.hansson@linaro.org>
Tested-by: default avatarBaolin Wang <baolin.wang7@gmail.com>
Tested-by: default avatarLudovic Barre <ludovic.barre@st.com>
Reviewed-by: default avatarLudovic Barre <ludovic.barre@st.com>
Link: https://lore.kernel.org/r/20200204085449.32585-11-ulf.hansson@linaro.org
parent 9f94d047
...@@ -471,6 +471,8 @@ static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err, ...@@ -471,6 +471,8 @@ static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err,
case MMC_BUSY_ERASE: case MMC_BUSY_ERASE:
err = R1_STATUS(status) ? -EIO : 0; err = R1_STATUS(status) ? -EIO : 0;
break; break;
case MMC_BUSY_HPI:
break;
default: default:
err = -EINVAL; err = -EINVAL;
} }
...@@ -831,6 +833,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width) ...@@ -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) 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 = {}; struct mmc_command cmd = {};
unsigned int opcode; unsigned int opcode;
int err; int err;
...@@ -852,7 +855,8 @@ static int mmc_send_hpi_cmd(struct mmc_card *card) ...@@ -852,7 +855,8 @@ static int mmc_send_hpi_cmd(struct mmc_card *card)
return err; 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) ...@@ -866,7 +870,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
{ {
int err; int err;
u32 status; u32 status;
unsigned long prg_wait;
if (!card->ext_csd.hpi_en) { if (!card->ext_csd.hpi_en) {
pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host)); pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host));
...@@ -900,19 +903,6 @@ int mmc_interrupt_hpi(struct mmc_card *card) ...@@ -900,19 +903,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
} }
err = mmc_send_hpi_cmd(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: out:
return err; return err;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
enum mmc_busy_cmd { enum mmc_busy_cmd {
MMC_BUSY_CMD6, MMC_BUSY_CMD6,
MMC_BUSY_ERASE, MMC_BUSY_ERASE,
MMC_BUSY_HPI,
}; };
struct mmc_host; struct mmc_host;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment