}
EXPORT_SYMBOL(mmc_power_restore_host);
-int mmc_card_awake(struct mmc_host *host)
-{
- int err = -ENOSYS;
-
- if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
- return 0;
-
- mmc_bus_get(host);
-
- if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
- err = host->bus_ops->awake(host);
-
- mmc_bus_put(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_card_awake);
-
-int mmc_card_sleep(struct mmc_host *host)
-{
- int err = -ENOSYS;
-
- if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
- return 0;
-
- mmc_bus_get(host);
-
- if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
- err = host->bus_ops->sleep(host);
-
- mmc_bus_put(host);
-
- return err;
-}
-EXPORT_SYMBOL(mmc_card_sleep);
-
-int mmc_card_can_sleep(struct mmc_host *host)
-{
- struct mmc_card *card = host->card;
-
- if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3)
- return 1;
- return 0;
-}
-EXPORT_SYMBOL(mmc_card_can_sleep);
-
/*
* Flush the cache to the non-volatile storage.
*/
#define MMC_CMD_RETRIES 3
struct mmc_bus_ops {
- int (*awake)(struct mmc_host *);
- int (*sleep)(struct mmc_host *);
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
int (*suspend)(struct mmc_host *);
return err;
}
+static int mmc_can_sleep(struct mmc_card *card)
+{
+ return (card && card->ext_csd.rev >= 3);
+}
+
+static int mmc_sleep(struct mmc_host *host)
+{
+ struct mmc_command cmd = {0};
+ struct mmc_card *card = host->card;
+ int err;
+
+ if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+ return 0;
+
+ err = mmc_deselect_cards(host);
+ if (err)
+ return err;
+
+ cmd.opcode = MMC_SLEEP_AWAKE;
+ cmd.arg = card->rca << 16;
+ cmd.arg |= 1 << 15;
+
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+ if (err)
+ return err;
+
+ /*
+ * If the host does not wait while the card signals busy, then we will
+ * will have to wait the sleep/awake timeout. Note, we cannot use the
+ * SEND_STATUS command to poll the status because that command (and most
+ * others) is invalid while the card sleeps.
+ */
+ if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
+ mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
+
+ return err;
+}
+
static int mmc_can_poweroff_notify(const struct mmc_card *card)
{
return card &&
if (mmc_can_poweroff_notify(host->card))
err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
- else if (mmc_card_can_sleep(host))
- err = mmc_card_sleep(host);
+ else if (mmc_can_sleep(host->card))
+ err = mmc_sleep(host);
else if (!mmc_host_is_spi(host))
err = mmc_deselect_cards(host);
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
return ret;
}
-static int mmc_sleep(struct mmc_host *host)
-{
- struct mmc_card *card = host->card;
- int err = -ENOSYS;
-
- if (card && card->ext_csd.rev >= 3) {
- err = mmc_card_sleepawake(host, 1);
- if (err < 0)
- pr_debug("%s: Error %d while putting card into sleep",
- mmc_hostname(host), err);
- }
-
- return err;
-}
-
-static int mmc_awake(struct mmc_host *host)
-{
- struct mmc_card *card = host->card;
- int err = -ENOSYS;
-
- if (card && card->ext_csd.rev >= 3) {
- err = mmc_card_sleepawake(host, 0);
- if (err < 0)
- pr_debug("%s: Error %d while awaking sleeping card",
- mmc_hostname(host), err);
- }
-
- return err;
-}
-
static const struct mmc_bus_ops mmc_ops = {
- .awake = mmc_awake,
- .sleep = mmc_sleep,
.remove = mmc_remove,
.detect = mmc_detect,
.suspend = NULL,
};
static const struct mmc_bus_ops mmc_ops_unsafe = {
- .awake = mmc_awake,
- .sleep = mmc_sleep,
.remove = mmc_remove,
.detect = mmc_detect,
.suspend = mmc_suspend,
return _mmc_select_card(host, NULL);
}
-int mmc_card_sleepawake(struct mmc_host *host, int sleep)
-{
- struct mmc_command cmd = {0};
- struct mmc_card *card = host->card;
- int err;
-
- if (sleep)
- mmc_deselect_cards(host);
-
- cmd.opcode = MMC_SLEEP_AWAKE;
- cmd.arg = card->rca << 16;
- if (sleep)
- cmd.arg |= 1 << 15;
-
- cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
- err = mmc_wait_for_cmd(host, &cmd, 0);
- if (err)
- return err;
-
- /*
- * If the host does not wait while the card signals busy, then we will
- * will have to wait the sleep/awake timeout. Note, we cannot use the
- * SEND_STATUS command to poll the status because that command (and most
- * others) is invalid while the card sleeps.
- */
- if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
- mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
-
- if (!sleep)
- err = mmc_select_card(card);
-
- return err;
-}
-
int mmc_go_idle(struct mmc_host *host)
{
int err;
int mmc_send_cid(struct mmc_host *host, u32 *cid);
int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
-int mmc_card_sleepawake(struct mmc_host *host, int sleep);
int mmc_bus_test(struct mmc_card *card, u8 bus_width);
int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
}
#endif
-int mmc_card_awake(struct mmc_host *host);
-int mmc_card_sleep(struct mmc_host *host);
-int mmc_card_can_sleep(struct mmc_host *host);
-
int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *);
/* Module parameter */