Skip to content

Commit e861e11

Browse files
committed
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
2 parents 52a7dc2 + b704441 commit e861e11

File tree

4 files changed

+40
-16
lines changed

4 files changed

+40
-16
lines changed

drivers/mmc/core/block.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ static int ioctl_do_sanitize(struct mmc_card *card)
472472
static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
473473
struct mmc_blk_ioc_data *idata)
474474
{
475-
struct mmc_command cmd = {};
475+
struct mmc_command cmd = {}, sbc = {};
476476
struct mmc_data data = {};
477477
struct mmc_request mrq = {};
478478
struct scatterlist sg;
@@ -550,10 +550,15 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
550550
}
551551

552552
if (idata->rpmb) {
553-
err = mmc_set_blockcount(card, data.blocks,
554-
idata->ic.write_flag & (1 << 31));
555-
if (err)
556-
return err;
553+
sbc.opcode = MMC_SET_BLOCK_COUNT;
554+
/*
555+
* We don't do any blockcount validation because the max size
556+
* may be increased by a future standard. We just copy the
557+
* 'Reliable Write' bit here.
558+
*/
559+
sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
560+
sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
561+
mrq.sbc = &sbc;
557562
}
558563

559564
if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&

drivers/mmc/host/omap.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct mmc_omap_slot {
104104
unsigned int vdd;
105105
u16 saved_con;
106106
u16 bus_mode;
107+
u16 power_mode;
107108
unsigned int fclk_freq;
108109

109110
struct tasklet_struct cover_tasklet;
@@ -1157,7 +1158,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11571158
struct mmc_omap_slot *slot = mmc_priv(mmc);
11581159
struct mmc_omap_host *host = slot->host;
11591160
int i, dsor;
1160-
int clk_enabled;
1161+
int clk_enabled, init_stream;
11611162

11621163
mmc_omap_select_slot(slot, 0);
11631164

@@ -1167,20 +1168,25 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11671168
slot->vdd = ios->vdd;
11681169

11691170
clk_enabled = 0;
1171+
init_stream = 0;
11701172
switch (ios->power_mode) {
11711173
case MMC_POWER_OFF:
11721174
mmc_omap_set_power(slot, 0, ios->vdd);
11731175
break;
11741176
case MMC_POWER_UP:
11751177
/* Cannot touch dsor yet, just power up MMC */
11761178
mmc_omap_set_power(slot, 1, ios->vdd);
1179+
slot->power_mode = ios->power_mode;
11771180
goto exit;
11781181
case MMC_POWER_ON:
11791182
mmc_omap_fclk_enable(host, 1);
11801183
clk_enabled = 1;
11811184
dsor |= 1 << 11;
1185+
if (slot->power_mode != MMC_POWER_ON)
1186+
init_stream = 1;
11821187
break;
11831188
}
1189+
slot->power_mode = ios->power_mode;
11841190

11851191
if (slot->bus_mode != ios->bus_mode) {
11861192
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)
11961202
for (i = 0; i < 2; i++)
11971203
OMAP_MMC_WRITE(host, CON, dsor);
11981204
slot->saved_con = dsor;
1199-
if (ios->power_mode == MMC_POWER_ON) {
1205+
if (init_stream) {
12001206
/* worst case at 400kHz, 80 cycles makes 200 microsecs */
12011207
int usecs = 250;
12021208

@@ -1234,6 +1240,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
12341240
slot->host = host;
12351241
slot->mmc = mmc;
12361242
slot->id = id;
1243+
slot->power_mode = MMC_POWER_UNDEFINED;
12371244
slot->pdata = &host->pdata->slots[id];
12381245

12391246
host->slots[id] = slot;

drivers/mmc/host/sdhci-omap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,9 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
288288
struct device *dev = omap_host->dev;
289289
struct mmc_ios *ios = &mmc->ios;
290290
u32 start_window = 0, max_window = 0;
291+
bool dcrc_was_enabled = false;
291292
u8 cur_match, prev_match = 0;
292293
u32 length = 0, max_len = 0;
293-
u32 ier = host->ier;
294294
u32 phase_delay = 0;
295295
int ret = 0;
296296
u32 reg;
@@ -317,9 +317,10 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
317317
* during the tuning procedure. So disable it during the
318318
* tuning procedure.
319319
*/
320-
ier &= ~SDHCI_INT_DATA_CRC;
321-
sdhci_writel(host, ier, SDHCI_INT_ENABLE);
322-
sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
320+
if (host->ier & SDHCI_INT_DATA_CRC) {
321+
host->ier &= ~SDHCI_INT_DATA_CRC;
322+
dcrc_was_enabled = true;
323+
}
323324

324325
while (phase_delay <= MAX_PHASE_DELAY) {
325326
sdhci_omap_set_dll(omap_host, phase_delay);
@@ -366,6 +367,9 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
366367

367368
ret:
368369
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
370+
/* Reenable forbidden interrupt */
371+
if (dcrc_was_enabled)
372+
host->ier |= SDHCI_INT_DATA_CRC;
369373
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
370374
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
371375
return ret;

drivers/mmc/host/sdhci.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,12 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
216216
timeout = ktime_add_ms(ktime_get(), 100);
217217

218218
/* hw clears the bit when it's done */
219-
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
220-
if (ktime_after(ktime_get(), timeout)) {
219+
while (1) {
220+
bool timedout = ktime_after(ktime_get(), timeout);
221+
222+
if (!(sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask))
223+
break;
224+
if (timedout) {
221225
pr_err("%s: Reset 0x%x never completed.\n",
222226
mmc_hostname(host->mmc), (int)mask);
223227
sdhci_dumpregs(host);
@@ -1608,9 +1612,13 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
16081612

16091613
/* Wait max 20 ms */
16101614
timeout = ktime_add_ms(ktime_get(), 20);
1611-
while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
1612-
& SDHCI_CLOCK_INT_STABLE)) {
1613-
if (ktime_after(ktime_get(), timeout)) {
1615+
while (1) {
1616+
bool timedout = ktime_after(ktime_get(), timeout);
1617+
1618+
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1619+
if (clk & SDHCI_CLOCK_INT_STABLE)
1620+
break;
1621+
if (timedout) {
16141622
pr_err("%s: Internal clock never stabilised.\n",
16151623
mmc_hostname(host->mmc));
16161624
sdhci_dumpregs(host);

0 commit comments

Comments
 (0)