aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorAndy Ross <andy.ross@windriver.com>2011-01-03 13:36:56 -0500
committerChris Ball <cjb@laptop.org>2011-01-08 23:52:25 -0500
commit807e8e40673d9628fa7dcdd14423424b4ee5f43b (patch)
treeca95bdb69d07f0169bbfc5388e15745b9811513e /drivers/mmc/core
parent08c82dfad2458f8f9b83126224a85e7ea9e2b046 (diff)
mmc: Fix sd/sdio/mmc initialization frequency retries
Rewrite and clean up mmc_rescan() to properly retry frequencies lower than 400kHz. Failures can happen both in sd_send_* calls and mmc_attach_*. Break out "mmc_rescan_try_freq" from the frequency selection loop. Symmetrize claim/release logic in mmc_attach_* API, and move the sd_send_* calls there to make mmc_rescan easier to read. Signed-off-by: Andy Ross <andy.ross@windriver.com> Reviewed-and-Tested-by: Hein Tibosch <hein_tibosch@yahoo.es> Reviewed-by: Chris Ball <cjb@laptop.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/core.c119
-rw-r--r--drivers/mmc/core/core.h6
-rw-r--r--drivers/mmc/core/mmc.c13
-rw-r--r--drivers/mmc/core/sd.c11
-rw-r--r--drivers/mmc/core/sdio.c18
5 files changed, 68 insertions, 99 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 97e0624eb9b6..198f70bad908 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1485,25 +1485,41 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
1485} 1485}
1486EXPORT_SYMBOL(mmc_set_blocklen); 1486EXPORT_SYMBOL(mmc_set_blocklen);
1487 1487
1488static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
1489{
1490 host->f_init = freq;
1491
1492#ifdef CONFIG_MMC_DEBUG
1493 pr_info("%s: %s: trying to init card at %u Hz\n",
1494 mmc_hostname(host), __func__, host->f_init);
1495#endif
1496 mmc_power_up(host);
1497 sdio_reset(host);
1498 mmc_go_idle(host);
1499
1500 mmc_send_if_cond(host, host->ocr_avail);
1501
1502 /* Order's important: probe SDIO, then SD, then MMC */
1503 if (!mmc_attach_sdio(host))
1504 return 0;
1505 if (!mmc_attach_sd(host))
1506 return 0;
1507 if (!mmc_attach_mmc(host))
1508 return 0;
1509
1510 mmc_power_off(host);
1511 return -EIO;
1512}
1513
1488void mmc_rescan(struct work_struct *work) 1514void mmc_rescan(struct work_struct *work)
1489{ 1515{
1516 static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
1490 struct mmc_host *host = 1517 struct mmc_host *host =
1491 container_of(work, struct mmc_host, detect.work); 1518 container_of(work, struct mmc_host, detect.work);
1492 u32 ocr;
1493 int err;
1494 unsigned long flags;
1495 int i; 1519 int i;
1496 const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
1497
1498 spin_lock_irqsave(&host->lock, flags);
1499 1520
1500 if (host->rescan_disable) { 1521 if (host->rescan_disable)
1501 spin_unlock_irqrestore(&host->lock, flags);
1502 return; 1522 return;
1503 }
1504
1505 spin_unlock_irqrestore(&host->lock, flags);
1506
1507 1523
1508 mmc_bus_get(host); 1524 mmc_bus_get(host);
1509 1525
@@ -1526,8 +1542,6 @@ void mmc_rescan(struct work_struct *work)
1526 goto out; 1542 goto out;
1527 } 1543 }
1528 1544
1529 /* detect a newly inserted card */
1530
1531 /* 1545 /*
1532 * Only we can add a new handler, so it's safe to 1546 * Only we can add a new handler, so it's safe to
1533 * release the lock here. 1547 * release the lock here.
@@ -1537,77 +1551,16 @@ void mmc_rescan(struct work_struct *work)
1537 if (host->ops->get_cd && host->ops->get_cd(host) == 0) 1551 if (host->ops->get_cd && host->ops->get_cd(host) == 0)
1538 goto out; 1552 goto out;
1539 1553
1554 mmc_claim_host(host);
1540 for (i = 0; i < ARRAY_SIZE(freqs); i++) { 1555 for (i = 0; i < ARRAY_SIZE(freqs); i++) {
1541 mmc_claim_host(host); 1556 if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
1542 1557 break;
1543 if (freqs[i] >= host->f_min) 1558 if (freqs[i] < host->f_min)
1544 host->f_init = freqs[i]; 1559 break;
1545 else if (!i || freqs[i-1] > host->f_min)
1546 host->f_init = host->f_min;
1547 else {
1548 mmc_release_host(host);
1549 goto out;
1550 }
1551#ifdef CONFIG_MMC_DEBUG
1552 pr_info("%s: %s: trying to init card at %u Hz\n",
1553 mmc_hostname(host), __func__, host->f_init);
1554#endif
1555 mmc_power_up(host);
1556 sdio_reset(host);
1557 mmc_go_idle(host);
1558
1559 mmc_send_if_cond(host, host->ocr_avail);
1560
1561 /*
1562 * First we search for SDIO...
1563 */
1564 err = mmc_send_io_op_cond(host, 0, &ocr);
1565 if (!err) {
1566 if (mmc_attach_sdio(host, ocr)) {
1567 mmc_claim_host(host);
1568 /*
1569 * Try SDMEM (but not MMC) even if SDIO
1570 * is broken.
1571 */
1572 mmc_power_up(host);
1573 sdio_reset(host);
1574 mmc_go_idle(host);
1575 mmc_send_if_cond(host, host->ocr_avail);
1576
1577 if (mmc_send_app_op_cond(host, 0, &ocr))
1578 goto out_fail;
1579
1580 if (mmc_attach_sd(host, ocr))
1581 mmc_power_off(host);
1582 }
1583 goto out;
1584 }
1585
1586 /*
1587 * ...then normal SD...
1588 */
1589 err = mmc_send_app_op_cond(host, 0, &ocr);
1590 if (!err) {
1591 if (mmc_attach_sd(host, ocr))
1592 mmc_power_off(host);
1593 goto out;
1594 }
1595
1596 /*
1597 * ...and finally MMC.
1598 */
1599 err = mmc_send_op_cond(host, 0, &ocr);
1600 if (!err) {
1601 if (mmc_attach_mmc(host, ocr))
1602 mmc_power_off(host);
1603 goto out;
1604 }
1605
1606out_fail:
1607 mmc_release_host(host);
1608 mmc_power_off(host);
1609 } 1560 }
1610out: 1561 mmc_release_host(host);
1562
1563 out:
1611 if (host->caps & MMC_CAP_NEEDS_POLL) 1564 if (host->caps & MMC_CAP_NEEDS_POLL)
1612 mmc_schedule_delayed_work(&host->detect, HZ); 1565 mmc_schedule_delayed_work(&host->detect, HZ);
1613} 1566}
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 026c975b99a9..ca1fdde29df6 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -57,9 +57,9 @@ void mmc_rescan(struct work_struct *work);
57void mmc_start_host(struct mmc_host *host); 57void mmc_start_host(struct mmc_host *host);
58void mmc_stop_host(struct mmc_host *host); 58void mmc_stop_host(struct mmc_host *host);
59 59
60int mmc_attach_mmc(struct mmc_host *host, u32 ocr); 60int mmc_attach_mmc(struct mmc_host *host);
61int mmc_attach_sd(struct mmc_host *host, u32 ocr); 61int mmc_attach_sd(struct mmc_host *host);
62int mmc_attach_sdio(struct mmc_host *host, u32 ocr); 62int mmc_attach_sdio(struct mmc_host *host);
63 63
64/* Module parameters */ 64/* Module parameters */
65extern int use_spi_crc; 65extern int use_spi_crc;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c86dd7384d7d..16006ef153fe 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -755,13 +755,18 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
755/* 755/*
756 * Starting point for MMC card init. 756 * Starting point for MMC card init.
757 */ 757 */
758int mmc_attach_mmc(struct mmc_host *host, u32 ocr) 758int mmc_attach_mmc(struct mmc_host *host)
759{ 759{
760 int err; 760 int err;
761 u32 ocr;
761 762
762 BUG_ON(!host); 763 BUG_ON(!host);
763 WARN_ON(!host->claimed); 764 WARN_ON(!host->claimed);
764 765
766 err = mmc_send_op_cond(host, 0, &ocr);
767 if (err)
768 return err;
769
765 mmc_attach_bus_ops(host); 770 mmc_attach_bus_ops(host);
766 if (host->ocr_avail_mmc) 771 if (host->ocr_avail_mmc)
767 host->ocr_avail = host->ocr_avail_mmc; 772 host->ocr_avail = host->ocr_avail_mmc;
@@ -804,20 +809,20 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
804 goto err; 809 goto err;
805 810
806 mmc_release_host(host); 811 mmc_release_host(host);
807
808 err = mmc_add_card(host->card); 812 err = mmc_add_card(host->card);
813 mmc_claim_host(host);
809 if (err) 814 if (err)
810 goto remove_card; 815 goto remove_card;
811 816
812 return 0; 817 return 0;
813 818
814remove_card: 819remove_card:
820 mmc_release_host(host);
815 mmc_remove_card(host->card); 821 mmc_remove_card(host->card);
816 host->card = NULL;
817 mmc_claim_host(host); 822 mmc_claim_host(host);
823 host->card = NULL;
818err: 824err:
819 mmc_detach_bus(host); 825 mmc_detach_bus(host);
820 mmc_release_host(host);
821 826
822 printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", 827 printk(KERN_ERR "%s: error %d whilst initialising MMC card\n",
823 mmc_hostname(host), err); 828 mmc_hostname(host), err);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index de062ebd8b26..d18c32bca99b 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -764,13 +764,18 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host)
764/* 764/*
765 * Starting point for SD card init. 765 * Starting point for SD card init.
766 */ 766 */
767int mmc_attach_sd(struct mmc_host *host, u32 ocr) 767int mmc_attach_sd(struct mmc_host *host)
768{ 768{
769 int err; 769 int err;
770 u32 ocr;
770 771
771 BUG_ON(!host); 772 BUG_ON(!host);
772 WARN_ON(!host->claimed); 773 WARN_ON(!host->claimed);
773 774
775 err = mmc_send_app_op_cond(host, 0, &ocr);
776 if (err)
777 return err;
778
774 mmc_sd_attach_bus_ops(host); 779 mmc_sd_attach_bus_ops(host);
775 if (host->ocr_avail_sd) 780 if (host->ocr_avail_sd)
776 host->ocr_avail = host->ocr_avail_sd; 781 host->ocr_avail = host->ocr_avail_sd;
@@ -823,20 +828,20 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
823 goto err; 828 goto err;
824 829
825 mmc_release_host(host); 830 mmc_release_host(host);
826
827 err = mmc_add_card(host->card); 831 err = mmc_add_card(host->card);
832 mmc_claim_host(host);
828 if (err) 833 if (err)
829 goto remove_card; 834 goto remove_card;
830 835
831 return 0; 836 return 0;
832 837
833remove_card: 838remove_card:
839 mmc_release_host(host);
834 mmc_remove_card(host->card); 840 mmc_remove_card(host->card);
835 host->card = NULL; 841 host->card = NULL;
836 mmc_claim_host(host); 842 mmc_claim_host(host);
837err: 843err:
838 mmc_detach_bus(host); 844 mmc_detach_bus(host);
839 mmc_release_host(host);
840 845
841 printk(KERN_ERR "%s: error %d whilst initialising SD card\n", 846 printk(KERN_ERR "%s: error %d whilst initialising SD card\n",
842 mmc_hostname(host), err); 847 mmc_hostname(host), err);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 82f4b9008987..5c4a54d9b6a4 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -702,15 +702,19 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
702/* 702/*
703 * Starting point for SDIO card init. 703 * Starting point for SDIO card init.
704 */ 704 */
705int mmc_attach_sdio(struct mmc_host *host, u32 ocr) 705int mmc_attach_sdio(struct mmc_host *host)
706{ 706{
707 int err; 707 int err, i, funcs;
708 int i, funcs; 708 u32 ocr;
709 struct mmc_card *card; 709 struct mmc_card *card;
710 710
711 BUG_ON(!host); 711 BUG_ON(!host);
712 WARN_ON(!host->claimed); 712 WARN_ON(!host->claimed);
713 713
714 err = mmc_send_io_op_cond(host, 0, &ocr);
715 if (err)
716 return err;
717
714 mmc_attach_bus(host, &mmc_sdio_ops); 718 mmc_attach_bus(host, &mmc_sdio_ops);
715 if (host->ocr_avail_sdio) 719 if (host->ocr_avail_sdio)
716 host->ocr_avail = host->ocr_avail_sdio; 720 host->ocr_avail = host->ocr_avail_sdio;
@@ -783,12 +787,12 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
783 pm_runtime_enable(&card->sdio_func[i]->dev); 787 pm_runtime_enable(&card->sdio_func[i]->dev);
784 } 788 }
785 789
786 mmc_release_host(host);
787
788 /* 790 /*
789 * First add the card to the driver model... 791 * First add the card to the driver model...
790 */ 792 */
793 mmc_release_host(host);
791 err = mmc_add_card(host->card); 794 err = mmc_add_card(host->card);
795 mmc_claim_host(host);
792 if (err) 796 if (err)
793 goto remove_added; 797 goto remove_added;
794 798
@@ -806,15 +810,17 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
806 810
807remove_added: 811remove_added:
808 /* Remove without lock if the device has been added. */ 812 /* Remove without lock if the device has been added. */
813 mmc_release_host(host);
809 mmc_sdio_remove(host); 814 mmc_sdio_remove(host);
810 mmc_claim_host(host); 815 mmc_claim_host(host);
811remove: 816remove:
812 /* And with lock if it hasn't been added. */ 817 /* And with lock if it hasn't been added. */
818 mmc_release_host(host);
813 if (host->card) 819 if (host->card)
814 mmc_sdio_remove(host); 820 mmc_sdio_remove(host);
821 mmc_claim_host(host);
815err: 822err:
816 mmc_detach_bus(host); 823 mmc_detach_bus(host);
817 mmc_release_host(host);
818 824
819 printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", 825 printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n",
820 mmc_hostname(host), err); 826 mmc_hostname(host), err);