* Copyright (C) 2003 Russell King, All Rights Reserved.
* Copyright (C) 2007-2008 Pierre Ossman
* Copyright (C) 2010 Linus Walleij
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
{
struct device_node *np;
u32 bus_width;
- int ret;
+ int len, ret;
bool cd_cap_invert, cd_gpio_invert = false;
bool ro_cap_invert, ro_gpio_invert = false;
host->pm_caps |= MMC_PM_KEEP_POWER;
if (of_property_read_bool(np, "enable-sdio-wakeup"))
host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+ if (of_find_property(np, "ignore-pm-notify", &len))
+ host->pm_caps |= MMC_PM_IGNORE_PM_NOTIFY;
if (of_property_read_bool(np, "mmc-ddr-1_8v"))
host->caps |= MMC_CAP_1_8V_DDR;
if (of_property_read_bool(np, "mmc-ddr-1_2v"))
static int mmc_can_sleep(struct mmc_card *card)
{
- return (card && card->ext_csd.rev >= 3);
+ return ((card && card->ext_csd.rev >= 3) &&
+ !(card->host->caps2 & MMC_CAP2_NO_SLEEP_CMD));
}
-static int mmc_sleep(struct mmc_host *host)
+static int mmc_sleep(struct mmc_host *host, int sleep)
{
struct mmc_command cmd = {0};
struct mmc_card *card = host->card;
/* Re-tuning can't be done once the card is deselected */
mmc_retune_hold(host);
- err = mmc_deselect_cards(host);
- if (err)
- goto out_release;
+ if (sleep) {
+ err = mmc_deselect_cards(host);
+ if (err)
+ goto out_release;
+ }
cmd.opcode = MMC_SLEEP_AWAKE;
cmd.arg = card->rca << 16;
- cmd.arg |= 1 << 15;
+ if (sleep)
+ cmd.arg |= 1 << 15;
/*
* If the max_busy_timeout of the host is specified, validate it against
if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
mmc_delay(timeout_ms);
+ if (!sleep)
+ err = mmc_select_card(card);
out_release:
mmc_retune_release(host);
return err;
if (mmc_can_poweroff_notify(host->card) &&
((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
err = mmc_poweroff_notify(host->card, notify_type);
- else if (mmc_can_sleep(host->card))
- err = mmc_sleep(host);
- else if (!mmc_host_is_spi(host))
+ else if (mmc_can_sleep(host->card)) {
+ err = mmc_sleep(host, 1);
+ if (!err) {
+ mmc_card_set_sleep(host->card);
+ mmc_card_set_suspended(host->card);
+ }
+ } else if (!mmc_host_is_spi(host))
err = mmc_deselect_cards(host);
- if (!err) {
+ if (!err && !mmc_card_in_sleep(host->card)) {
mmc_power_off(host);
mmc_card_set_suspended(host->card);
}
if (!mmc_card_suspended(host->card))
goto out;
- mmc_power_up(host, host->card->ocr);
- err = mmc_init_card(host, host->card->ocr, host->card);
- mmc_card_clr_suspended(host->card);
+ if (mmc_can_sleep(host->card) &&
+ mmc_card_in_sleep(host->card)) {
+ err = mmc_sleep(host, 0);
+ if (!err) {
+ mmc_card_clr_sleep(host->card);
+ mmc_card_clr_suspended(host->card);
+ }
+ } else {
+ mmc_power_up(host, host->card->ocr);
+ err = mmc_init_card(host, host->card->ocr, host->card);
+ mmc_card_clr_suspended(host->card);
+ }
out:
mmc_release_host(host);
mmc_retune_timer_stop(host->mmc);
mmc_retune_needed(host->mmc);
+ /*
+ * If eMMC cards are put in sleep state, Vccq can be disabled
+ * but Vcc would still be powered on. In resume, we only restore
+ * the controller context. So, set MMC_PM_KEEP_POWER flag.
+ */
+ if (!(host->mmc->caps2 & MMC_CAP2_NO_SLEEP_CMD) &&
+ (host->mmc->pm_caps & MMC_PM_KEEP_POWER))
+ host->mmc->pm_flags |= MMC_PM_KEEP_POWER;
+
if (!device_may_wakeup(mmc_dev(host->mmc))) {
host->ier = 0;
sdhci_writel(host, 0, SDHCI_INT_ENABLE);
#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */
#define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */
#define MMC_STATE_CMDQ (1<<8) /* card is in cmd queue mode */
+#define MMC_STATE_SLEEP (1<<9) /* Card is in sleep mode */
+
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
#define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED)
#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ)
+#define mmc_card_in_sleep(c) ((c)->state & MMC_STATE_SLEEP)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
+#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
#define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED)
#define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ)
#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ)
+#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
/*
* Quirk add/remove for MMC products.
#define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17)
#define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */
#define MMC_CAP2_EN_STROBE (1 << 19)
+#define MMC_CAP2_NO_SLEEP_CMD (1 << 20) /* cannot support sleep mode */
#define MMC_CAP2_HW_CQ (1 << 23) /* support eMMC command queue */
#define MMC_CAP2_CMDQ_QBR (1 << 24) /* CMDQ Queue barrier supported */