Commit 3977a3fb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Restore (mostly) the busy polling for MMC_SEND_OP_COND

  MMC host:
   - meson-gx: Fix DMA usage of meson_mmc_post_req()"

* tag 'mmc-v5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: core: Restore (almost) the busy polling for MMC_SEND_OP_COND
  mmc: meson: Fix usage of meson_mmc_post_req()
parents 93ce9358 1760fdb6
...@@ -1908,7 +1908,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req) ...@@ -1908,7 +1908,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
cb_data.card = card; cb_data.card = card;
cb_data.status = 0; cb_data.status = 0;
err = __mmc_poll_for_busy(card->host, MMC_BLK_TIMEOUT_MS, err = __mmc_poll_for_busy(card->host, 0, MMC_BLK_TIMEOUT_MS,
&mmc_blk_busy_cb, &cb_data); &mmc_blk_busy_cb, &cb_data);
/* /*
......
...@@ -1962,7 +1962,7 @@ static int mmc_sleep(struct mmc_host *host) ...@@ -1962,7 +1962,7 @@ static int mmc_sleep(struct mmc_host *host)
goto out_release; goto out_release;
} }
err = __mmc_poll_for_busy(host, timeout_ms, &mmc_sleep_busy_cb, host); err = __mmc_poll_for_busy(host, 0, timeout_ms, &mmc_sleep_busy_cb, host);
out_release: out_release:
mmc_retune_release(host); mmc_retune_release(host);
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */ #define MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */
#define MMC_SANITIZE_TIMEOUT_MS (240 * 1000) /* 240s */ #define MMC_SANITIZE_TIMEOUT_MS (240 * 1000) /* 240s */
#define MMC_OP_COND_PERIOD_US (1 * 1000) /* 1ms */
#define MMC_OP_COND_TIMEOUT_MS 1000 /* 1s */
static const u8 tuning_blk_pattern_4bit[] = { static const u8 tuning_blk_pattern_4bit[] = {
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
...@@ -232,7 +234,9 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) ...@@ -232,7 +234,9 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
err = __mmc_poll_for_busy(host, 1000, &__mmc_send_op_cond_cb, &cb_data); err = __mmc_poll_for_busy(host, MMC_OP_COND_PERIOD_US,
MMC_OP_COND_TIMEOUT_MS,
&__mmc_send_op_cond_cb, &cb_data);
if (err) if (err)
return err; return err;
...@@ -495,13 +499,14 @@ static int mmc_busy_cb(void *cb_data, bool *busy) ...@@ -495,13 +499,14 @@ static int mmc_busy_cb(void *cb_data, bool *busy)
return 0; return 0;
} }
int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms, int __mmc_poll_for_busy(struct mmc_host *host, unsigned int period_us,
unsigned int timeout_ms,
int (*busy_cb)(void *cb_data, bool *busy), int (*busy_cb)(void *cb_data, bool *busy),
void *cb_data) void *cb_data)
{ {
int err; int err;
unsigned long timeout; unsigned long timeout;
unsigned int udelay = 32, udelay_max = 32768; unsigned int udelay = period_us ? period_us : 32, udelay_max = 32768;
bool expired = false; bool expired = false;
bool busy = false; bool busy = false;
...@@ -546,7 +551,7 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, ...@@ -546,7 +551,7 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
cb_data.retry_crc_err = retry_crc_err; cb_data.retry_crc_err = retry_crc_err;
cb_data.busy_cmd = busy_cmd; cb_data.busy_cmd = busy_cmd;
return __mmc_poll_for_busy(host, timeout_ms, &mmc_busy_cb, &cb_data); return __mmc_poll_for_busy(host, 0, timeout_ms, &mmc_busy_cb, &cb_data);
} }
EXPORT_SYMBOL_GPL(mmc_poll_for_busy); EXPORT_SYMBOL_GPL(mmc_poll_for_busy);
......
...@@ -41,7 +41,8 @@ int mmc_can_ext_csd(struct mmc_card *card); ...@@ -41,7 +41,8 @@ int mmc_can_ext_csd(struct mmc_card *card);
int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd, bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd,
unsigned int timeout_ms); unsigned int timeout_ms);
int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms, int __mmc_poll_for_busy(struct mmc_host *host, unsigned int period_us,
unsigned int timeout_ms,
int (*busy_cb)(void *cb_data, bool *busy), int (*busy_cb)(void *cb_data, bool *busy),
void *cb_data); void *cb_data);
int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
......
...@@ -1672,7 +1672,7 @@ static int sd_poweroff_notify(struct mmc_card *card) ...@@ -1672,7 +1672,7 @@ static int sd_poweroff_notify(struct mmc_card *card)
cb_data.card = card; cb_data.card = card;
cb_data.reg_buf = reg_buf; cb_data.reg_buf = reg_buf;
err = __mmc_poll_for_busy(card->host, SD_POWEROFF_NOTIFY_TIMEOUT_MS, err = __mmc_poll_for_busy(card->host, 0, SD_POWEROFF_NOTIFY_TIMEOUT_MS,
&sd_busy_poweroff_notify_cb, &cb_data); &sd_busy_poweroff_notify_cb, &cb_data);
out: out:
......
...@@ -173,6 +173,8 @@ struct meson_host { ...@@ -173,6 +173,8 @@ struct meson_host {
int irq; int irq;
bool vqmmc_enabled; bool vqmmc_enabled;
bool needs_pre_post_req;
}; };
#define CMD_CFG_LENGTH_MASK GENMASK(8, 0) #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
...@@ -663,6 +665,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc, ...@@ -663,6 +665,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
struct meson_host *host = mmc_priv(mmc); struct meson_host *host = mmc_priv(mmc);
host->cmd = NULL; host->cmd = NULL;
if (host->needs_pre_post_req)
meson_mmc_post_req(mmc, mrq, 0);
mmc_request_done(host->mmc, mrq); mmc_request_done(host->mmc, mrq);
} }
...@@ -880,7 +884,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data ...@@ -880,7 +884,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{ {
struct meson_host *host = mmc_priv(mmc); struct meson_host *host = mmc_priv(mmc);
bool needs_pre_post_req = mrq->data && host->needs_pre_post_req = mrq->data &&
!(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE); !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
/* /*
...@@ -896,22 +900,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -896,22 +900,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
} }
} }
if (needs_pre_post_req) { if (host->needs_pre_post_req) {
meson_mmc_get_transfer_mode(mmc, mrq); meson_mmc_get_transfer_mode(mmc, mrq);
if (!meson_mmc_desc_chain_mode(mrq->data)) if (!meson_mmc_desc_chain_mode(mrq->data))
needs_pre_post_req = false; host->needs_pre_post_req = false;
} }
if (needs_pre_post_req) if (host->needs_pre_post_req)
meson_mmc_pre_req(mmc, mrq); meson_mmc_pre_req(mmc, mrq);
/* Stop execution */ /* Stop execution */
writel(0, host->regs + SD_EMMC_START); writel(0, host->regs + SD_EMMC_START);
meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd); meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
if (needs_pre_post_req)
meson_mmc_post_req(mmc, mrq, 0);
} }
static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd) static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
......
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