aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHein Tibosch <hein_tibosch@yahoo.es>2010-09-05 21:37:19 -0400
committerChris Ball <cjb@laptop.org>2010-10-23 09:11:15 -0400
commit88ae8b866488031b0e2fc05a27440fefec5e6927 (patch)
tree07fba0c9aab5c50230fcac22e74506622fa19c68 /drivers/mmc
parent176d1ed426a2a73a87c62a8aa05f6d002353cd50 (diff)
mmc: Make ID freq configurable
In the latest releases of the mmc driver, the freq during initialization is set to a fixed 400 Khz. This was reportedly too fast for several users. As there doesn't seem to be an ideal frequency which-works-for-all, Pierre suggested to let the driver try several frequencies. This patch implements that idea. It will try mmc-initialization using several frequencies from an array 400, 300, 200 and 100. In case SDIO is broken, it'll still try to detect SDMEM, also at different freqs. Signed-off-by: Hein Tibosch <hein_tibosch@yahoo.es> Cc: Pierre Ossman <pierre@ossman.eu> Reviewed-by: Chris Ball <cjb@laptop.org> Tested-by: Chris Ball <cjb@laptop.org> Cc: Ben Nizette <bn@niasdigital.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Adrian Hunter <adrian.hunter@nokia.com> Cc: Matt Fleming <matt@console-pimps.org> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/core.c102
1 files changed, 57 insertions, 45 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ab4446c428be..222466df66ff 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -908,12 +908,7 @@ static void mmc_power_up(struct mmc_host *host)
908 */ 908 */
909 mmc_delay(10); 909 mmc_delay(10);
910 910
911 if (host->f_min > 400000) { 911 host->ios.clock = host->f_init;
912 pr_warning("%s: Minimum clock frequency too high for "
913 "identification mode\n", mmc_hostname(host));
914 host->ios.clock = host->f_min;
915 } else
916 host->ios.clock = 400000;
917 912
918 host->ios.power_mode = MMC_POWER_ON; 913 host->ios.power_mode = MMC_POWER_ON;
919 mmc_set_ios(host); 914 mmc_set_ios(host);
@@ -1405,6 +1400,8 @@ void mmc_rescan(struct work_struct *work)
1405 u32 ocr; 1400 u32 ocr;
1406 int err; 1401 int err;
1407 unsigned long flags; 1402 unsigned long flags;
1403 int i;
1404 const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
1408 1405
1409 spin_lock_irqsave(&host->lock, flags); 1406 spin_lock_irqsave(&host->lock, flags);
1410 1407
@@ -1444,55 +1441,70 @@ void mmc_rescan(struct work_struct *work)
1444 if (host->ops->get_cd && host->ops->get_cd(host) == 0) 1441 if (host->ops->get_cd && host->ops->get_cd(host) == 0)
1445 goto out; 1442 goto out;
1446 1443
1447 mmc_claim_host(host); 1444 for (i = 0; i < ARRAY_SIZE(freqs); i++) {
1445 mmc_claim_host(host);
1448 1446
1449 mmc_power_up(host); 1447 if (freqs[i] >= host->f_min)
1450 sdio_reset(host); 1448 host->f_init = freqs[i];
1451 mmc_go_idle(host); 1449 else if (!i || freqs[i-1] > host->f_min)
1450 host->f_init = host->f_min;
1451 else {
1452 mmc_release_host(host);
1453 goto out;
1454 }
1455 pr_info("%s: %s: trying to init card at %u Hz\n",
1456 mmc_hostname(host), __func__, host->f_init);
1452 1457
1453 mmc_send_if_cond(host, host->ocr_avail); 1458 mmc_power_up(host);
1459 sdio_reset(host);
1460 mmc_go_idle(host);
1454 1461
1455 /* 1462 mmc_send_if_cond(host, host->ocr_avail);
1456 * First we search for SDIO...
1457 */
1458 err = mmc_send_io_op_cond(host, 0, &ocr);
1459 if (!err) {
1460 if (mmc_attach_sdio(host, ocr)) {
1461 mmc_claim_host(host);
1462 /* try SDMEM (but not MMC) even if SDIO is broken */
1463 if (mmc_send_app_op_cond(host, 0, &ocr))
1464 goto out_fail;
1465 1463
1464 /*
1465 * First we search for SDIO...
1466 */
1467 err = mmc_send_io_op_cond(host, 0, &ocr);
1468 if (!err) {
1469 if (mmc_attach_sdio(host, ocr)) {
1470 mmc_claim_host(host);
1471 /*
1472 * Try SDMEM (but not MMC) even if SDIO
1473 * is broken.
1474 */
1475 if (mmc_send_app_op_cond(host, 0, &ocr))
1476 goto out_fail;
1477
1478 if (mmc_attach_sd(host, ocr))
1479 mmc_power_off(host);
1480 }
1481 goto out;
1482 }
1483
1484 /*
1485 * ...then normal SD...
1486 */
1487 err = mmc_send_app_op_cond(host, 0, &ocr);
1488 if (!err) {
1466 if (mmc_attach_sd(host, ocr)) 1489 if (mmc_attach_sd(host, ocr))
1467 mmc_power_off(host); 1490 mmc_power_off(host);
1491 goto out;
1468 } 1492 }
1469 goto out;
1470 }
1471 1493
1472 /* 1494 /*
1473 * ...then normal SD... 1495 * ...and finally MMC.
1474 */ 1496 */
1475 err = mmc_send_app_op_cond(host, 0, &ocr); 1497 err = mmc_send_op_cond(host, 0, &ocr);
1476 if (!err) { 1498 if (!err) {
1477 if (mmc_attach_sd(host, ocr)) 1499 if (mmc_attach_mmc(host, ocr))
1478 mmc_power_off(host); 1500 mmc_power_off(host);
1479 goto out; 1501 goto out;
1480 } 1502 }
1481
1482 /*
1483 * ...and finally MMC.
1484 */
1485 err = mmc_send_op_cond(host, 0, &ocr);
1486 if (!err) {
1487 if (mmc_attach_mmc(host, ocr))
1488 mmc_power_off(host);
1489 goto out;
1490 }
1491 1503
1492out_fail: 1504out_fail:
1493 mmc_release_host(host); 1505 mmc_release_host(host);
1494 mmc_power_off(host); 1506 mmc_power_off(host);
1495 1507 }
1496out: 1508out:
1497 if (host->caps & MMC_CAP_NEEDS_POLL) 1509 if (host->caps & MMC_CAP_NEEDS_POLL)
1498 mmc_schedule_delayed_work(&host->detect, HZ); 1510 mmc_schedule_delayed_work(&host->detect, HZ);