aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-12 00:37:42 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-12 00:37:42 -0500
commit83eb95b852902f952ba594447a796ad8146b9462 (patch)
tree33c199aeeae58b69ad8d6d2a33c2d96ba2b98ddf /drivers/mmc/core/mmc.c
parentefb3e34b6176d30c4fe8635fa8e1beb6280cc2cd (diff)
parent9bbe7b984096ac45586da2adf26c14069ecb79b2 (diff)
Merge branch 'sh/sdio' into sh-latest
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c91
1 files changed, 58 insertions, 33 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 77f93c3b8808..16006ef153fe 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -534,39 +534,57 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
534 */ 534 */
535 if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && 535 if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
536 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { 536 (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
537 unsigned ext_csd_bit, bus_width; 537 static unsigned ext_csd_bits[][2] = {
538 538 { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
539 if (host->caps & MMC_CAP_8_BIT_DATA) { 539 { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 },
540 if (ddr) 540 { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 },
541 ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; 541 };
542 else 542 static unsigned bus_widths[] = {
543 ext_csd_bit = EXT_CSD_BUS_WIDTH_8; 543 MMC_BUS_WIDTH_8,
544 bus_width = MMC_BUS_WIDTH_8; 544 MMC_BUS_WIDTH_4,
545 } else { 545 MMC_BUS_WIDTH_1
546 if (ddr) 546 };
547 ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; 547 unsigned idx, bus_width = 0;
548 else 548
549 ext_csd_bit = EXT_CSD_BUS_WIDTH_4; 549 if (host->caps & MMC_CAP_8_BIT_DATA)
550 bus_width = MMC_BUS_WIDTH_4; 550 idx = 0;
551 else
552 idx = 1;
553 for (; idx < ARRAY_SIZE(bus_widths); idx++) {
554 bus_width = bus_widths[idx];
555 if (bus_width == MMC_BUS_WIDTH_1)
556 ddr = 0; /* no DDR for 1-bit width */
557 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
558 EXT_CSD_BUS_WIDTH,
559 ext_csd_bits[idx][0]);
560 if (!err) {
561 mmc_set_bus_width_ddr(card->host,
562 bus_width, MMC_SDR_MODE);
563 /*
564 * If controller can't handle bus width test,
565 * use the highest bus width to maintain
566 * compatibility with previous MMC behavior.
567 */
568 if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
569 break;
570 err = mmc_bus_test(card, bus_width);
571 if (!err)
572 break;
573 }
551 } 574 }
552 575
553 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 576 if (!err && ddr) {
554 EXT_CSD_BUS_WIDTH, ext_csd_bit); 577 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
555 578 EXT_CSD_BUS_WIDTH,
556 if (err && err != -EBADMSG) 579 ext_csd_bits[idx][1]);
557 goto free_card; 580 }
558
559 if (err) { 581 if (err) {
560 printk(KERN_WARNING "%s: switch to bus width %d ddr %d " 582 printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
561 "failed\n", mmc_hostname(card->host), 583 "failed\n", mmc_hostname(card->host),
562 1 << bus_width, ddr); 584 1 << bus_width, ddr);
563 err = 0; 585 goto free_card;
564 } else { 586 } else if (ddr) {
565 if (ddr) 587 mmc_card_set_ddr_mode(card);
566 mmc_card_set_ddr_mode(card);
567 else
568 ddr = MMC_SDR_MODE;
569
570 mmc_set_bus_width_ddr(card->host, bus_width, ddr); 588 mmc_set_bus_width_ddr(card->host, bus_width, ddr);
571 } 589 }
572 } 590 }
@@ -737,14 +755,21 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
737/* 755/*
738 * Starting point for MMC card init. 756 * Starting point for MMC card init.
739 */ 757 */
740int mmc_attach_mmc(struct mmc_host *host, u32 ocr) 758int mmc_attach_mmc(struct mmc_host *host)
741{ 759{
742 int err; 760 int err;
761 u32 ocr;
743 762
744 BUG_ON(!host); 763 BUG_ON(!host);
745 WARN_ON(!host->claimed); 764 WARN_ON(!host->claimed);
746 765
766 err = mmc_send_op_cond(host, 0, &ocr);
767 if (err)
768 return err;
769
747 mmc_attach_bus_ops(host); 770 mmc_attach_bus_ops(host);
771 if (host->ocr_avail_mmc)
772 host->ocr_avail = host->ocr_avail_mmc;
748 773
749 /* 774 /*
750 * We need to get OCR a different way for SPI. 775 * We need to get OCR a different way for SPI.
@@ -784,20 +809,20 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
784 goto err; 809 goto err;
785 810
786 mmc_release_host(host); 811 mmc_release_host(host);
787
788 err = mmc_add_card(host->card); 812 err = mmc_add_card(host->card);
813 mmc_claim_host(host);
789 if (err) 814 if (err)
790 goto remove_card; 815 goto remove_card;
791 816
792 return 0; 817 return 0;
793 818
794remove_card: 819remove_card:
820 mmc_release_host(host);
795 mmc_remove_card(host->card); 821 mmc_remove_card(host->card);
796 host->card = NULL;
797 mmc_claim_host(host); 822 mmc_claim_host(host);
823 host->card = NULL;
798err: 824err:
799 mmc_detach_bus(host); 825 mmc_detach_bus(host);
800 mmc_release_host(host);
801 826
802 printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", 827 printk(KERN_ERR "%s: error %d whilst initialising MMC card\n",
803 mmc_hostname(host), err); 828 mmc_hostname(host), err);