aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c127
1 files changed, 76 insertions, 51 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6d02012a1d0b..f631f5a9bf79 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -13,6 +13,7 @@
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/stat.h> 15#include <linux/stat.h>
16#include <linux/pm_runtime.h>
16 17
17#include <linux/mmc/host.h> 18#include <linux/mmc/host.h>
18#include <linux/mmc/card.h> 19#include <linux/mmc/card.h>
@@ -934,6 +935,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
934 goto err; 935 goto err;
935 } 936 }
936 937
938 card->ocr = ocr;
937 card->type = MMC_TYPE_MMC; 939 card->type = MMC_TYPE_MMC;
938 card->rca = 1; 940 card->rca = 1;
939 memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 941 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
@@ -1404,9 +1406,9 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
1404 if (notify_type == EXT_CSD_POWER_OFF_LONG) 1406 if (notify_type == EXT_CSD_POWER_OFF_LONG)
1405 timeout = card->ext_csd.power_off_longtime; 1407 timeout = card->ext_csd.power_off_longtime;
1406 1408
1407 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1409 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1408 EXT_CSD_POWER_OFF_NOTIFICATION, 1410 EXT_CSD_POWER_OFF_NOTIFICATION,
1409 notify_type, timeout); 1411 notify_type, timeout, true, false);
1410 if (err) 1412 if (err)
1411 pr_err("%s: Power Off Notification timed out, %u\n", 1413 pr_err("%s: Power Off Notification timed out, %u\n",
1412 mmc_hostname(card->host), timeout); 1414 mmc_hostname(card->host), timeout);
@@ -1477,6 +1479,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
1477 1479
1478 mmc_claim_host(host); 1480 mmc_claim_host(host);
1479 1481
1482 if (mmc_card_suspended(host->card))
1483 goto out;
1484
1480 if (mmc_card_doing_bkops(host->card)) { 1485 if (mmc_card_doing_bkops(host->card)) {
1481 err = mmc_stop_bkops(host->card); 1486 err = mmc_stop_bkops(host->card);
1482 if (err) 1487 if (err)
@@ -1496,51 +1501,93 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
1496 err = mmc_deselect_cards(host); 1501 err = mmc_deselect_cards(host);
1497 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); 1502 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
1498 1503
1499 if (!err) 1504 if (!err) {
1500 mmc_power_off(host); 1505 mmc_power_off(host);
1506 mmc_card_set_suspended(host->card);
1507 }
1501out: 1508out:
1502 mmc_release_host(host); 1509 mmc_release_host(host);
1503 return err; 1510 return err;
1504} 1511}
1505 1512
1506/* 1513/*
1507 * Suspend callback from host. 1514 * Suspend callback
1508 */ 1515 */
1509static int mmc_suspend(struct mmc_host *host) 1516static int mmc_suspend(struct mmc_host *host)
1510{ 1517{
1511 return _mmc_suspend(host, true); 1518 int err;
1512}
1513 1519
1514/* 1520 err = _mmc_suspend(host, true);
1515 * Shutdown callback 1521 if (!err) {
1516 */ 1522 pm_runtime_disable(&host->card->dev);
1517static int mmc_shutdown(struct mmc_host *host) 1523 pm_runtime_set_suspended(&host->card->dev);
1518{ 1524 }
1519 return _mmc_suspend(host, false); 1525
1526 return err;
1520} 1527}
1521 1528
1522/* 1529/*
1523 * Resume callback from host.
1524 *
1525 * This function tries to determine if the same card is still present 1530 * This function tries to determine if the same card is still present
1526 * and, if so, restore all state to it. 1531 * and, if so, restore all state to it.
1527 */ 1532 */
1528static int mmc_resume(struct mmc_host *host) 1533static int _mmc_resume(struct mmc_host *host)
1529{ 1534{
1530 int err; 1535 int err = 0;
1531 1536
1532 BUG_ON(!host); 1537 BUG_ON(!host);
1533 BUG_ON(!host->card); 1538 BUG_ON(!host->card);
1534 1539
1535 mmc_claim_host(host); 1540 mmc_claim_host(host);
1536 mmc_power_up(host); 1541
1537 mmc_select_voltage(host, host->ocr); 1542 if (!mmc_card_suspended(host->card))
1538 err = mmc_init_card(host, host->ocr, host->card); 1543 goto out;
1544
1545 mmc_power_up(host, host->card->ocr);
1546 err = mmc_init_card(host, host->card->ocr, host->card);
1547 mmc_card_clr_suspended(host->card);
1548
1549out:
1539 mmc_release_host(host); 1550 mmc_release_host(host);
1551 return err;
1552}
1553
1554/*
1555 * Shutdown callback
1556 */
1557static int mmc_shutdown(struct mmc_host *host)
1558{
1559 int err = 0;
1560
1561 /*
1562 * In a specific case for poweroff notify, we need to resume the card
1563 * before we can shutdown it properly.
1564 */
1565 if (mmc_can_poweroff_notify(host->card) &&
1566 !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE))
1567 err = _mmc_resume(host);
1568
1569 if (!err)
1570 err = _mmc_suspend(host, false);
1540 1571
1541 return err; 1572 return err;
1542} 1573}
1543 1574
1575/*
1576 * Callback for resume.
1577 */
1578static int mmc_resume(struct mmc_host *host)
1579{
1580 int err = 0;
1581
1582 if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
1583 err = _mmc_resume(host);
1584 pm_runtime_set_active(&host->card->dev);
1585 pm_runtime_mark_last_busy(&host->card->dev);
1586 }
1587 pm_runtime_enable(&host->card->dev);
1588
1589 return err;
1590}
1544 1591
1545/* 1592/*
1546 * Callback for runtime_suspend. 1593 * Callback for runtime_suspend.
@@ -1552,18 +1599,11 @@ static int mmc_runtime_suspend(struct mmc_host *host)
1552 if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) 1599 if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
1553 return 0; 1600 return 0;
1554 1601
1555 mmc_claim_host(host); 1602 err = _mmc_suspend(host, true);
1556 1603 if (err)
1557 err = mmc_suspend(host);
1558 if (err) {
1559 pr_err("%s: error %d doing aggessive suspend\n", 1604 pr_err("%s: error %d doing aggessive suspend\n",
1560 mmc_hostname(host), err); 1605 mmc_hostname(host), err);
1561 goto out;
1562 }
1563 mmc_power_off(host);
1564 1606
1565out:
1566 mmc_release_host(host);
1567 return err; 1607 return err;
1568} 1608}
1569 1609
@@ -1574,18 +1614,14 @@ static int mmc_runtime_resume(struct mmc_host *host)
1574{ 1614{
1575 int err; 1615 int err;
1576 1616
1577 if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) 1617 if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME)))
1578 return 0; 1618 return 0;
1579 1619
1580 mmc_claim_host(host); 1620 err = _mmc_resume(host);
1581
1582 mmc_power_up(host);
1583 err = mmc_resume(host);
1584 if (err) 1621 if (err)
1585 pr_err("%s: error %d doing aggessive resume\n", 1622 pr_err("%s: error %d doing aggessive resume\n",
1586 mmc_hostname(host), err); 1623 mmc_hostname(host), err);
1587 1624
1588 mmc_release_host(host);
1589 return 0; 1625 return 0;
1590} 1626}
1591 1627
@@ -1595,7 +1631,7 @@ static int mmc_power_restore(struct mmc_host *host)
1595 1631
1596 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); 1632 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
1597 mmc_claim_host(host); 1633 mmc_claim_host(host);
1598 ret = mmc_init_card(host, host->ocr, host->card); 1634 ret = mmc_init_card(host, host->card->ocr, host->card);
1599 mmc_release_host(host); 1635 mmc_release_host(host);
1600 1636
1601 return ret; 1637 return ret;
@@ -1640,7 +1676,7 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
1640int mmc_attach_mmc(struct mmc_host *host) 1676int mmc_attach_mmc(struct mmc_host *host)
1641{ 1677{
1642 int err; 1678 int err;
1643 u32 ocr; 1679 u32 ocr, rocr;
1644 1680
1645 BUG_ON(!host); 1681 BUG_ON(!host);
1646 WARN_ON(!host->claimed); 1682 WARN_ON(!host->claimed);
@@ -1666,23 +1702,12 @@ int mmc_attach_mmc(struct mmc_host *host)
1666 goto err; 1702 goto err;
1667 } 1703 }
1668 1704
1669 /* 1705 rocr = mmc_select_voltage(host, ocr);
1670 * Sanity check the voltages that the card claims to
1671 * support.
1672 */
1673 if (ocr & 0x7F) {
1674 pr_warning("%s: card claims to support voltages "
1675 "below the defined range. These will be ignored.\n",
1676 mmc_hostname(host));
1677 ocr &= ~0x7F;
1678 }
1679
1680 host->ocr = mmc_select_voltage(host, ocr);
1681 1706
1682 /* 1707 /*
1683 * Can we support the voltage of the card? 1708 * Can we support the voltage of the card?
1684 */ 1709 */
1685 if (!host->ocr) { 1710 if (!rocr) {
1686 err = -EINVAL; 1711 err = -EINVAL;
1687 goto err; 1712 goto err;
1688 } 1713 }
@@ -1690,7 +1715,7 @@ int mmc_attach_mmc(struct mmc_host *host)
1690 /* 1715 /*
1691 * Detect and init the card. 1716 * Detect and init the card.
1692 */ 1717 */
1693 err = mmc_init_card(host, host->ocr, NULL); 1718 err = mmc_init_card(host, rocr, NULL);
1694 if (err) 1719 if (err)
1695 goto err; 1720 goto err;
1696 1721