diff options
author | Andrei Warkentin <andreiw@motorola.com> | 2011-04-11 17:13:43 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2011-05-24 21:01:13 -0400 |
commit | d3a8d95dcbb726b9cf0bbc166b2473bdd236c88c (patch) | |
tree | 10c6e435f28f6d61562ce54291063913e59dc0b3 /drivers/mmc | |
parent | a3c7778f8153b9e4eceea6738973280b9e63c618 (diff) |
mmc: core: Allow setting CMD timeout for CMD6 (SWITCH).
CMD6 is an R1B-type command, where DAT is used as busy. Depending
on register written using CMD6, timeout value can be different
as per spec.
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/mmc.c | 14 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 16 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 1 |
3 files changed, 23 insertions, 8 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index ae6b8fd38800..396cb23625d2 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -548,7 +548,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
548 | */ | 548 | */ |
549 | if (card->ext_csd.enhanced_area_en) { | 549 | if (card->ext_csd.enhanced_area_en) { |
550 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 550 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
551 | EXT_CSD_ERASE_GROUP_DEF, 1); | 551 | EXT_CSD_ERASE_GROUP_DEF, 1, 0); |
552 | 552 | ||
553 | if (err && err != -EBADMSG) | 553 | if (err && err != -EBADMSG) |
554 | goto free_card; | 554 | goto free_card; |
@@ -579,7 +579,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
579 | if (card->ext_csd.bootconfig & 0x7) { | 579 | if (card->ext_csd.bootconfig & 0x7) { |
580 | card->ext_csd.bootconfig &= ~0x7; | 580 | card->ext_csd.bootconfig &= ~0x7; |
581 | mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, | 581 | mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, |
582 | card->ext_csd.bootconfig); | 582 | card->ext_csd.bootconfig, 0); |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
@@ -588,7 +588,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
588 | if ((card->ext_csd.hs_max_dtr != 0) && | 588 | if ((card->ext_csd.hs_max_dtr != 0) && |
589 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | 589 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { |
590 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 590 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
591 | EXT_CSD_HS_TIMING, 1); | 591 | EXT_CSD_HS_TIMING, 1, 0); |
592 | if (err && err != -EBADMSG) | 592 | if (err && err != -EBADMSG) |
593 | goto free_card; | 593 | goto free_card; |
594 | 594 | ||
@@ -655,7 +655,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
655 | ddr = 0; /* no DDR for 1-bit width */ | 655 | ddr = 0; /* no DDR for 1-bit width */ |
656 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 656 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
657 | EXT_CSD_BUS_WIDTH, | 657 | EXT_CSD_BUS_WIDTH, |
658 | ext_csd_bits[idx][0]); | 658 | ext_csd_bits[idx][0], |
659 | 0); | ||
659 | if (!err) { | 660 | if (!err) { |
660 | mmc_set_bus_width_ddr(card->host, | 661 | mmc_set_bus_width_ddr(card->host, |
661 | bus_width, MMC_SDR_MODE); | 662 | bus_width, MMC_SDR_MODE); |
@@ -674,8 +675,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
674 | 675 | ||
675 | if (!err && ddr) { | 676 | if (!err && ddr) { |
676 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 677 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
677 | EXT_CSD_BUS_WIDTH, | 678 | EXT_CSD_BUS_WIDTH, |
678 | ext_csd_bits[idx][1]); | 679 | ext_csd_bits[idx][1], |
680 | 0); | ||
679 | } | 681 | } |
680 | if (err) { | 682 | if (err) { |
681 | printk(KERN_WARNING "%s: switch to bus width %d ddr %d " | 683 | printk(KERN_WARNING "%s: switch to bus width %d ddr %d " |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index f3b22bf89cc9..a2bae625332a 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -387,7 +387,19 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | |||
387 | return err; | 387 | return err; |
388 | } | 388 | } |
389 | 389 | ||
390 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | 390 | /** |
391 | * mmc_switch - modify EXT_CSD register | ||
392 | * @card: the MMC card associated with the data transfer | ||
393 | * @set: cmd set values | ||
394 | * @index: EXT_CSD register index | ||
395 | * @value: value to program into EXT_CSD register | ||
396 | * @timeout_ms: timeout (ms) for operation performed by register write, | ||
397 | * timeout of zero implies maximum possible timeout | ||
398 | * | ||
399 | * Modifies the EXT_CSD register for selected card. | ||
400 | */ | ||
401 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | ||
402 | unsigned int timeout_ms) | ||
391 | { | 403 | { |
392 | int err; | 404 | int err; |
393 | struct mmc_command cmd; | 405 | struct mmc_command cmd; |
@@ -404,6 +416,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | |||
404 | (value << 8) | | 416 | (value << 8) | |
405 | set; | 417 | set; |
406 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | 418 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
419 | cmd.cmd_timeout_ms = timeout_ms; | ||
407 | 420 | ||
408 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 421 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
409 | if (err) | 422 | if (err) |
@@ -433,6 +446,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | |||
433 | 446 | ||
434 | return 0; | 447 | return 0; |
435 | } | 448 | } |
449 | EXPORT_SYMBOL_GPL(mmc_switch); | ||
436 | 450 | ||
437 | int mmc_send_status(struct mmc_card *card, u32 *status) | 451 | int mmc_send_status(struct mmc_card *card, u32 *status) |
438 | { | 452 | { |
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index e6d44b8a18db..9276946fa5b7 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -20,7 +20,6 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | |||
20 | int mmc_set_relative_addr(struct mmc_card *card); | 20 | int mmc_set_relative_addr(struct mmc_card *card); |
21 | int mmc_send_csd(struct mmc_card *card, u32 *csd); | 21 | int mmc_send_csd(struct mmc_card *card, u32 *csd); |
22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | 22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); |
23 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); | ||
24 | int mmc_send_status(struct mmc_card *card, u32 *status); | 23 | int mmc_send_status(struct mmc_card *card, u32 *status); |
25 | int mmc_send_cid(struct mmc_host *host, u32 *cid); | 24 | int mmc_send_cid(struct mmc_host *host, u32 *cid); |
26 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); | 25 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); |