aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2013-04-19 09:12:11 -0400
committerChris Ball <cjb@laptop.org>2013-05-26 14:23:17 -0400
commit07a682160866e302d696f5c76d74024d575fb79d (patch)
treea2c74c48a953607d255ad006e3a58a2ed0969515 /drivers/mmc/core/mmc.c
parentc4d770d72492df510077b277f21ac5f0dad9e5eb (diff)
mmc: core: Restructure and simplify code for mmc sleep|awake
The mmc_card_sleep|awake APIs are not being used since the support is already properly encapsulated within the suspend sequence. Sleep|awake command is also specific for eMMC. We remove the sleep|awake bus_ops, the mmc_card_sleep|awake APIs and move the code into the mmc specific core instead. This also includes the mmc ops function, mmc_sleepawake. All releated functions have then become static and we have got far less code to maintain. Additionally this patch also simplifies the code from mmc_sleepawake, since it is only used to put the card to sleep and not awake. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 506f4ee84e12..dd6810eebd3f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1321,6 +1321,45 @@ err:
1321 return err; 1321 return err;
1322} 1322}
1323 1323
1324static int mmc_can_sleep(struct mmc_card *card)
1325{
1326 return (card && card->ext_csd.rev >= 3);
1327}
1328
1329static int mmc_sleep(struct mmc_host *host)
1330{
1331 struct mmc_command cmd = {0};
1332 struct mmc_card *card = host->card;
1333 int err;
1334
1335 if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
1336 return 0;
1337
1338 err = mmc_deselect_cards(host);
1339 if (err)
1340 return err;
1341
1342 cmd.opcode = MMC_SLEEP_AWAKE;
1343 cmd.arg = card->rca << 16;
1344 cmd.arg |= 1 << 15;
1345
1346 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
1347 err = mmc_wait_for_cmd(host, &cmd, 0);
1348 if (err)
1349 return err;
1350
1351 /*
1352 * If the host does not wait while the card signals busy, then we will
1353 * will have to wait the sleep/awake timeout. Note, we cannot use the
1354 * SEND_STATUS command to poll the status because that command (and most
1355 * others) is invalid while the card sleeps.
1356 */
1357 if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
1358 mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
1359
1360 return err;
1361}
1362
1324static int mmc_can_poweroff_notify(const struct mmc_card *card) 1363static int mmc_can_poweroff_notify(const struct mmc_card *card)
1325{ 1364{
1326 return card && 1365 return card &&
@@ -1423,8 +1462,8 @@ static int mmc_suspend(struct mmc_host *host)
1423 1462
1424 if (mmc_can_poweroff_notify(host->card)) 1463 if (mmc_can_poweroff_notify(host->card))
1425 err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT); 1464 err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
1426 else if (mmc_card_can_sleep(host)) 1465 else if (mmc_can_sleep(host->card))
1427 err = mmc_card_sleep(host); 1466 err = mmc_sleep(host);
1428 else if (!mmc_host_is_spi(host)) 1467 else if (!mmc_host_is_spi(host))
1429 err = mmc_deselect_cards(host); 1468 err = mmc_deselect_cards(host);
1430 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); 1469 host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
@@ -1514,39 +1553,7 @@ static int mmc_power_restore(struct mmc_host *host)
1514 return ret; 1553 return ret;
1515} 1554}
1516 1555
1517static int mmc_sleep(struct mmc_host *host)
1518{
1519 struct mmc_card *card = host->card;
1520 int err = -ENOSYS;
1521
1522 if (card && card->ext_csd.rev >= 3) {
1523 err = mmc_card_sleepawake(host, 1);
1524 if (err < 0)
1525 pr_debug("%s: Error %d while putting card into sleep",
1526 mmc_hostname(host), err);
1527 }
1528
1529 return err;
1530}
1531
1532static int mmc_awake(struct mmc_host *host)
1533{
1534 struct mmc_card *card = host->card;
1535 int err = -ENOSYS;
1536
1537 if (card && card->ext_csd.rev >= 3) {
1538 err = mmc_card_sleepawake(host, 0);
1539 if (err < 0)
1540 pr_debug("%s: Error %d while awaking sleeping card",
1541 mmc_hostname(host), err);
1542 }
1543
1544 return err;
1545}
1546
1547static const struct mmc_bus_ops mmc_ops = { 1556static const struct mmc_bus_ops mmc_ops = {
1548 .awake = mmc_awake,
1549 .sleep = mmc_sleep,
1550 .remove = mmc_remove, 1557 .remove = mmc_remove,
1551 .detect = mmc_detect, 1558 .detect = mmc_detect,
1552 .suspend = NULL, 1559 .suspend = NULL,
@@ -1556,8 +1563,6 @@ static const struct mmc_bus_ops mmc_ops = {
1556}; 1563};
1557 1564
1558static const struct mmc_bus_ops mmc_ops_unsafe = { 1565static const struct mmc_bus_ops mmc_ops_unsafe = {
1559 .awake = mmc_awake,
1560 .sleep = mmc_sleep,
1561 .remove = mmc_remove, 1566 .remove = mmc_remove,
1562 .detect = mmc_detect, 1567 .detect = mmc_detect,
1563 .suspend = mmc_suspend, 1568 .suspend = mmc_suspend,