MMC core:

- Fixup RPMB requests to use mrq->sbc when sending CMD23
 
 MMC host:
  - omap: Fix broken MMC/SD on OMAP15XX/OMAP5910/OMAP310
  - sdhci-omap: Fix DCRC error handling during tuning
  - sdhci: Fixup the timeout check window for clock and reset
 -----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAlwSOjAXHHVsZi5oYW5z
 c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCkexA//cw/KotpQQpIirpmVvvnB52aR
 eephJ6CsoFC6Mqdmjto9i4hO4bwsDr0S8RQBjF+rpcGzN2lo3Kn6rongKxWd5Y++
 UZkNdY/t8rGe/bumbaQgvMNnQ7RcwknlL36Xn2sN+hcoqY4/8P/3eF4+ysc4i4Gy
 PG6AHXVNotCmQwwCElAmhKoQN2JCMRZyUlMkgl/yXqLljhEQJ0jzWHicFFsRMF4t
 teCV3CGazffYopipiQUeRNKUbCTaF8UFoybgONnyVXFy9gmzzAAbb6behRbh2U/s
 XNqopa2R3wwxXep2TrwUDYMrDFl1ibRnuYi0VYz0VZRyA1vdEz8XKB3QQaQf03d2
 yzjWUWd4YI0RZMrdhaOIyvVkbk9//2JzrCHen1wnhU8AFInpJdcwN0NKcVCUJXfb
 5f2fB1GO9lDogW0n+z57+Hsux9wWWcLcfrY5g454qlySou/jmvfhH0onhQOH4aTs
 oJcU7vDsZQHftQYfol2e8K/5m3KKRKVRCDLzw0RRQbplC04r/5afuL3dA1YEI8/Y
 ZTAgd0rOXvOY+oW4q0a8CbEnknk9MoXUd41/LkbG8eJWliStOsV0PJZzmgDcIgPH
 EB3LyZRccJwKzSMtLLktx/iTm4grVjFABnQxlf80twoJjjnlcoNaBYHfr3Zc9BTf
 7E7AXxdUUwMn5qWhOxQ=
 =wS1m
 -----END PGP SIGNATURE-----

Merge tag 'mmc-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull mmc fixes from Ulf Hansson:
 "MMC core:
   - Fixup RPMB requests to use mrq->sbc when sending CMD23

  MMC host:
   - omap: Fix broken MMC/SD on OMAP15XX/OMAP5910/OMAP310

   - sdhci-omap: Fix DCRC error handling during tuning

   - sdhci: Fixup the timeout check window for clock and reset"

* tag 'mmc-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci: fix the timeout check window for clock and reset
  mmc: sdhci-omap: Fix DCRC error handling during tuning
  MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310
  mmc: core: use mrq->sbc when sending CMD23 for RPMB
This commit is contained in:
Linus Torvalds 2018-12-13 10:59:02 -08:00
commit e861e11c59
4 changed files with 40 additions and 16 deletions

View File

@ -472,7 +472,7 @@ out:
static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
struct mmc_blk_ioc_data *idata)
{
struct mmc_command cmd = {};
struct mmc_command cmd = {}, sbc = {};
struct mmc_data data = {};
struct mmc_request mrq = {};
struct scatterlist sg;
@ -550,10 +550,15 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
}
if (idata->rpmb) {
err = mmc_set_blockcount(card, data.blocks,
idata->ic.write_flag & (1 << 31));
if (err)
return err;
sbc.opcode = MMC_SET_BLOCK_COUNT;
/*
* We don't do any blockcount validation because the max size
* may be increased by a future standard. We just copy the
* 'Reliable Write' bit here.
*/
sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
mrq.sbc = &sbc;
}
if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&

View File

@ -104,6 +104,7 @@ struct mmc_omap_slot {
unsigned int vdd;
u16 saved_con;
u16 bus_mode;
u16 power_mode;
unsigned int fclk_freq;
struct tasklet_struct cover_tasklet;
@ -1157,7 +1158,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
struct mmc_omap_slot *slot = mmc_priv(mmc);
struct mmc_omap_host *host = slot->host;
int i, dsor;
int clk_enabled;
int clk_enabled, init_stream;
mmc_omap_select_slot(slot, 0);
@ -1167,6 +1168,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->vdd = ios->vdd;
clk_enabled = 0;
init_stream = 0;
switch (ios->power_mode) {
case MMC_POWER_OFF:
mmc_omap_set_power(slot, 0, ios->vdd);
@ -1174,13 +1176,17 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_UP:
/* Cannot touch dsor yet, just power up MMC */
mmc_omap_set_power(slot, 1, ios->vdd);
slot->power_mode = ios->power_mode;
goto exit;
case MMC_POWER_ON:
mmc_omap_fclk_enable(host, 1);
clk_enabled = 1;
dsor |= 1 << 11;
if (slot->power_mode != MMC_POWER_ON)
init_stream = 1;
break;
}
slot->power_mode = ios->power_mode;
if (slot->bus_mode != ios->bus_mode) {
if (slot->pdata->set_bus_mode != NULL)
@ -1196,7 +1202,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
for (i = 0; i < 2; i++)
OMAP_MMC_WRITE(host, CON, dsor);
slot->saved_con = dsor;
if (ios->power_mode == MMC_POWER_ON) {
if (init_stream) {
/* worst case at 400kHz, 80 cycles makes 200 microsecs */
int usecs = 250;
@ -1234,6 +1240,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
slot->host = host;
slot->mmc = mmc;
slot->id = id;
slot->power_mode = MMC_POWER_UNDEFINED;
slot->pdata = &host->pdata->slots[id];
host->slots[id] = slot;

View File

@ -288,9 +288,9 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
struct device *dev = omap_host->dev;
struct mmc_ios *ios = &mmc->ios;
u32 start_window = 0, max_window = 0;
bool dcrc_was_enabled = false;
u8 cur_match, prev_match = 0;
u32 length = 0, max_len = 0;
u32 ier = host->ier;
u32 phase_delay = 0;
int ret = 0;
u32 reg;
@ -317,9 +317,10 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
* during the tuning procedure. So disable it during the
* tuning procedure.
*/
ier &= ~SDHCI_INT_DATA_CRC;
sdhci_writel(host, ier, SDHCI_INT_ENABLE);
sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
if (host->ier & SDHCI_INT_DATA_CRC) {
host->ier &= ~SDHCI_INT_DATA_CRC;
dcrc_was_enabled = true;
}
while (phase_delay <= MAX_PHASE_DELAY) {
sdhci_omap_set_dll(omap_host, phase_delay);
@ -366,6 +367,9 @@ tuning_error:
ret:
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
/* Reenable forbidden interrupt */
if (dcrc_was_enabled)
host->ier |= SDHCI_INT_DATA_CRC;
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
return ret;

View File

@ -216,8 +216,12 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout = ktime_add_ms(ktime_get(), 100);
/* hw clears the bit when it's done */
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
if (ktime_after(ktime_get(), timeout)) {
while (1) {
bool timedout = ktime_after(ktime_get(), timeout);
if (!(sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask))
break;
if (timedout) {
pr_err("%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
sdhci_dumpregs(host);
@ -1608,9 +1612,13 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
/* Wait max 20 ms */
timeout = ktime_add_ms(ktime_get(), 20);
while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (ktime_after(ktime_get(), timeout)) {
while (1) {
bool timedout = ktime_after(ktime_get(), timeout);
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
if (clk & SDHCI_CLOCK_INT_STABLE)
break;
if (timedout) {
pr_err("%s: Internal clock never stabilised.\n",
mmc_hostname(host->mmc));
sdhci_dumpregs(host);