diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2013-04-19 09:12:11 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-05-26 14:23:17 -0400 |
commit | 07a682160866e302d696f5c76d74024d575fb79d (patch) | |
tree | a2c74c48a953607d255ad006e3a58a2ed0969515 /drivers/mmc/core/mmc.c | |
parent | c4d770d72492df510077b277f21ac5f0dad9e5eb (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.c | 77 |
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 | ||
1324 | static int mmc_can_sleep(struct mmc_card *card) | ||
1325 | { | ||
1326 | return (card && card->ext_csd.rev >= 3); | ||
1327 | } | ||
1328 | |||
1329 | static 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 | |||
1324 | static int mmc_can_poweroff_notify(const struct mmc_card *card) | 1363 | static 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 | ||
1517 | static 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 | |||
1532 | static 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 | |||
1547 | static const struct mmc_bus_ops mmc_ops = { | 1556 | static 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 | ||
1558 | static const struct mmc_bus_ops mmc_ops_unsafe = { | 1565 | static 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, |