aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index bffcaf8df352..bad39442f8fe 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -42,6 +42,14 @@ extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
42static struct workqueue_struct *workqueue; 42static struct workqueue_struct *workqueue;
43 43
44/* 44/*
45 * Enabling software CRCs on the data blocks can be a significant (30%)
46 * performance cost, and for other reasons may not always be desired.
47 * So we allow it it to be disabled.
48 */
49int use_spi_crc = 1;
50module_param(use_spi_crc, bool, 0);
51
52/*
45 * Internal function. Schedule delayed work in the MMC work queue. 53 * Internal function. Schedule delayed work in the MMC work queue.
46 */ 54 */
47static int mmc_schedule_delayed_work(struct delayed_work *work, 55static int mmc_schedule_delayed_work(struct delayed_work *work,
@@ -71,6 +79,11 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
71 struct mmc_command *cmd = mrq->cmd; 79 struct mmc_command *cmd = mrq->cmd;
72 int err = cmd->error; 80 int err = cmd->error;
73 81
82 if (err && cmd->retries && mmc_host_is_spi(host)) {
83 if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
84 cmd->retries = 0;
85 }
86
74 if (err && cmd->retries) { 87 if (err && cmd->retries) {
75 pr_debug("%s: req failed (CMD%u): %d, retrying...\n", 88 pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
76 mmc_hostname(host), cmd->opcode, err); 89 mmc_hostname(host), cmd->opcode, err);
@@ -453,8 +466,13 @@ static void mmc_power_up(struct mmc_host *host)
453 int bit = fls(host->ocr_avail) - 1; 466 int bit = fls(host->ocr_avail) - 1;
454 467
455 host->ios.vdd = bit; 468 host->ios.vdd = bit;
456 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 469 if (mmc_host_is_spi(host)) {
457 host->ios.chip_select = MMC_CS_DONTCARE; 470 host->ios.chip_select = MMC_CS_HIGH;
471 host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
472 } else {
473 host->ios.chip_select = MMC_CS_DONTCARE;
474 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
475 }
458 host->ios.power_mode = MMC_POWER_UP; 476 host->ios.power_mode = MMC_POWER_UP;
459 host->ios.bus_width = MMC_BUS_WIDTH_1; 477 host->ios.bus_width = MMC_BUS_WIDTH_1;
460 host->ios.timing = MMC_TIMING_LEGACY; 478 host->ios.timing = MMC_TIMING_LEGACY;
@@ -481,8 +499,10 @@ static void mmc_power_off(struct mmc_host *host)
481{ 499{
482 host->ios.clock = 0; 500 host->ios.clock = 0;
483 host->ios.vdd = 0; 501 host->ios.vdd = 0;
484 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 502 if (!mmc_host_is_spi(host)) {
485 host->ios.chip_select = MMC_CS_DONTCARE; 503 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
504 host->ios.chip_select = MMC_CS_DONTCARE;
505 }
486 host->ios.power_mode = MMC_POWER_OFF; 506 host->ios.power_mode = MMC_POWER_OFF;
487 host->ios.bus_width = MMC_BUS_WIDTH_1; 507 host->ios.bus_width = MMC_BUS_WIDTH_1;
488 host->ios.timing = MMC_TIMING_LEGACY; 508 host->ios.timing = MMC_TIMING_LEGACY;