Skip to content
This repository was archived by the owner on Oct 5, 2018. It is now read-only.

Commit e654df4

Browse files
committed
Merge pull request #156 from chensihao1/android-sdcard.bug.175
Fix Android sdcard.bug #175
2 parents 7b222e7 + 78f464d commit e654df4

File tree

4 files changed

+68
-14
lines changed

4 files changed

+68
-14
lines changed

drivers/mmc/core/core.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,8 +1478,8 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
14781478
goto power_cycle;
14791479
}
14801480

1481-
/* Keep clock gated for at least 5 ms */
1482-
mmc_delay(5);
1481+
/* Keep clock gated for at least 10 ms, though spec only says 5 ms */
1482+
mmc_delay(10);
14831483
host->ios.clock = clock;
14841484
mmc_set_ios(host);
14851485

@@ -1556,6 +1556,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
15561556
host->ios.timing = MMC_TIMING_LEGACY;
15571557
mmc_set_ios(host);
15581558

1559+
15591560
/* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */
15601561
if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0)
15611562
dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
@@ -2337,6 +2338,8 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
23372338
mmc_hostname(host), __func__, host->f_init);
23382339
#endif
23392340
mmc_power_up(host, host->ocr_avail);
2341+
if (host->ops->card_busy && host->ops->card_busy(host))
2342+
return -EIO;
23402343

23412344
/*
23422345
* Some eMMCs (with VCCQ always on) may not be reset after power up, so

drivers/mmc/host/dw_mmc-k3.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,17 @@ static void dw_mci_hi6220_prepare_command(struct dw_mci *host, u32 *cmdr)
127127
*cmdr |= SDMMC_CMD_USE_HOLD_REG;
128128
}
129129

130+
static int dw_mci_hi6220_execute_tunning(struct dw_mci_slot *slot)
131+
{
132+
return 0;
133+
}
134+
130135
static const struct dw_mci_drv_data hi6220_data = {
131136
.switch_voltage = dw_mci_hi6220_switch_voltage,
132137
.set_ios = dw_mci_hi6220_set_ios,
133138
.parse_dt = dw_mci_hi6220_parse_dt,
134139
.prepare_command = dw_mci_hi6220_prepare_command,
140+
.execute_tuning = dw_mci_hi6220_execute_tunning,
135141
};
136142

137143
static const struct of_device_id dw_mci_k3_match[] = {

drivers/mmc/host/dw_mmc.c

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@
4444
/* Common flag combinations */
4545
#define DW_MCI_DATA_ERROR_FLAGS (SDMMC_INT_DRTO | SDMMC_INT_DCRC | \
4646
SDMMC_INT_HTO | SDMMC_INT_SBE | \
47-
SDMMC_INT_EBE)
47+
SDMMC_INT_EBE | SDMMC_INT_HLE)
4848
#define DW_MCI_CMD_ERROR_FLAGS (SDMMC_INT_RTO | SDMMC_INT_RCRC | \
49-
SDMMC_INT_RESP_ERR)
49+
SDMMC_INT_RESP_ERR | SDMMC_INT_HLE)
5050
#define DW_MCI_ERROR_FLAGS (DW_MCI_DATA_ERROR_FLAGS | \
51-
DW_MCI_CMD_ERROR_FLAGS | SDMMC_INT_HLE)
51+
DW_MCI_CMD_ERROR_FLAGS)
5252
#define DW_MCI_SEND_STATUS 1
5353
#define DW_MCI_RECV_STATUS 2
5454
#define DW_MCI_DMA_THRESHOLD 16
@@ -311,7 +311,7 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)
311311
return cmdr;
312312
}
313313

314-
static void dw_mci_wait_while_busy(struct dw_mci *host, u32 cmd_flags)
314+
static int dw_mci_wait_while_busy(struct dw_mci *host, u32 cmd_flags)
315315
{
316316
unsigned long timeout = jiffies + msecs_to_jiffies(500);
317317

@@ -327,13 +327,21 @@ static void dw_mci_wait_while_busy(struct dw_mci *host, u32 cmd_flags)
327327
!(cmd_flags & SDMMC_CMD_VOLT_SWITCH)) {
328328
while (mci_readl(host, STATUS) & SDMMC_STATUS_BUSY) {
329329
if (time_after(jiffies, timeout)) {
330-
/* Command will fail; we'll pass error then */
331-
dev_err(host->dev, "Busy; trying anyway\n");
332-
break;
330+
dev_err(host->dev, "card not ready: "
331+
332+
#if defined CONFIG_MMC_DW_K3
333+
"aborting command\n");
334+
return -EBUSY;
335+
#else
336+
"sending command anyway\n");
337+
return 0;
338+
#endif
333339
}
334340
udelay(10);
335341
}
336342
}
343+
344+
return 0;
337345
}
338346

339347
static void dw_mci_start_command(struct dw_mci *host,
@@ -799,10 +807,19 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
799807
struct dw_mci *host = slot->host;
800808
unsigned long timeout = jiffies + msecs_to_jiffies(500);
801809
unsigned int cmd_status = 0;
810+
int rc;
802811

803812
mci_writel(host, CMDARG, arg);
804813
wmb();
805-
dw_mci_wait_while_busy(host, cmd);
814+
815+
rc = dw_mci_wait_while_busy(host, cmd);
816+
if (rc) {
817+
dev_err(&slot->mmc->class_dev,
818+
"Timeout preparing command (cmd %#x arg %#x status %#x)\n",
819+
cmd, arg, cmd_status);
820+
return;
821+
}
822+
806823
mci_writel(host, CMD, SDMMC_CMD_START | cmd);
807824

808825
while (time_before(jiffies, timeout)) {
@@ -920,6 +937,17 @@ static void __dw_mci_start_request(struct dw_mci *host,
920937

921938
dw_mci_start_command(host, cmd, cmdflags);
922939

940+
if (cmd->opcode == SD_SWITCH_VOLTAGE) {
941+
/*
942+
* Databook says to fail after 2ms w/ no response, but evidence
943+
* shows that sometimes the cmd11 interrupt takes over 130ms.
944+
* We'll set to 500ms, plus an extra jiffy just in case jiffies
945+
* is just about to roll over.
946+
*/
947+
mod_timer(&host->cmd11_timer,
948+
jiffies + msecs_to_jiffies(500) + 1);
949+
}
950+
923951
if (mrq->stop)
924952
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
925953
else
@@ -1013,6 +1041,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
10131041

10141042
/* DDR mode set */
10151043
if (ios->timing == MMC_TIMING_MMC_DDR52 ||
1044+
ios->timing == MMC_TIMING_UHS_DDR50 ||
10161045
ios->timing == MMC_TIMING_MMC_HS400)
10171046
regs |= ((0x1 << slot->id) << 16);
10181047
else
@@ -1069,7 +1098,6 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
10691098
dw_mci_ctrl_reset(slot->host,
10701099
SDMMC_CTRL_ALL_RESET_FLAGS);
10711100
}
1072-
10731101
/* Adjust clock / bus width after power is up */
10741102
dw_mci_setup_bus(slot, false);
10751103

@@ -1272,8 +1300,6 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
12721300

12731301
if (drv_data && drv_data->execute_tuning)
12741302
err = drv_data->execute_tuning(slot);
1275-
else
1276-
err = 0;
12771303

12781304
return err;
12791305
}
@@ -2071,6 +2097,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
20712097
/* Check volt switch first, since it can look like an error */
20722098
if ((host->state == STATE_SENDING_CMD11) &&
20732099
(pending & SDMMC_INT_VOLT_SWITCH)) {
2100+
del_timer(&host->cmd11_timer);
2101+
20742102
mci_writel(host, RINTSTS, SDMMC_INT_VOLT_SWITCH);
20752103
pending &= ~SDMMC_INT_VOLT_SWITCH;
20762104
dw_mci_cmd_interrupt(host, pending);
@@ -2457,6 +2485,18 @@ static bool dw_mci_reset(struct dw_mci *host)
24572485
return ret;
24582486
}
24592487

2488+
static void dw_mci_cmd11_timer(unsigned long arg)
2489+
{
2490+
struct dw_mci *host = (struct dw_mci *)arg;
2491+
2492+
if (host->state != STATE_SENDING_CMD11)
2493+
dev_info(host->dev, "Unexpected CMD11 timeout\n");
2494+
2495+
host->cmd_status = SDMMC_INT_RTO;
2496+
set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
2497+
tasklet_schedule(&host->tasklet);
2498+
}
2499+
24602500
#ifdef CONFIG_OF
24612501
static struct dw_mci_of_quirks {
24622502
char *quirk;
@@ -2568,7 +2608,7 @@ int dw_mci_probe(struct dw_mci *host)
25682608
}
25692609
}
25702610

2571-
if (host->pdata->num_slots > 1) {
2611+
if (host->pdata->num_slots < 1) {
25722612
dev_err(host->dev,
25732613
"Platform data must supply num_slots.\n");
25742614
return -ENODEV;
@@ -2631,6 +2671,9 @@ int dw_mci_probe(struct dw_mci *host)
26312671
}
26322672
}
26332673

2674+
setup_timer(&host->cmd11_timer,
2675+
dw_mci_cmd11_timer, (unsigned long)host);
2676+
26342677
host->quirks = host->pdata->quirks;
26352678

26362679
spin_lock_init(&host->lock);

include/linux/mmc/dw_mmc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ struct dw_mci {
200200
int irq;
201201

202202
int sdio_id0;
203+
204+
struct timer_list cmd11_timer;
203205
};
204206

205207
/* DMA ops for Internal/External DMAC interface */

0 commit comments

Comments
 (0)