diff mbox

mmc: Fixup broken suspend and eMMC4.5 power off notify

Message ID 1347528053-8521-1-git-send-email-ulf.hansson@stericsson.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ulf Hansson Sept. 13, 2012, 9:20 a.m. UTC
From: Ulf Hansson <ulf.hansson@linaro.org>

This patch fixup the broken suspend sequence for eMMC
with sleep support. Additionally it reworks the eMMC4.5
Power Off Notification feature so it fits together with
the existing sleep feature.

The CMD0 based re-initialization of the eMMC at resume
is re-introduced to maintain compatiblity for devices
using sleep.

A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
Power Off Notification feature. We might be able to
remove this cap later on, if we think that Power Off
Notification always is preferred over sleep, even if the
host is not able to cut the eMMC VCCQ power.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Saugata Das <saugata.das@linaro.org>
CC: Girish K S <girish.shivananjappa@linaro.org>
CC: Asutosh Das <asutoshd@codeaurora.org>
---
 drivers/mmc/core/core.c   |   62 ---------------------------------------------
 drivers/mmc/core/mmc.c    |   46 +++++++++++++++++++++++++--------
 drivers/mmc/host/dw_mmc.c |    5 ----
 drivers/mmc/host/sdhci.c  |    9 -------
 include/linux/mmc/card.h  |   10 +-------
 include/linux/mmc/host.h  |    4 ---
 6 files changed, 36 insertions(+), 100 deletions(-)

Comments

Girish K S Sept. 14, 2012, 5:08 a.m. UTC | #1
HI Ulf,
You had Acked the rework patch mailed by Saugata. But this patch
doesnt look same like the one sent by saugata.

On 13 September 2012 14:50, Ulf Hansson <ulf.hansson@stericsson.com> wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> This patch fixup the broken suspend sequence for eMMC
> with sleep support. Additionally it reworks the eMMC4.5
> Power Off Notification feature so it fits together with
> the existing sleep feature.
>
> The CMD0 based re-initialization of the eMMC at resume
> is re-introduced to maintain compatiblity for devices
> using sleep.
>
> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
> Power Off Notification feature. We might be able to
> remove this cap later on, if we think that Power Off
> Notification always is preferred over sleep, even if the
> host is not able to cut the eMMC VCCQ power.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Saugata Das <saugata.das@linaro.org>
> CC: Girish K S <girish.shivananjappa@linaro.org>
> CC: Asutosh Das <asutoshd@codeaurora.org>
> ---
>  drivers/mmc/core/core.c   |   62 ---------------------------------------------
>  drivers/mmc/core/mmc.c    |   46 +++++++++++++++++++++++++--------
>  drivers/mmc/host/dw_mmc.c |    5 ----
>  drivers/mmc/host/sdhci.c  |    9 -------
>  include/linux/mmc/card.h  |   10 +-------
>  include/linux/mmc/host.h  |    4 ---
>  6 files changed, 36 insertions(+), 100 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index af2c4d2..2765097 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1134,48 +1134,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
>         mmc_host_clk_release(host);
>  }
>
> -static void mmc_poweroff_notify(struct mmc_host *host)
> -{
> -       struct mmc_card *card;
> -       unsigned int timeout;
> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
> -       int err = 0;
> -
> -       card = host->card;
> -       mmc_claim_host(host);
> -
> -       /*
> -        * Send power notify command only if card
> -        * is mmc and notify state is powered ON
> -        */
> -       if (card && mmc_card_mmc(card) &&
> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
> -
> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
> -                       timeout = card->ext_csd.generic_cmd6_time;
> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
> -               } else {
> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
> -                       timeout = card->ext_csd.power_off_longtime;
> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
> -               }
> -
> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
> -                                notify_type, timeout);
> -
> -               if (err && err != -EBADMSG)
> -                       pr_err("Device failed to respond within %d poweroff "
> -                              "time. Forcefully powering down the device\n",
> -                              timeout);
> -
> -               /* Set the card state to no notification after the poweroff */
> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
> -       }
> -       mmc_release_host(host);
> -}
> -
>  /*
>   * Apply power to the MMC stack.  This is a two-stage process.
>   * First, we enable power to the card without the clock running.
> @@ -1238,8 +1196,6 @@ static void mmc_power_up(struct mmc_host *host)
>
>  void mmc_power_off(struct mmc_host *host)
>  {
> -       int err = 0;
> -
>         if (host->ios.power_mode == MMC_POWER_OFF)
>                 return;
>
> @@ -1248,22 +1204,6 @@ void mmc_power_off(struct mmc_host *host)
>         host->ios.clock = 0;
>         host->ios.vdd = 0;
>
> -       /*
> -        * For eMMC 4.5 device send AWAKE command before
> -        * POWER_OFF_NOTIFY command, because in sleep state
> -        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
> -        */
> -       if (host->card && mmc_card_is_sleep(host->card) &&
> -           host->bus_ops->resume) {
> -               err = host->bus_ops->resume(host);
> -
> -               if (!err)
> -                       mmc_poweroff_notify(host);
> -               else
> -                       pr_warning("%s: error %d during resume "
> -                                  "(continue with poweroff sequence)\n",
> -                                  mmc_hostname(host), err);
> -       }
>
>         /*
>          * Reset ocr mask to be the highest possible voltage supported for
> @@ -2425,7 +2365,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>
>                 spin_lock_irqsave(&host->lock, flags);
>                 host->rescan_disable = 1;
> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>                 spin_unlock_irqrestore(&host->lock, flags);
>                 cancel_delayed_work_sync(&host->detect);
>
> @@ -2449,7 +2388,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>
>                 spin_lock_irqsave(&host->lock, flags);
>                 host->rescan_disable = 0;
> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>                 spin_unlock_irqrestore(&host->lock, flags);
>                 mmc_detect_change(host, 0);
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 396b258..9607c35 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -996,7 +996,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>                  * so check for success and update the flag
>                  */
>                 if (!err)
> -                       card->poweroff_notify_state = MMC_POWERED_ON;
> +                       card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
>         }
>
>         /*
> @@ -1262,6 +1262,35 @@ err:
>         return err;
>  }
>
> +static int mmc_can_poweroff_notify(const struct mmc_card *card)
> +{
> +       return card &&
> +               mmc_card_mmc(card) &&
> +               (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
> +}
> +
> +static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
> +{
> +       unsigned int timeout = card->ext_csd.generic_cmd6_time;
> +       int err;
> +
> +       /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
> +       if (notify_type == EXT_CSD_POWER_OFF_LONG)
> +               timeout = card->ext_csd.power_off_longtime;
> +
> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> +                        EXT_CSD_POWER_OFF_NOTIFICATION,
> +                        notify_type, timeout);
> +       if (err)
> +               pr_err("%s: Power Off Notification timed out, %u\n",
> +                      mmc_hostname(card->host), timeout);
> +
> +       /* Disable the power off notification after the switch operation. */
> +       card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
> +
> +       return err;
> +}
> +
>  /*
>   * Host is being removed. Free up the current card.
>   */
> @@ -1322,11 +1351,11 @@ static int mmc_suspend(struct mmc_host *host)
>         BUG_ON(!host->card);
>
>         mmc_claim_host(host);
> -       if (mmc_card_can_sleep(host)) {
> +       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);
> -               if (!err)
> -                       mmc_card_set_sleep(host->card);
> -       } else if (!mmc_host_is_spi(host))
> +       else if (!mmc_host_is_spi(host))
>                 err = mmc_deselect_cards(host);
>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>         mmc_release_host(host);
> @@ -1348,11 +1377,7 @@ static int mmc_resume(struct mmc_host *host)
>         BUG_ON(!host->card);
>
>         mmc_claim_host(host);
> -       if (mmc_card_is_sleep(host->card)) {
> -               err = mmc_card_awake(host);
> -               mmc_card_clr_sleep(host->card);
> -       } else
> -               err = mmc_init_card(host, host->ocr, host->card);
> +       err = mmc_init_card(host, host->ocr, host->card);
>         mmc_release_host(host);
>
>         return err;
> @@ -1363,7 +1388,6 @@ static int mmc_power_restore(struct mmc_host *host)
>         int ret;
>
>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
> -       mmc_card_clr_sleep(host->card);
>         mmc_claim_host(host);
>         ret = mmc_init_card(host, host->ocr, host->card);
>         mmc_release_host(host);
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 36f98c0..7ef4f8a 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1810,11 +1810,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>         if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
>                 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
>
> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
> -       else
> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
> -
>         if (host->pdata->blk_settings) {
>                 mmc->max_segs = host->pdata->blk_settings->max_segs;
>                 mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index d98b199..6035094 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2878,15 +2878,6 @@ int sdhci_add_host(struct sdhci_host *host)
>         if (caps[1] & SDHCI_DRIVER_TYPE_D)
>                 mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
>
> -       /*
> -        * If Power Off Notify capability is enabled by the host,
> -        * set notify to short power off notify timeout value.
> -        */
> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
> -       else
> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
> -
>         /* Initial value for re-tuning timer count */
>         host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
>                               SDHCI_RETUNING_TIMER_COUNT_SHIFT;
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 4b27f9f..90f655b 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -57,6 +57,7 @@ struct mmc_ext_csd {
>         unsigned int            sa_timeout;             /* Units: 100ns */
>         unsigned int            generic_cmd6_time;      /* Units: 10ms */
>         unsigned int            power_off_longtime;     /* Units: ms */
> +       u8                      power_off_notification; /* state */
>         unsigned int            hs_max_dtr;
>  #define MMC_HIGH_26_MAX_DTR    26000000
>  #define MMC_HIGH_52_MAX_DTR    52000000
> @@ -225,7 +226,6 @@ struct mmc_card {
>  #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
>  #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
> -#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
>         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 */
> @@ -241,11 +241,6 @@ struct mmc_card {
>  #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
>  #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)        /* Skip secure for erase/trim */
>                                                 /* byte mode */
> -       unsigned int    poweroff_notify_state;  /* eMMC4.5 notify feature */
> -#define MMC_NO_POWER_NOTIFICATION      0
> -#define MMC_POWERED_ON                 1
> -#define MMC_POWEROFF_SHORT             2
> -#define MMC_POWEROFF_LONG              3
>
>         unsigned int            erase_size;     /* erase size in sectors */
>         unsigned int            erase_shift;    /* if erase unit is power 2 */
> @@ -392,7 +387,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>  #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
>  #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
> -#define mmc_card_is_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)
> @@ -404,9 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>  #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
>  #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_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>
> -#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
>  /*
>   * Quirk add/remove for MMC products.
>   */
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index d5d9bd4..7abb0e1 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -259,10 +259,6 @@ struct mmc_host {
>  #define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
>
>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
> -       unsigned int        power_notify_type;
> -#define MMC_HOST_PW_NOTIFY_NONE                0
> -#define MMC_HOST_PW_NOTIFY_SHORT       1
> -#define MMC_HOST_PW_NOTIFY_LONG                2
>
>  #ifdef CONFIG_MMC_CLKGATE
>         int                     clk_requests;   /* internal reference counter */
> --
> 1.7.10
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 14, 2012, 6:38 a.m. UTC | #2
On 14 September 2012 10:38, Girish K S <girish.shivananjappa@linaro.org> wrote:
> HI Ulf,
> You had Acked the rework patch mailed by Saugata. But this patch
> doesnt look same like the one sent by saugata.
Sorry Ulf
I saw your and Saugata mail after replying to this.
Pls ignore this
>
> On 13 September 2012 14:50, Ulf Hansson <ulf.hansson@stericsson.com> wrote:
>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>
>> This patch fixup the broken suspend sequence for eMMC
>> with sleep support. Additionally it reworks the eMMC4.5
>> Power Off Notification feature so it fits together with
>> the existing sleep feature.
>>
>> The CMD0 based re-initialization of the eMMC at resume
>> is re-introduced to maintain compatiblity for devices
>> using sleep.
>>
>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>> Power Off Notification feature. We might be able to
>> remove this cap later on, if we think that Power Off
>> Notification always is preferred over sleep, even if the
>> host is not able to cut the eMMC VCCQ power.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>> CC: Girish K S <girish.shivananjappa@linaro.org>
>> CC: Asutosh Das <asutoshd@codeaurora.org>
>> ---
>>  drivers/mmc/core/core.c   |   62 ---------------------------------------------
>>  drivers/mmc/core/mmc.c    |   46 +++++++++++++++++++++++++--------
>>  drivers/mmc/host/dw_mmc.c |    5 ----
>>  drivers/mmc/host/sdhci.c  |    9 -------
>>  include/linux/mmc/card.h  |   10 +-------
>>  include/linux/mmc/host.h  |    4 ---
>>  6 files changed, 36 insertions(+), 100 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index af2c4d2..2765097 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1134,48 +1134,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
>>         mmc_host_clk_release(host);
>>  }
>>
>> -static void mmc_poweroff_notify(struct mmc_host *host)
>> -{
>> -       struct mmc_card *card;
>> -       unsigned int timeout;
>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>> -       int err = 0;
>> -
>> -       card = host->card;
>> -       mmc_claim_host(host);
>> -
>> -       /*
>> -        * Send power notify command only if card
>> -        * is mmc and notify state is powered ON
>> -        */
>> -       if (card && mmc_card_mmc(card) &&
>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>> -
>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>> -                       timeout = card->ext_csd.generic_cmd6_time;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>> -               } else {
>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>> -                       timeout = card->ext_csd.power_off_longtime;
>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>> -               }
>> -
>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>> -                                notify_type, timeout);
>> -
>> -               if (err && err != -EBADMSG)
>> -                       pr_err("Device failed to respond within %d poweroff "
>> -                              "time. Forcefully powering down the device\n",
>> -                              timeout);
>> -
>> -               /* Set the card state to no notification after the poweroff */
>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>> -       }
>> -       mmc_release_host(host);
>> -}
>> -
>>  /*
>>   * Apply power to the MMC stack.  This is a two-stage process.
>>   * First, we enable power to the card without the clock running.
>> @@ -1238,8 +1196,6 @@ static void mmc_power_up(struct mmc_host *host)
>>
>>  void mmc_power_off(struct mmc_host *host)
>>  {
>> -       int err = 0;
>> -
>>         if (host->ios.power_mode == MMC_POWER_OFF)
>>                 return;
>>
>> @@ -1248,22 +1204,6 @@ void mmc_power_off(struct mmc_host *host)
>>         host->ios.clock = 0;
>>         host->ios.vdd = 0;
>>
>> -       /*
>> -        * For eMMC 4.5 device send AWAKE command before
>> -        * POWER_OFF_NOTIFY command, because in sleep state
>> -        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
>> -        */
>> -       if (host->card && mmc_card_is_sleep(host->card) &&
>> -           host->bus_ops->resume) {
>> -               err = host->bus_ops->resume(host);
>> -
>> -               if (!err)
>> -                       mmc_poweroff_notify(host);
>> -               else
>> -                       pr_warning("%s: error %d during resume "
>> -                                  "(continue with poweroff sequence)\n",
>> -                                  mmc_hostname(host), err);
>> -       }
>>
>>         /*
>>          * Reset ocr mask to be the highest possible voltage supported for
>> @@ -2425,7 +2365,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>
>>                 spin_lock_irqsave(&host->lock, flags);
>>                 host->rescan_disable = 1;
>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>                 spin_unlock_irqrestore(&host->lock, flags);
>>                 cancel_delayed_work_sync(&host->detect);
>>
>> @@ -2449,7 +2388,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>
>>                 spin_lock_irqsave(&host->lock, flags);
>>                 host->rescan_disable = 0;
>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>>                 spin_unlock_irqrestore(&host->lock, flags);
>>                 mmc_detect_change(host, 0);
>>
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index 396b258..9607c35 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -996,7 +996,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>>                  * so check for success and update the flag
>>                  */
>>                 if (!err)
>> -                       card->poweroff_notify_state = MMC_POWERED_ON;
>> +                       card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
>>         }
>>
>>         /*
>> @@ -1262,6 +1262,35 @@ err:
>>         return err;
>>  }
>>
>> +static int mmc_can_poweroff_notify(const struct mmc_card *card)
>> +{
>> +       return card &&
>> +               mmc_card_mmc(card) &&
>> +               (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
>> +}
>> +
>> +static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
>> +{
>> +       unsigned int timeout = card->ext_csd.generic_cmd6_time;
>> +       int err;
>> +
>> +       /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
>> +       if (notify_type == EXT_CSD_POWER_OFF_LONG)
>> +               timeout = card->ext_csd.power_off_longtime;
>> +
>> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                        EXT_CSD_POWER_OFF_NOTIFICATION,
>> +                        notify_type, timeout);
>> +       if (err)
>> +               pr_err("%s: Power Off Notification timed out, %u\n",
>> +                      mmc_hostname(card->host), timeout);
>> +
>> +       /* Disable the power off notification after the switch operation. */
>> +       card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
>> +
>> +       return err;
>> +}
>> +
>>  /*
>>   * Host is being removed. Free up the current card.
>>   */
>> @@ -1322,11 +1351,11 @@ static int mmc_suspend(struct mmc_host *host)
>>         BUG_ON(!host->card);
>>
>>         mmc_claim_host(host);
>> -       if (mmc_card_can_sleep(host)) {
>> +       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);
>> -               if (!err)
>> -                       mmc_card_set_sleep(host->card);
>> -       } else if (!mmc_host_is_spi(host))
>> +       else if (!mmc_host_is_spi(host))
>>                 err = mmc_deselect_cards(host);
>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>>         mmc_release_host(host);
>> @@ -1348,11 +1377,7 @@ static int mmc_resume(struct mmc_host *host)
>>         BUG_ON(!host->card);
>>
>>         mmc_claim_host(host);
>> -       if (mmc_card_is_sleep(host->card)) {
>> -               err = mmc_card_awake(host);
>> -               mmc_card_clr_sleep(host->card);
>> -       } else
>> -               err = mmc_init_card(host, host->ocr, host->card);
>> +       err = mmc_init_card(host, host->ocr, host->card);
>>         mmc_release_host(host);
>>
>>         return err;
>> @@ -1363,7 +1388,6 @@ static int mmc_power_restore(struct mmc_host *host)
>>         int ret;
>>
>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>> -       mmc_card_clr_sleep(host->card);
>>         mmc_claim_host(host);
>>         ret = mmc_init_card(host, host->ocr, host->card);
>>         mmc_release_host(host);
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 36f98c0..7ef4f8a 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1810,11 +1810,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>>         if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
>>                 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
>>
>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>> -       else
>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>> -
>>         if (host->pdata->blk_settings) {
>>                 mmc->max_segs = host->pdata->blk_settings->max_segs;
>>                 mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>> index d98b199..6035094 100644
>> --- a/drivers/mmc/host/sdhci.c
>> +++ b/drivers/mmc/host/sdhci.c
>> @@ -2878,15 +2878,6 @@ int sdhci_add_host(struct sdhci_host *host)
>>         if (caps[1] & SDHCI_DRIVER_TYPE_D)
>>                 mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
>>
>> -       /*
>> -        * If Power Off Notify capability is enabled by the host,
>> -        * set notify to short power off notify timeout value.
>> -        */
>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>> -       else
>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>> -
>>         /* Initial value for re-tuning timer count */
>>         host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
>>                               SDHCI_RETUNING_TIMER_COUNT_SHIFT;
>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>> index 4b27f9f..90f655b 100644
>> --- a/include/linux/mmc/card.h
>> +++ b/include/linux/mmc/card.h
>> @@ -57,6 +57,7 @@ struct mmc_ext_csd {
>>         unsigned int            sa_timeout;             /* Units: 100ns */
>>         unsigned int            generic_cmd6_time;      /* Units: 10ms */
>>         unsigned int            power_off_longtime;     /* Units: ms */
>> +       u8                      power_off_notification; /* state */
>>         unsigned int            hs_max_dtr;
>>  #define MMC_HIGH_26_MAX_DTR    26000000
>>  #define MMC_HIGH_52_MAX_DTR    52000000
>> @@ -225,7 +226,6 @@ struct mmc_card {
>>  #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
>>  #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
>>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
>> -#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
>>         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 */
>> @@ -241,11 +241,6 @@ struct mmc_card {
>>  #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
>>  #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)        /* Skip secure for erase/trim */
>>                                                 /* byte mode */
>> -       unsigned int    poweroff_notify_state;  /* eMMC4.5 notify feature */
>> -#define MMC_NO_POWER_NOTIFICATION      0
>> -#define MMC_POWERED_ON                 1
>> -#define MMC_POWEROFF_SHORT             2
>> -#define MMC_POWEROFF_LONG              3
>>
>>         unsigned int            erase_size;     /* erase size in sectors */
>>         unsigned int            erase_shift;    /* if erase unit is power 2 */
>> @@ -392,7 +387,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>  #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
>>  #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
>>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
>> -#define mmc_card_is_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)
>> @@ -404,9 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>  #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
>>  #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_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>>
>> -#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
>>  /*
>>   * Quirk add/remove for MMC products.
>>   */
>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>> index d5d9bd4..7abb0e1 100644
>> --- a/include/linux/mmc/host.h
>> +++ b/include/linux/mmc/host.h
>> @@ -259,10 +259,6 @@ struct mmc_host {
>>  #define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
>>
>>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
>> -       unsigned int        power_notify_type;
>> -#define MMC_HOST_PW_NOTIFY_NONE                0
>> -#define MMC_HOST_PW_NOTIFY_SHORT       1
>> -#define MMC_HOST_PW_NOTIFY_LONG                2
>>
>>  #ifdef CONFIG_MMC_CLKGATE
>>         int                     clk_requests;   /* internal reference counter */
>> --
>> 1.7.10
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 14, 2012, 7:07 a.m. UTC | #3
Hi Girish,

I should also have stated that this patch has not been tested with an
eMMC 4.5 device, thus the power off notification is not fully tested.
Unfortunate I don't have such a device available right now. What I did
test was that patch must not break anything and tested that the
suspend/resume sequence is fixed for eMMC with sleep support. I also
tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.

Are you able to help out in testing with a eMMC 4.5 device with
POWER_OFF_NOTIFY support?

Kind regards
Ulf Hansson

On 14 September 2012 08:38, Girish K S <girish.shivananjappa@linaro.org> wrote:
> On 14 September 2012 10:38, Girish K S <girish.shivananjappa@linaro.org> wrote:
>> HI Ulf,
>> You had Acked the rework patch mailed by Saugata. But this patch
>> doesnt look same like the one sent by saugata.
> Sorry Ulf
> I saw your and Saugata mail after replying to this.
> Pls ignore this
>>
>> On 13 September 2012 14:50, Ulf Hansson <ulf.hansson@stericsson.com> wrote:
>>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>>
>>> This patch fixup the broken suspend sequence for eMMC
>>> with sleep support. Additionally it reworks the eMMC4.5
>>> Power Off Notification feature so it fits together with
>>> the existing sleep feature.
>>>
>>> The CMD0 based re-initialization of the eMMC at resume
>>> is re-introduced to maintain compatiblity for devices
>>> using sleep.
>>>
>>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>>> Power Off Notification feature. We might be able to
>>> remove this cap later on, if we think that Power Off
>>> Notification always is preferred over sleep, even if the
>>> host is not able to cut the eMMC VCCQ power.
>>>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>>> CC: Girish K S <girish.shivananjappa@linaro.org>
>>> CC: Asutosh Das <asutoshd@codeaurora.org>
>>> ---
>>>  drivers/mmc/core/core.c   |   62 ---------------------------------------------
>>>  drivers/mmc/core/mmc.c    |   46 +++++++++++++++++++++++++--------
>>>  drivers/mmc/host/dw_mmc.c |    5 ----
>>>  drivers/mmc/host/sdhci.c  |    9 -------
>>>  include/linux/mmc/card.h  |   10 +-------
>>>  include/linux/mmc/host.h  |    4 ---
>>>  6 files changed, 36 insertions(+), 100 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index af2c4d2..2765097 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1134,48 +1134,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
>>>         mmc_host_clk_release(host);
>>>  }
>>>
>>> -static void mmc_poweroff_notify(struct mmc_host *host)
>>> -{
>>> -       struct mmc_card *card;
>>> -       unsigned int timeout;
>>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>>> -       int err = 0;
>>> -
>>> -       card = host->card;
>>> -       mmc_claim_host(host);
>>> -
>>> -       /*
>>> -        * Send power notify command only if card
>>> -        * is mmc and notify state is powered ON
>>> -        */
>>> -       if (card && mmc_card_mmc(card) &&
>>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>>> -
>>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>>> -                       timeout = card->ext_csd.generic_cmd6_time;
>>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>>> -               } else {
>>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>>> -                       timeout = card->ext_csd.power_off_longtime;
>>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>>> -               }
>>> -
>>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>>> -                                notify_type, timeout);
>>> -
>>> -               if (err && err != -EBADMSG)
>>> -                       pr_err("Device failed to respond within %d poweroff "
>>> -                              "time. Forcefully powering down the device\n",
>>> -                              timeout);
>>> -
>>> -               /* Set the card state to no notification after the poweroff */
>>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>>> -       }
>>> -       mmc_release_host(host);
>>> -}
>>> -
>>>  /*
>>>   * Apply power to the MMC stack.  This is a two-stage process.
>>>   * First, we enable power to the card without the clock running.
>>> @@ -1238,8 +1196,6 @@ static void mmc_power_up(struct mmc_host *host)
>>>
>>>  void mmc_power_off(struct mmc_host *host)
>>>  {
>>> -       int err = 0;
>>> -
>>>         if (host->ios.power_mode == MMC_POWER_OFF)
>>>                 return;
>>>
>>> @@ -1248,22 +1204,6 @@ void mmc_power_off(struct mmc_host *host)
>>>         host->ios.clock = 0;
>>>         host->ios.vdd = 0;
>>>
>>> -       /*
>>> -        * For eMMC 4.5 device send AWAKE command before
>>> -        * POWER_OFF_NOTIFY command, because in sleep state
>>> -        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
>>> -        */
>>> -       if (host->card && mmc_card_is_sleep(host->card) &&
>>> -           host->bus_ops->resume) {
>>> -               err = host->bus_ops->resume(host);
>>> -
>>> -               if (!err)
>>> -                       mmc_poweroff_notify(host);
>>> -               else
>>> -                       pr_warning("%s: error %d during resume "
>>> -                                  "(continue with poweroff sequence)\n",
>>> -                                  mmc_hostname(host), err);
>>> -       }
>>>
>>>         /*
>>>          * Reset ocr mask to be the highest possible voltage supported for
>>> @@ -2425,7 +2365,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>>
>>>                 spin_lock_irqsave(&host->lock, flags);
>>>                 host->rescan_disable = 1;
>>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>>                 spin_unlock_irqrestore(&host->lock, flags);
>>>                 cancel_delayed_work_sync(&host->detect);
>>>
>>> @@ -2449,7 +2388,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>>
>>>                 spin_lock_irqsave(&host->lock, flags);
>>>                 host->rescan_disable = 0;
>>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>>>                 spin_unlock_irqrestore(&host->lock, flags);
>>>                 mmc_detect_change(host, 0);
>>>
>>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>>> index 396b258..9607c35 100644
>>> --- a/drivers/mmc/core/mmc.c
>>> +++ b/drivers/mmc/core/mmc.c
>>> @@ -996,7 +996,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>>>                  * so check for success and update the flag
>>>                  */
>>>                 if (!err)
>>> -                       card->poweroff_notify_state = MMC_POWERED_ON;
>>> +                       card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
>>>         }
>>>
>>>         /*
>>> @@ -1262,6 +1262,35 @@ err:
>>>         return err;
>>>  }
>>>
>>> +static int mmc_can_poweroff_notify(const struct mmc_card *card)
>>> +{
>>> +       return card &&
>>> +               mmc_card_mmc(card) &&
>>> +               (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
>>> +}
>>> +
>>> +static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
>>> +{
>>> +       unsigned int timeout = card->ext_csd.generic_cmd6_time;
>>> +       int err;
>>> +
>>> +       /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
>>> +       if (notify_type == EXT_CSD_POWER_OFF_LONG)
>>> +               timeout = card->ext_csd.power_off_longtime;
>>> +
>>> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> +                        EXT_CSD_POWER_OFF_NOTIFICATION,
>>> +                        notify_type, timeout);
>>> +       if (err)
>>> +               pr_err("%s: Power Off Notification timed out, %u\n",
>>> +                      mmc_hostname(card->host), timeout);
>>> +
>>> +       /* Disable the power off notification after the switch operation. */
>>> +       card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
>>> +
>>> +       return err;
>>> +}
>>> +
>>>  /*
>>>   * Host is being removed. Free up the current card.
>>>   */
>>> @@ -1322,11 +1351,11 @@ static int mmc_suspend(struct mmc_host *host)
>>>         BUG_ON(!host->card);
>>>
>>>         mmc_claim_host(host);
>>> -       if (mmc_card_can_sleep(host)) {
>>> +       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);
>>> -               if (!err)
>>> -                       mmc_card_set_sleep(host->card);
>>> -       } else if (!mmc_host_is_spi(host))
>>> +       else if (!mmc_host_is_spi(host))
>>>                 err = mmc_deselect_cards(host);
>>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>>>         mmc_release_host(host);
>>> @@ -1348,11 +1377,7 @@ static int mmc_resume(struct mmc_host *host)
>>>         BUG_ON(!host->card);
>>>
>>>         mmc_claim_host(host);
>>> -       if (mmc_card_is_sleep(host->card)) {
>>> -               err = mmc_card_awake(host);
>>> -               mmc_card_clr_sleep(host->card);
>>> -       } else
>>> -               err = mmc_init_card(host, host->ocr, host->card);
>>> +       err = mmc_init_card(host, host->ocr, host->card);
>>>         mmc_release_host(host);
>>>
>>>         return err;
>>> @@ -1363,7 +1388,6 @@ static int mmc_power_restore(struct mmc_host *host)
>>>         int ret;
>>>
>>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>>> -       mmc_card_clr_sleep(host->card);
>>>         mmc_claim_host(host);
>>>         ret = mmc_init_card(host, host->ocr, host->card);
>>>         mmc_release_host(host);
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 36f98c0..7ef4f8a 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -1810,11 +1810,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>>>         if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
>>>                 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
>>>
>>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>> -       else
>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>>> -
>>>         if (host->pdata->blk_settings) {
>>>                 mmc->max_segs = host->pdata->blk_settings->max_segs;
>>>                 mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>> index d98b199..6035094 100644
>>> --- a/drivers/mmc/host/sdhci.c
>>> +++ b/drivers/mmc/host/sdhci.c
>>> @@ -2878,15 +2878,6 @@ int sdhci_add_host(struct sdhci_host *host)
>>>         if (caps[1] & SDHCI_DRIVER_TYPE_D)
>>>                 mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
>>>
>>> -       /*
>>> -        * If Power Off Notify capability is enabled by the host,
>>> -        * set notify to short power off notify timeout value.
>>> -        */
>>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>> -       else
>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>>> -
>>>         /* Initial value for re-tuning timer count */
>>>         host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
>>>                               SDHCI_RETUNING_TIMER_COUNT_SHIFT;
>>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>>> index 4b27f9f..90f655b 100644
>>> --- a/include/linux/mmc/card.h
>>> +++ b/include/linux/mmc/card.h
>>> @@ -57,6 +57,7 @@ struct mmc_ext_csd {
>>>         unsigned int            sa_timeout;             /* Units: 100ns */
>>>         unsigned int            generic_cmd6_time;      /* Units: 10ms */
>>>         unsigned int            power_off_longtime;     /* Units: ms */
>>> +       u8                      power_off_notification; /* state */
>>>         unsigned int            hs_max_dtr;
>>>  #define MMC_HIGH_26_MAX_DTR    26000000
>>>  #define MMC_HIGH_52_MAX_DTR    52000000
>>> @@ -225,7 +226,6 @@ struct mmc_card {
>>>  #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
>>>  #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
>>>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
>>> -#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
>>>         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 */
>>> @@ -241,11 +241,6 @@ struct mmc_card {
>>>  #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
>>>  #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)        /* Skip secure for erase/trim */
>>>                                                 /* byte mode */
>>> -       unsigned int    poweroff_notify_state;  /* eMMC4.5 notify feature */
>>> -#define MMC_NO_POWER_NOTIFICATION      0
>>> -#define MMC_POWERED_ON                 1
>>> -#define MMC_POWEROFF_SHORT             2
>>> -#define MMC_POWEROFF_LONG              3
>>>
>>>         unsigned int            erase_size;     /* erase size in sectors */
>>>         unsigned int            erase_shift;    /* if erase unit is power 2 */
>>> @@ -392,7 +387,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>>  #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
>>>  #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
>>>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
>>> -#define mmc_card_is_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)
>>> @@ -404,9 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>>  #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
>>>  #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_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>>>
>>> -#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
>>>  /*
>>>   * Quirk add/remove for MMC products.
>>>   */
>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>> index d5d9bd4..7abb0e1 100644
>>> --- a/include/linux/mmc/host.h
>>> +++ b/include/linux/mmc/host.h
>>> @@ -259,10 +259,6 @@ struct mmc_host {
>>>  #define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
>>>
>>>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
>>> -       unsigned int        power_notify_type;
>>> -#define MMC_HOST_PW_NOTIFY_NONE                0
>>> -#define MMC_HOST_PW_NOTIFY_SHORT       1
>>> -#define MMC_HOST_PW_NOTIFY_LONG                2
>>>
>>>  #ifdef CONFIG_MMC_CLKGATE
>>>         int                     clk_requests;   /* internal reference counter */
>>> --
>>> 1.7.10
>>>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 14, 2012, 8:25 a.m. UTC | #4
On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> Hi Girish,
>
> I should also have stated that this patch has not been tested with an
> eMMC 4.5 device, thus the power off notification is not fully tested.
> Unfortunate I don't have such a device available right now. What I did
> test was that patch must not break anything and tested that the
> suspend/resume sequence is fixed for eMMC with sleep support. I also
> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>
> Are you able to help out in testing with a eMMC 4.5 device with
> POWER_OFF_NOTIFY support?
I am also facing the same  problem. The board that i used earlier to
upstream 4.5 patches is not functioning. Thats the reason for the
delay in upstreaming or sending the patch. Once i get it repaired i ll
definitely do it.
It would be helpful if somebody in the list can do this in the mean time.
>
> Kind regards
> Ulf Hansson
>
> On 14 September 2012 08:38, Girish K S <girish.shivananjappa@linaro.org> wrote:
>> On 14 September 2012 10:38, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>> HI Ulf,
>>> You had Acked the rework patch mailed by Saugata. But this patch
>>> doesnt look same like the one sent by saugata.
>> Sorry Ulf
>> I saw your and Saugata mail after replying to this.
>> Pls ignore this
>>>
>>> On 13 September 2012 14:50, Ulf Hansson <ulf.hansson@stericsson.com> wrote:
>>>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>>>
>>>> This patch fixup the broken suspend sequence for eMMC
>>>> with sleep support. Additionally it reworks the eMMC4.5
>>>> Power Off Notification feature so it fits together with
>>>> the existing sleep feature.
>>>>
>>>> The CMD0 based re-initialization of the eMMC at resume
>>>> is re-introduced to maintain compatiblity for devices
>>>> using sleep.
>>>>
>>>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>>>> Power Off Notification feature. We might be able to
>>>> remove this cap later on, if we think that Power Off
>>>> Notification always is preferred over sleep, even if the
>>>> host is not able to cut the eMMC VCCQ power.
>>>>
>>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>>>> CC: Girish K S <girish.shivananjappa@linaro.org>
>>>> CC: Asutosh Das <asutoshd@codeaurora.org>
>>>> ---
>>>>  drivers/mmc/core/core.c   |   62 ---------------------------------------------
>>>>  drivers/mmc/core/mmc.c    |   46 +++++++++++++++++++++++++--------
>>>>  drivers/mmc/host/dw_mmc.c |    5 ----
>>>>  drivers/mmc/host/sdhci.c  |    9 -------
>>>>  include/linux/mmc/card.h  |   10 +-------
>>>>  include/linux/mmc/host.h  |    4 ---
>>>>  6 files changed, 36 insertions(+), 100 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>> index af2c4d2..2765097 100644
>>>> --- a/drivers/mmc/core/core.c
>>>> +++ b/drivers/mmc/core/core.c
>>>> @@ -1134,48 +1134,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
>>>>         mmc_host_clk_release(host);
>>>>  }
>>>>
>>>> -static void mmc_poweroff_notify(struct mmc_host *host)
>>>> -{
>>>> -       struct mmc_card *card;
>>>> -       unsigned int timeout;
>>>> -       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
>>>> -       int err = 0;
>>>> -
>>>> -       card = host->card;
>>>> -       mmc_claim_host(host);
>>>> -
>>>> -       /*
>>>> -        * Send power notify command only if card
>>>> -        * is mmc and notify state is powered ON
>>>> -        */
>>>> -       if (card && mmc_card_mmc(card) &&
>>>> -           (card->poweroff_notify_state == MMC_POWERED_ON)) {
>>>> -
>>>> -               if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
>>>> -                       notify_type = EXT_CSD_POWER_OFF_SHORT;
>>>> -                       timeout = card->ext_csd.generic_cmd6_time;
>>>> -                       card->poweroff_notify_state = MMC_POWEROFF_SHORT;
>>>> -               } else {
>>>> -                       notify_type = EXT_CSD_POWER_OFF_LONG;
>>>> -                       timeout = card->ext_csd.power_off_longtime;
>>>> -                       card->poweroff_notify_state = MMC_POWEROFF_LONG;
>>>> -               }
>>>> -
>>>> -               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>>> -                                EXT_CSD_POWER_OFF_NOTIFICATION,
>>>> -                                notify_type, timeout);
>>>> -
>>>> -               if (err && err != -EBADMSG)
>>>> -                       pr_err("Device failed to respond within %d poweroff "
>>>> -                              "time. Forcefully powering down the device\n",
>>>> -                              timeout);
>>>> -
>>>> -               /* Set the card state to no notification after the poweroff */
>>>> -               card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
>>>> -       }
>>>> -       mmc_release_host(host);
>>>> -}
>>>> -
>>>>  /*
>>>>   * Apply power to the MMC stack.  This is a two-stage process.
>>>>   * First, we enable power to the card without the clock running.
>>>> @@ -1238,8 +1196,6 @@ static void mmc_power_up(struct mmc_host *host)
>>>>
>>>>  void mmc_power_off(struct mmc_host *host)
>>>>  {
>>>> -       int err = 0;
>>>> -
>>>>         if (host->ios.power_mode == MMC_POWER_OFF)
>>>>                 return;
>>>>
>>>> @@ -1248,22 +1204,6 @@ void mmc_power_off(struct mmc_host *host)
>>>>         host->ios.clock = 0;
>>>>         host->ios.vdd = 0;
>>>>
>>>> -       /*
>>>> -        * For eMMC 4.5 device send AWAKE command before
>>>> -        * POWER_OFF_NOTIFY command, because in sleep state
>>>> -        * eMMC 4.5 devices respond to only RESET and AWAKE cmd
>>>> -        */
>>>> -       if (host->card && mmc_card_is_sleep(host->card) &&
>>>> -           host->bus_ops->resume) {
>>>> -               err = host->bus_ops->resume(host);
>>>> -
>>>> -               if (!err)
>>>> -                       mmc_poweroff_notify(host);
>>>> -               else
>>>> -                       pr_warning("%s: error %d during resume "
>>>> -                                  "(continue with poweroff sequence)\n",
>>>> -                                  mmc_hostname(host), err);
>>>> -       }
>>>>
>>>>         /*
>>>>          * Reset ocr mask to be the highest possible voltage supported for
>>>> @@ -2425,7 +2365,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>>>
>>>>                 spin_lock_irqsave(&host->lock, flags);
>>>>                 host->rescan_disable = 1;
>>>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>>>                 spin_unlock_irqrestore(&host->lock, flags);
>>>>                 cancel_delayed_work_sync(&host->detect);
>>>>
>>>> @@ -2449,7 +2388,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>>>
>>>>                 spin_lock_irqsave(&host->lock, flags);
>>>>                 host->rescan_disable = 0;
>>>> -               host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>>>>                 spin_unlock_irqrestore(&host->lock, flags);
>>>>                 mmc_detect_change(host, 0);
>>>>
>>>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>>>> index 396b258..9607c35 100644
>>>> --- a/drivers/mmc/core/mmc.c
>>>> +++ b/drivers/mmc/core/mmc.c
>>>> @@ -996,7 +996,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>>>>                  * so check for success and update the flag
>>>>                  */
>>>>                 if (!err)
>>>> -                       card->poweroff_notify_state = MMC_POWERED_ON;
>>>> +                       card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
>>>>         }
>>>>
>>>>         /*
>>>> @@ -1262,6 +1262,35 @@ err:
>>>>         return err;
>>>>  }
>>>>
>>>> +static int mmc_can_poweroff_notify(const struct mmc_card *card)
>>>> +{
>>>> +       return card &&
>>>> +               mmc_card_mmc(card) &&
>>>> +               (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
>>>> +}
>>>> +
>>>> +static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
>>>> +{
>>>> +       unsigned int timeout = card->ext_csd.generic_cmd6_time;
>>>> +       int err;
>>>> +
>>>> +       /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
>>>> +       if (notify_type == EXT_CSD_POWER_OFF_LONG)
>>>> +               timeout = card->ext_csd.power_off_longtime;
>>>> +
>>>> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>>> +                        EXT_CSD_POWER_OFF_NOTIFICATION,
>>>> +                        notify_type, timeout);
>>>> +       if (err)
>>>> +               pr_err("%s: Power Off Notification timed out, %u\n",
>>>> +                      mmc_hostname(card->host), timeout);
>>>> +
>>>> +       /* Disable the power off notification after the switch operation. */
>>>> +       card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
>>>> +
>>>> +       return err;
>>>> +}
>>>> +
>>>>  /*
>>>>   * Host is being removed. Free up the current card.
>>>>   */
>>>> @@ -1322,11 +1351,11 @@ static int mmc_suspend(struct mmc_host *host)
>>>>         BUG_ON(!host->card);
>>>>
>>>>         mmc_claim_host(host);
>>>> -       if (mmc_card_can_sleep(host)) {
>>>> +       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);
>>>> -               if (!err)
>>>> -                       mmc_card_set_sleep(host->card);
>>>> -       } else if (!mmc_host_is_spi(host))
>>>> +       else if (!mmc_host_is_spi(host))
>>>>                 err = mmc_deselect_cards(host);
>>>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>>>>         mmc_release_host(host);
>>>> @@ -1348,11 +1377,7 @@ static int mmc_resume(struct mmc_host *host)
>>>>         BUG_ON(!host->card);
>>>>
>>>>         mmc_claim_host(host);
>>>> -       if (mmc_card_is_sleep(host->card)) {
>>>> -               err = mmc_card_awake(host);
>>>> -               mmc_card_clr_sleep(host->card);
>>>> -       } else
>>>> -               err = mmc_init_card(host, host->ocr, host->card);
>>>> +       err = mmc_init_card(host, host->ocr, host->card);
>>>>         mmc_release_host(host);
>>>>
>>>>         return err;
>>>> @@ -1363,7 +1388,6 @@ static int mmc_power_restore(struct mmc_host *host)
>>>>         int ret;
>>>>
>>>>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
>>>> -       mmc_card_clr_sleep(host->card);
>>>>         mmc_claim_host(host);
>>>>         ret = mmc_init_card(host, host->ocr, host->card);
>>>>         mmc_release_host(host);
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 36f98c0..7ef4f8a 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -1810,11 +1810,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>>>>         if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
>>>>                 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
>>>>
>>>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>>> -       else
>>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>>>> -
>>>>         if (host->pdata->blk_settings) {
>>>>                 mmc->max_segs = host->pdata->blk_settings->max_segs;
>>>>                 mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
>>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>>> index d98b199..6035094 100644
>>>> --- a/drivers/mmc/host/sdhci.c
>>>> +++ b/drivers/mmc/host/sdhci.c
>>>> @@ -2878,15 +2878,6 @@ int sdhci_add_host(struct sdhci_host *host)
>>>>         if (caps[1] & SDHCI_DRIVER_TYPE_D)
>>>>                 mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
>>>>
>>>> -       /*
>>>> -        * If Power Off Notify capability is enabled by the host,
>>>> -        * set notify to short power off notify timeout value.
>>>> -        */
>>>> -       if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
>>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>>>> -       else
>>>> -               mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
>>>> -
>>>>         /* Initial value for re-tuning timer count */
>>>>         host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
>>>>                               SDHCI_RETUNING_TIMER_COUNT_SHIFT;
>>>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>>>> index 4b27f9f..90f655b 100644
>>>> --- a/include/linux/mmc/card.h
>>>> +++ b/include/linux/mmc/card.h
>>>> @@ -57,6 +57,7 @@ struct mmc_ext_csd {
>>>>         unsigned int            sa_timeout;             /* Units: 100ns */
>>>>         unsigned int            generic_cmd6_time;      /* Units: 10ms */
>>>>         unsigned int            power_off_longtime;     /* Units: ms */
>>>> +       u8                      power_off_notification; /* state */
>>>>         unsigned int            hs_max_dtr;
>>>>  #define MMC_HIGH_26_MAX_DTR    26000000
>>>>  #define MMC_HIGH_52_MAX_DTR    52000000
>>>> @@ -225,7 +226,6 @@ struct mmc_card {
>>>>  #define MMC_CARD_SDXC          (1<<6)          /* card is SDXC */
>>>>  #define MMC_CARD_REMOVED       (1<<7)          /* card has been removed */
>>>>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
>>>> -#define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
>>>>         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 */
>>>> @@ -241,11 +241,6 @@ struct mmc_card {
>>>>  #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
>>>>  #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)        /* Skip secure for erase/trim */
>>>>                                                 /* byte mode */
>>>> -       unsigned int    poweroff_notify_state;  /* eMMC4.5 notify feature */
>>>> -#define MMC_NO_POWER_NOTIFICATION      0
>>>> -#define MMC_POWERED_ON                 1
>>>> -#define MMC_POWEROFF_SHORT             2
>>>> -#define MMC_POWEROFF_LONG              3
>>>>
>>>>         unsigned int            erase_size;     /* erase size in sectors */
>>>>         unsigned int            erase_shift;    /* if erase unit is power 2 */
>>>> @@ -392,7 +387,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>>>  #define mmc_sd_card_uhs(c)     ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
>>>>  #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
>>>>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
>>>> -#define mmc_card_is_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)
>>>> @@ -404,9 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>>>>  #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
>>>>  #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_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>>>>
>>>> -#define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
>>>>  /*
>>>>   * Quirk add/remove for MMC products.
>>>>   */
>>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>>> index d5d9bd4..7abb0e1 100644
>>>> --- a/include/linux/mmc/host.h
>>>> +++ b/include/linux/mmc/host.h
>>>> @@ -259,10 +259,6 @@ struct mmc_host {
>>>>  #define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
>>>>
>>>>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
>>>> -       unsigned int        power_notify_type;
>>>> -#define MMC_HOST_PW_NOTIFY_NONE                0
>>>> -#define MMC_HOST_PW_NOTIFY_SHORT       1
>>>> -#define MMC_HOST_PW_NOTIFY_LONG                2
>>>>
>>>>  #ifdef CONFIG_MMC_CLKGATE
>>>>         int                     clk_requests;   /* internal reference counter */
>>>> --
>>>> 1.7.10
>>>>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 14, 2012, 9:19 a.m. UTC | #5
On 14 September 2012 10:25, Girish K S <girish.shivananjappa@linaro.org> wrote:
> On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> Hi Girish,
>>
>> I should also have stated that this patch has not been tested with an
>> eMMC 4.5 device, thus the power off notification is not fully tested.
>> Unfortunate I don't have such a device available right now. What I did
>> test was that patch must not break anything and tested that the
>> suspend/resume sequence is fixed for eMMC with sleep support. I also
>> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>>
>> Are you able to help out in testing with a eMMC 4.5 device with
>> POWER_OFF_NOTIFY support?
> I am also facing the same  problem. The board that i used earlier to
> upstream 4.5 patches is not functioning. Thats the reason for the
> delay in upstreaming or sending the patch. Once i get it repaired i ll
> definitely do it.
> It would be helpful if somebody in the list can do this in the mean time.

Ah, I see.

If not possible to test soon, I anyway think we should go ahead with
this patch, since it fixes the supend/resume sequence for eMMC with
sleep, which to me is far more important right know, it has been
broken for several month now. If there are any issues with power off
notify feature, we can fix that later on. What do you think of that
approach?

Kind regards
Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 14, 2012, 9:41 a.m. UTC | #6
On 14 September 2012 14:49, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 14 September 2012 10:25, Girish K S <girish.shivananjappa@linaro.org> wrote:
>> On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>>> Hi Girish,
>>>
>>> I should also have stated that this patch has not been tested with an
>>> eMMC 4.5 device, thus the power off notification is not fully tested.
>>> Unfortunate I don't have such a device available right now. What I did
>>> test was that patch must not break anything and tested that the
>>> suspend/resume sequence is fixed for eMMC with sleep support. I also
>>> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>>>
>>> Are you able to help out in testing with a eMMC 4.5 device with
>>> POWER_OFF_NOTIFY support?
>> I am also facing the same  problem. The board that i used earlier to
>> upstream 4.5 patches is not functioning. Thats the reason for the
>> delay in upstreaming or sending the patch. Once i get it repaired i ll
>> definitely do it.
>> It would be helpful if somebody in the list can do this in the mean time.
>
> Ah, I see.
>
> If not possible to test soon, I anyway think we should go ahead with
> this patch, since it fixes the supend/resume sequence for eMMC with
> sleep, which to me is far more important right know, it has been
> broken for several month now. If there are any issues with power off
> notify feature, we can fix that later on. What do you think of that
> approach?
OK i do agree with it.
 you can add my signoff or ack for this
>
> Kind regards
> Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Sept. 14, 2012, 2:03 p.m. UTC | #7
On Fri, Sep 14, 2012 at 10:25 AM, Girish K S
<girish.shivananjappa@linaro.org> wrote:
> On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> Hi Girish,
>>
>> I should also have stated that this patch has not been tested with an
>> eMMC 4.5 device, thus the power off notification is not fully tested.
>> Unfortunate I don't have such a device available right now. What I did
>> test was that patch must not break anything and tested that the
>> suspend/resume sequence is fixed for eMMC with sleep support. I also
>> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>>
>> Are you able to help out in testing with a eMMC 4.5 device with
>> POWER_OFF_NOTIFY support?
>
> I am also facing the same  problem. The board that i used earlier to
> upstream 4.5 patches is not functioning. Thats the reason for the
> delay in upstreaming or sending the patch. Once i get it repaired i ll
> definitely do it.
> It would be helpful if somebody in the list can do this in the mean time.

Let's page Arnd, I was under the impression that he has a eMMC 4.5
board so maybe he can test it?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann Sept. 14, 2012, 3:04 p.m. UTC | #8
On Friday 14 September 2012, Linus Walleij wrote:
> On Fri, Sep 14, 2012 at 10:25 AM, Girish K S
> <girish.shivananjappa@linaro.org> wrote:
> > On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >> Hi Girish,
> >>
> >> I should also have stated that this patch has not been tested with an
> >> eMMC 4.5 device, thus the power off notification is not fully tested.
> >> Unfortunate I don't have such a device available right now. What I did
> >> test was that patch must not break anything and tested that the
> >> suspend/resume sequence is fixed for eMMC with sleep support. I also
> >> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
> >>
> >> Are you able to help out in testing with a eMMC 4.5 device with
> >> POWER_OFF_NOTIFY support?
> >
> > I am also facing the same  problem. The board that i used earlier to
> > upstream 4.5 patches is not functioning. Thats the reason for the
> > delay in upstreaming or sending the patch. Once i get it repaired i ll
> > definitely do it.
> > It would be helpful if somebody in the list can do this in the mean time.
> 
> Let's page Arnd, I was under the impression that he has a eMMC 4.5
> board so maybe he can test it?

I have a few eMMC samples but am only using them with my (slow) thinkpad
SD card reader. I also don't know which eMMC-4.5 features they implement,
as some may be early prototypes.

What exactly do you need tested?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 17, 2012, 4:50 a.m. UTC | #9
On 14 September 2012 20:34, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 14 September 2012, Linus Walleij wrote:
>> On Fri, Sep 14, 2012 at 10:25 AM, Girish K S
>> <girish.shivananjappa@linaro.org> wrote:
>> > On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> >> Hi Girish,
>> >>
>> >> I should also have stated that this patch has not been tested with an
>> >> eMMC 4.5 device, thus the power off notification is not fully tested.
>> >> Unfortunate I don't have such a device available right now. What I did
>> >> test was that patch must not break anything and tested that the
>> >> suspend/resume sequence is fixed for eMMC with sleep support. I also
>> >> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>> >>
>> >> Are you able to help out in testing with a eMMC 4.5 device with
>> >> POWER_OFF_NOTIFY support?
>> >
>> > I am also facing the same  problem. The board that i used earlier to
>> > upstream 4.5 patches is not functioning. Thats the reason for the
>> > delay in upstreaming or sending the patch. Once i get it repaired i ll
>> > definitely do it.
>> > It would be helpful if somebody in the list can do this in the mean time.
>>
>> Let's page Arnd, I was under the impression that he has a eMMC 4.5
>> board so maybe he can test it?
>
> I have a few eMMC samples but am only using them with my (slow) thinkpad
> SD card reader. I also don't know which eMMC-4.5 features they implement,
> as some may be early prototypes.
>
> What exactly do you need tested?
Poweroff Notify feature with the above patch in suspend to ram.
>
>         Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 19, 2012, 4:06 p.m. UTC | #10
Hi Chris,

Just pinging you to see if you have an opinion in merging this without
full testing on eMMC4.5 device?

I am kind of eager to fixup the broken suspend for eMMC with sleep,
which this does. :-)

Kind regards
Ulf Hansson

On 17 September 2012 06:50, Girish K S <girish.shivananjappa@linaro.org> wrote:
> On 14 September 2012 20:34, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Friday 14 September 2012, Linus Walleij wrote:
>>> On Fri, Sep 14, 2012 at 10:25 AM, Girish K S
>>> <girish.shivananjappa@linaro.org> wrote:
>>> > On 14 September 2012 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>>> >> Hi Girish,
>>> >>
>>> >> I should also have stated that this patch has not been tested with an
>>> >> eMMC 4.5 device, thus the power off notification is not fully tested.
>>> >> Unfortunate I don't have such a device available right now. What I did
>>> >> test was that patch must not break anything and tested that the
>>> >> suspend/resume sequence is fixed for eMMC with sleep support. I also
>>> >> tested this with MMC_CAP2_POWEROFF_NOTIFY enabled.
>>> >>
>>> >> Are you able to help out in testing with a eMMC 4.5 device with
>>> >> POWER_OFF_NOTIFY support?
>>> >
>>> > I am also facing the same  problem. The board that i used earlier to
>>> > upstream 4.5 patches is not functioning. Thats the reason for the
>>> > delay in upstreaming or sending the patch. Once i get it repaired i ll
>>> > definitely do it.
>>> > It would be helpful if somebody in the list can do this in the mean time.
>>>
>>> Let's page Arnd, I was under the impression that he has a eMMC 4.5
>>> board so maybe he can test it?
>>
>> I have a few eMMC samples but am only using them with my (slow) thinkpad
>> SD card reader. I also don't know which eMMC-4.5 features they implement,
>> as some may be early prototypes.
>>
>> What exactly do you need tested?
> Poweroff Notify feature with the above patch in suspend to ram.
>>
>>         Arnd
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chris Ball Sept. 20, 2012, 1:35 a.m. UTC | #11
Hi,

On Wed, Sep 19 2012, Ulf Hansson wrote:
> Just pinging you to see if you have an opinion in merging this without
> full testing on eMMC4.5 device?
>
> I am kind of eager to fixup the broken suspend for eMMC with sleep,
> which this does. :-)

Well, we don't need "full testing", but I don't think it's a good idea
to merge this without any testing at all on eMMC 4.5.  Might as well
just wait a little longer and send it as a 3.7 fix with a stable@ tag?
Do we have any ETA on when someone will be able to test?

Thanks,

- Chris.
tlinder Sept. 20, 2012, 7:58 a.m. UTC | #12
> >
> > Let's page Arnd, I was under the impression that he has a eMMC 4.5
> > board so maybe he can test it?
> 
> I have a few eMMC samples but am only using them with my (slow) thinkpad
> SD card reader. I also don't know which eMMC-4.5 features they implement,
> as some may be early prototypes.
> 
> What exactly do you need tested?
> 
> 	Arnd
> --

Hi 

We have eMMC4.5 board and can help with the testing. 
Are there other patches besides this one I should take in?

Thanks,
Tanya Brokhman
---
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 20, 2012, 3:39 p.m. UTC | #13
Hi Tanya,

On 20 September 2012 09:58, Tanya Brokhman <tlinder@codeaurora.org> wrote:
>> >
>> > Let's page Arnd, I was under the impression that he has a eMMC 4.5
>> > board so maybe he can test it?
>>
>> I have a few eMMC samples but am only using them with my (slow) thinkpad
>> SD card reader. I also don't know which eMMC-4.5 features they implement,
>> as some may be early prototypes.
>>
>> What exactly do you need tested?
>>
>>       Arnd
>> --
>
> Hi
>
> We have eMMC4.5 board and can help with the testing.
> Are there other patches besides this one I should take in?
>

Nope, this is the only one needed.
Thanks a lot for helping out!

Kind regards
Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
tlinder Sept. 20, 2012, 5:56 p.m. UTC | #14
Hi Ulf

> 
> Nope, this is the only one needed.
> Thanks a lot for helping out!
> 
Np. 
I understand this is a bit urgent. Will do my best to speed it up...

Thanks,
Tanya Brokhman
---
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 25, 2012, 9:19 a.m. UTC | #15
On 20 September 2012 03:35, Chris Ball <cjb@laptop.org> wrote:
> Hi,
>
> On Wed, Sep 19 2012, Ulf Hansson wrote:
>> Just pinging you to see if you have an opinion in merging this without
>> full testing on eMMC4.5 device?
>>
>> I am kind of eager to fixup the broken suspend for eMMC with sleep,
>> which this does. :-)
>
> Well, we don't need "full testing", but I don't think it's a good idea
> to merge this without any testing at all on eMMC 4.5.  Might as well
> just wait a little longer and send it as a 3.7 fix with a stable@ tag?
> Do we have any ETA on when someone will be able to test?
>

Unfortunately still no progress for testing for eMMC 4.5. Sorry for that.

Tanya Brokhman and possibly Arnd Bergman is trying to help out, which
is really great. Although I have yet not received an answer. Hopefully
soon. :-)
My self is trying to get a hold of an eMMC 4.5 device, so I can do the
test myself.

I am not sure how long we should wait for eMMC 4.5 to be tested. Until
testing is resolved the eMMC 4.3 and onwards are having a broken
suspend sequence using SLEEP, which I think is really bad. This also
includes eMMC4.5 devices, for which hosts is not using the new
POWER_OFF _NOTIFY CAP.

Kind regards
Ulf Hansson

> Thanks,
>
> - Chris.
> --
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Sept. 26, 2012, 11:19 a.m. UTC | #16
On Tue, Sep 25, 2012 at 11:19 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:

> I am not sure how long we should wait for eMMC 4.5 to be tested. Until
> testing is resolved the eMMC 4.3 and onwards are having a broken
> suspend sequence using SLEEP, which I think is really bad.

To me this sounds like a case for even adding Cc: stable@kernel.org
to this when merged.

Breaking existing devices is worse than breaking future devices, so:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
tlinder Sept. 27, 2012, 11:27 a.m. UTC | #17
Hi Ulf

We've tested your change. It seems to be working fine. We mainly focused on
testing stability and that the performance wasn't decreased. All tests
passed.
As far as performance improvement: it wasn't affected because of BKOPs
feature.
Please let me know if there is any specific test scenario you want me to
run.

(Sorry it took me some time to get back to you. It's holiday season in
Israel)

Thanks,
Tanya Brokhman
---
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson@linaro.org]
> Sent: Thursday, September 20, 2012 6:40 PM
> To: Tanya Brokhman
> Cc: Arnd Bergmann; Linus Walleij; Girish K S; linux-mmc@vger.kernel.org;
> Chris Ball; Per Forlin; Johan Rudholm; Lee Jones; Saugata Das; Asutosh Das
> Subject: Re: [PATCH] mmc: Fixup broken suspend and eMMC4.5 power off
> notify
> 
> Hi Tanya,
> 
> On 20 September 2012 09:58, Tanya Brokhman <tlinder@codeaurora.org>
> wrote:
> >> >
> >> > Let's page Arnd, I was under the impression that he has a eMMC 4.5
> >> > board so maybe he can test it?
> >>
> >> I have a few eMMC samples but am only using them with my (slow)
> >> thinkpad SD card reader. I also don't know which eMMC-4.5 features
> >> they implement, as some may be early prototypes.
> >>
> >> What exactly do you need tested?
> >>
> >>       Arnd
> >> --
> >
> > Hi
> >
> > We have eMMC4.5 board and can help with the testing.
> > Are there other patches besides this one I should take in?
> >
> 
> Nope, this is the only one needed.
> Thanks a lot for helping out!
> 
> Kind regards
> Ulf Hansson

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Sept. 27, 2012, 11:45 a.m. UTC | #18
Hi Tanya,

Thanks a lot for helping out!!!

Testing suspend to ram, and then resuming back again is the key use
case to test.

Kind regards
Ulf Hansson

On 27 September 2012 13:27, Tanya Brokhman <tlinder@codeaurora.org> wrote:
> Hi Ulf
>
> We've tested your change. It seems to be working fine. We mainly focused on
> testing stability and that the performance wasn't decreased. All tests
> passed.
> As far as performance improvement: it wasn't affected because of BKOPs
> feature.
> Please let me know if there is any specific test scenario you want me to
> run.
>
> (Sorry it took me some time to get back to you. It's holiday season in
> Israel)
>
> Thanks,
> Tanya Brokhman
> ---
> QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
>
>> -----Original Message-----
>> From: Ulf Hansson [mailto:ulf.hansson@linaro.org]
>> Sent: Thursday, September 20, 2012 6:40 PM
>> To: Tanya Brokhman
>> Cc: Arnd Bergmann; Linus Walleij; Girish K S; linux-mmc@vger.kernel.org;
>> Chris Ball; Per Forlin; Johan Rudholm; Lee Jones; Saugata Das; Asutosh Das
>> Subject: Re: [PATCH] mmc: Fixup broken suspend and eMMC4.5 power off
>> notify
>>
>> Hi Tanya,
>>
>> On 20 September 2012 09:58, Tanya Brokhman <tlinder@codeaurora.org>
>> wrote:
>> >> >
>> >> > Let's page Arnd, I was under the impression that he has a eMMC 4.5
>> >> > board so maybe he can test it?
>> >>
>> >> I have a few eMMC samples but am only using them with my (slow)
>> >> thinkpad SD card reader. I also don't know which eMMC-4.5 features
>> >> they implement, as some may be early prototypes.
>> >>
>> >> What exactly do you need tested?
>> >>
>> >>       Arnd
>> >> --
>> >
>> > Hi
>> >
>> > We have eMMC4.5 board and can help with the testing.
>> > Are there other patches besides this one I should take in?
>> >
>>
>> Nope, this is the only one needed.
>> Thanks a lot for helping out!
>>
>> Kind regards
>> Ulf Hansson
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
tlinder Sept. 30, 2012, 6:48 a.m. UTC | #19
Hi Ulf,

> 
> Hi Tanya,
> 
> Thanks a lot for helping out!!!

NP. 
> 
> Testing suspend to ram, and then resuming back again is the key use case
to
> test.


Is there a special scenario to trigger suspend or just leaving the system
idle? I did that. Added prints in the code to verify that the PON was sent
to the card.... It feels a bit superficial to me that's why I'm asking if
there is a specific scenario I can try.
Other than that, as I already mentioned we ran our test suit that includes
various user-use cases such as playing a game, reading a web page, email
etc. And of course I tried lmdd both ways.

> 
> Kind regards
> Ulf Hansson
> 


Thanks,
Tanya Brokhman
---
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 30, 2012, 7:07 a.m. UTC | #20
On 30 September 2012 15:48, Tanya Brokhman <tlinder@codeaurora.org> wrote:
> Hi Ulf,
>
>>
>> Hi Tanya,
>>
>> Thanks a lot for helping out!!!
>
> NP.
>>
>> Testing suspend to ram, and then resuming back again is the key use case
> to
>> test.
>
>
> Is there a special scenario to trigger suspend or just leaving the system
> idle? I did that. Added prints in the code to verify that the PON was sent
> to the card.... It feels a bit superficial to me that's why I'm asking if
> there is a specific scenario I can try.
> Other than that, as I already mentioned we ran our test suit that includes
> various user-use cases such as playing a game, reading a web page, email
> etc. And of course I tried lmdd both ways.
from command prompt you can suspend by forcing the string mem to state
variable as given below
 echo mem > sys/power/state
If sysfs is not mounted mount it(mount -t sysfs sys /sys) before
running the above command.

If your board is configured for an external interrupt as a wakeup
source (on my board it is the keypad)
press the key for resume.

If no External interrupt wakeup source is availabe, and if the SOc has
a RTC, it can be used for resume purpose as below

echo 0 > /sys/class/rtc/rtcN/wakealarm  (reset old value)
echo 10 > /sys/class/rtc/rtcN/wakealarm (set new value)

After  the specified above seconds the system will resume

>
>>
>> Kind regards
>> Ulf Hansson
>>
>
>
> Thanks,
> Tanya Brokhman
> ---
> QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Sept. 30, 2012, 7:09 a.m. UTC | #21
On 30 September 2012 16:07, Girish K S <girish.shivananjappa@linaro.org> wrote:
> On 30 September 2012 15:48, Tanya Brokhman <tlinder@codeaurora.org> wrote:
>> Hi Ulf,
>>
>>>
>>> Hi Tanya,
>>>
>>> Thanks a lot for helping out!!!
>>
>> NP.
>>>
>>> Testing suspend to ram, and then resuming back again is the key use case
>> to
>>> test.
>>
>>
>> Is there a special scenario to trigger suspend or just leaving the system
>> idle? I did that. Added prints in the code to verify that the PON was sent
>> to the card.... It feels a bit superficial to me that's why I'm asking if
>> there is a specific scenario I can try.
>> Other than that, as I already mentioned we ran our test suit that includes
>> various user-use cases such as playing a game, reading a web page, email
>> etc. And of course I tried lmdd both ways.
> from command prompt you can suspend by forcing the string mem to state
> variable as given below
>  echo mem > sys/power/state
> If sysfs is not mounted mount it(mount -t sysfs sys /sys) before
> running the above command.
>
> If your board is configured for an external interrupt as a wakeup
> source (on my board it is the keypad)
> press the key for resume.
>
> If no External interrupt wakeup source is availabe, and if the SOc has
> a RTC, it can be used for resume purpose as below
>
> echo 0 > /sys/class/rtc/rtcN/wakealarm  (reset old value)
> echo 10 > /sys/class/rtc/rtcN/wakealarm (set new value)
>
> After  the specified above seconds the system will resume
If you are using rtc as wakeup source.

first configure rtc and then run echo mem > sys/power/state
>
>>
>>>
>>> Kind regards
>>> Ulf Hansson
>>>
>>
>>
>> Thanks,
>> Tanya Brokhman
>> ---
>> QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
>> of Code Aurora Forum, hosted by The Linux Foundation
>>
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chris Ball Oct. 3, 2012, 9:03 p.m. UTC | #22
Hi Ulf,

On Thu, Sep 13 2012, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> This patch fixup the broken suspend sequence for eMMC
> with sleep support. Additionally it reworks the eMMC4.5
> Power Off Notification feature so it fits together with
> the existing sleep feature.
>
> The CMD0 based re-initialization of the eMMC at resume
> is re-introduced to maintain compatiblity for devices
> using sleep.
>
> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
> Power Off Notification feature. We might be able to
> remove this cap later on, if we think that Power Off
> Notification always is preferred over sleep, even if the
> host is not able to cut the eMMC VCCQ power.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Saugata Das <saugata.das@linaro.org>
> CC: Girish K S <girish.shivananjappa@linaro.org>
> CC: Asutosh Das <asutoshd@codeaurora.org>

I gave this patch a try on a board with an eMMC 4.41, but it didn't
resolve the crash that I see.  After applying the patch, I still see:

[   25.191917] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
[   25.319299] mmc1: Got data interrupt 0x00000002 even though no data operation was in progress.
[   25.335054] PM: Device d4281000.sdhci failed to suspend: error -110
[   25.341461] PM: Some devices failed to suspend

and the suspend aborts.  If I modify mmc_card_can_sleep() to always
return false, the suspend completes without errors, so I know that
something in the sleep code is responsible for my crash.

Any suggestions?  Perhaps it's a different bug in the eMMC sleep code.

Thanks,

- Chris.
Ulf Hansson Oct. 4, 2012, 11:46 a.m. UTC | #23
Hi Chris,

On 3 October 2012 23:03, Chris Ball <cjb@laptop.org> wrote:
> Hi Ulf,
>
> On Thu, Sep 13 2012, Ulf Hansson wrote:
>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>
>> This patch fixup the broken suspend sequence for eMMC
>> with sleep support. Additionally it reworks the eMMC4.5
>> Power Off Notification feature so it fits together with
>> the existing sleep feature.
>>
>> The CMD0 based re-initialization of the eMMC at resume
>> is re-introduced to maintain compatiblity for devices
>> using sleep.
>>
>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>> Power Off Notification feature. We might be able to
>> remove this cap later on, if we think that Power Off
>> Notification always is preferred over sleep, even if the
>> host is not able to cut the eMMC VCCQ power.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>> CC: Girish K S <girish.shivananjappa@linaro.org>
>> CC: Asutosh Das <asutoshd@codeaurora.org>
>
> I gave this patch a try on a board with an eMMC 4.41, but it didn't
> resolve the crash that I see.  After applying the patch, I still see:
>
> [   25.191917] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
> [   25.319299] mmc1: Got data interrupt 0x00000002 even though no data operation was in progress.
> [   25.335054] PM: Device d4281000.sdhci failed to suspend: error -110
> [   25.341461] PM: Some devices failed to suspend
>
> and the suspend aborts.  If I modify mmc_card_can_sleep() to always
> return false, the suspend completes without errors, so I know that
> something in the sleep code is responsible for my crash.

This patch restores the sequence for how the sleep sequence is
executed, before the poweroff notify patches was merged at all.
So in principle I guess the problem for sdhci has been there for quite
a while, unless some patch in the sdhci driver has screwed something
up recently.

>
> Any suggestions?  Perhaps it's a different bug in the eMMC sleep code.

Well, actually there is not so much that can be wrong in the sleep
code in the protocol layer. I believe we need to debug the sdhci
driver, to see what happens during the suspend operation instead.

The sleep code from the protocol layer is requesting sdhci to run a
request (sleep cmd and "deselect" cmd). This request is not data
requests but cmd requests. Due to the prints from you log it indicates
that sdhci believes that there are an ongoing data request to handle.
This is not the case, so I think the sdhci has screwed up something.

Although, I am not an sdhci expert, so just guessing. :-)

Kind regards
Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S Oct. 4, 2012, 1:11 p.m. UTC | #24
On 4 October 2012 20:46, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> Hi Chris,
>
> On 3 October 2012 23:03, Chris Ball <cjb@laptop.org> wrote:
>> Hi Ulf,
>>
>> On Thu, Sep 13 2012, Ulf Hansson wrote:
>>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>>
>>> This patch fixup the broken suspend sequence for eMMC
>>> with sleep support. Additionally it reworks the eMMC4.5
>>> Power Off Notification feature so it fits together with
>>> the existing sleep feature.
>>>
>>> The CMD0 based re-initialization of the eMMC at resume
>>> is re-introduced to maintain compatiblity for devices
>>> using sleep.
>>>
>>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>>> Power Off Notification feature. We might be able to
>>> remove this cap later on, if we think that Power Off
>>> Notification always is preferred over sleep, even if the
>>> host is not able to cut the eMMC VCCQ power.
>>>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>>> CC: Girish K S <girish.shivananjappa@linaro.org>
>>> CC: Asutosh Das <asutoshd@codeaurora.org>
>>
>> I gave this patch a try on a board with an eMMC 4.41, but it didn't
>> resolve the crash that I see.  After applying the patch, I still see:
>>
>> [   25.191917] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
>> [   25.319299] mmc1: Got data interrupt 0x00000002 even though no data operation was in progress.
(Just a guess) for non-dt case just check in the machine fiile whether
the correct platform device is passed. i mean for mmc0 channel devic0
and for mmc1 channel its device1. In my case i had duplicated device0
for both channels and had seen such log.
>> [   25.335054] PM: Device d4281000.sdhci failed to suspend: error -110
>> [   25.341461] PM: Some devices failed to suspend
>>
>> and the suspend aborts.  If I modify mmc_card_can_sleep() to always
>> return false, the suspend completes without errors, so I know that
>> something in the sleep code is responsible for my crash.
>
> This patch restores the sequence for how the sleep sequence is
> executed, before the poweroff notify patches was merged at all.
> So in principle I guess the problem for sdhci has been there for quite
> a while, unless some patch in the sdhci driver has screwed something
> up recently.
>
>>
>> Any suggestions?  Perhaps it's a different bug in the eMMC sleep code.
>
> Well, actually there is not so much that can be wrong in the sleep
> code in the protocol layer. I believe we need to debug the sdhci
> driver, to see what happens during the suspend operation instead.
>
> The sleep code from the protocol layer is requesting sdhci to run a
> request (sleep cmd and "deselect" cmd). This request is not data
> requests but cmd requests. Due to the prints from you log it indicates
> that sdhci believes that there are an ongoing data request to handle.
> This is not the case, so I think the sdhci has screwed up something.
>
> Although, I am not an sdhci expert, so just guessing. :-)
>
> Kind regards
> Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chris Ball Oct. 5, 2012, 4:50 p.m. UTC | #25
Hi Ulf,

On Thu, Sep 13 2012, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> This patch fixup the broken suspend sequence for eMMC
> with sleep support. Additionally it reworks the eMMC4.5
> Power Off Notification feature so it fits together with
> the existing sleep feature.
>
> The CMD0 based re-initialization of the eMMC at resume
> is re-introduced to maintain compatiblity for devices
> using sleep.
>
> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
> Power Off Notification feature. We might be able to
> remove this cap later on, if we think that Power Off
> Notification always is preferred over sleep, even if the
> host is not able to cut the eMMC VCCQ power.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Saugata Das <saugata.das@linaro.org>
> CC: Girish K S <girish.shivananjappa@linaro.org>
> CC: Asutosh Das <asutoshd@codeaurora.org>

Thanks, I've merged this now.  I've got an eMMC 4.5 sample on the way
to me, I'll help out with making sure that suspend/resume is tested.

- Chris.
Ulf Hansson Oct. 8, 2012, 7:31 a.m. UTC | #26
On 5 October 2012 18:50, Chris Ball <cjb@laptop.org> wrote:
> Hi Ulf,
>
> On Thu, Sep 13 2012, Ulf Hansson wrote:
>> From: Ulf Hansson <ulf.hansson@linaro.org>
>>
>> This patch fixup the broken suspend sequence for eMMC
>> with sleep support. Additionally it reworks the eMMC4.5
>> Power Off Notification feature so it fits together with
>> the existing sleep feature.
>>
>> The CMD0 based re-initialization of the eMMC at resume
>> is re-introduced to maintain compatiblity for devices
>> using sleep.
>>
>> A host shall use MMC_CAP2_POWEROFF_NOTIFY to enable the
>> Power Off Notification feature. We might be able to
>> remove this cap later on, if we think that Power Off
>> Notification always is preferred over sleep, even if the
>> host is not able to cut the eMMC VCCQ power.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Saugata Das <saugata.das@linaro.org>
>> CC: Girish K S <girish.shivananjappa@linaro.org>
>> CC: Asutosh Das <asutoshd@codeaurora.org>
>
> Thanks, I've merged this now.  I've got an eMMC 4.5 sample on the way
> to me, I'll help out with making sure that suspend/resume is tested.
>
> - Chris.
> --
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child

Sounds great! Thanks for helping out! Juts ping me if you need some
further assistance around this.

Myself is also waiting for a eMMC 4.5 device, should probably show up
this week. I will try to test it as soon as I can.

Kind regards
Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index af2c4d2..2765097 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1134,48 +1134,6 @@  void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 	mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-	struct mmc_card *card;
-	unsigned int timeout;
-	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-	int err = 0;
-
-	card = host->card;
-	mmc_claim_host(host);
-
-	/*
-	 * Send power notify command only if card
-	 * is mmc and notify state is powered ON
-	 */
-	if (card && mmc_card_mmc(card) &&
-	    (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-			notify_type = EXT_CSD_POWER_OFF_SHORT;
-			timeout = card->ext_csd.generic_cmd6_time;
-			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-		} else {
-			notify_type = EXT_CSD_POWER_OFF_LONG;
-			timeout = card->ext_csd.power_off_longtime;
-			card->poweroff_notify_state = MMC_POWEROFF_LONG;
-		}
-
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_POWER_OFF_NOTIFICATION,
-				 notify_type, timeout);
-
-		if (err && err != -EBADMSG)
-			pr_err("Device failed to respond within %d poweroff "
-			       "time. Forcefully powering down the device\n",
-			       timeout);
-
-		/* Set the card state to no notification after the poweroff */
-		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
-	}
-	mmc_release_host(host);
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1238,8 +1196,6 @@  static void mmc_power_up(struct mmc_host *host)
 
 void mmc_power_off(struct mmc_host *host)
 {
-	int err = 0;
-
 	if (host->ios.power_mode == MMC_POWER_OFF)
 		return;
 
@@ -1248,22 +1204,6 @@  void mmc_power_off(struct mmc_host *host)
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
-	/*
-	 * For eMMC 4.5 device send AWAKE command before
-	 * POWER_OFF_NOTIFY command, because in sleep state
-	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
-	 */
-	if (host->card && mmc_card_is_sleep(host->card) &&
-	    host->bus_ops->resume) {
-		err = host->bus_ops->resume(host);
-
-		if (!err)
-			mmc_poweroff_notify(host);
-		else
-			pr_warning("%s: error %d during resume "
-				   "(continue with poweroff sequence)\n",
-				   mmc_hostname(host), err);
-	}
 
 	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
@@ -2425,7 +2365,6 @@  int mmc_pm_notify(struct notifier_block *notify_block,
 
 		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 1;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
 		spin_unlock_irqrestore(&host->lock, flags);
 		cancel_delayed_work_sync(&host->detect);
 
@@ -2449,7 +2388,6 @@  int mmc_pm_notify(struct notifier_block *notify_block,
 
 		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 0;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
 		spin_unlock_irqrestore(&host->lock, flags);
 		mmc_detect_change(host, 0);
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 396b258..9607c35 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -996,7 +996,7 @@  static int mmc_init_card(struct mmc_host *host, u32 ocr,
 		 * so check for success and update the flag
 		 */
 		if (!err)
-			card->poweroff_notify_state = MMC_POWERED_ON;
+			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
 	}
 
 	/*
@@ -1262,6 +1262,35 @@  err:
 	return err;
 }
 
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+	return card &&
+		mmc_card_mmc(card) &&
+		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+	unsigned int timeout = card->ext_csd.generic_cmd6_time;
+	int err;
+
+	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+	if (notify_type == EXT_CSD_POWER_OFF_LONG)
+		timeout = card->ext_csd.power_off_longtime;
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_POWER_OFF_NOTIFICATION,
+			 notify_type, timeout);
+	if (err)
+		pr_err("%s: Power Off Notification timed out, %u\n",
+		       mmc_hostname(card->host), timeout);
+
+	/* Disable the power off notification after the switch operation. */
+	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+	return err;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -1322,11 +1351,11 @@  static int mmc_suspend(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host)) {
+	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);
-		if (!err)
-			mmc_card_set_sleep(host->card);
-	} else if (!mmc_host_is_spi(host))
+	else if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_release_host(host);
@@ -1348,11 +1377,7 @@  static int mmc_resume(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_is_sleep(host->card)) {
-		err = mmc_card_awake(host);
-		mmc_card_clr_sleep(host->card);
-	} else
-		err = mmc_init_card(host, host->ocr, host->card);
+	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
@@ -1363,7 +1388,6 @@  static int mmc_power_restore(struct mmc_host *host)
 	int ret;
 
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 36f98c0..7ef4f8a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1810,11 +1810,6 @@  static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 	if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	if (host->pdata->blk_settings) {
 		mmc->max_segs = host->pdata->blk_settings->max_segs;
 		mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d98b199..6035094 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2878,15 +2878,6 @@  int sdhci_add_host(struct sdhci_host *host)
 	if (caps[1] & SDHCI_DRIVER_TYPE_D)
 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
 
-	/*
-	 * If Power Off Notify capability is enabled by the host,
-	 * set notify to short power off notify timeout value.
-	 */
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	/* Initial value for re-tuning timer count */
 	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
 			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4b27f9f..90f655b 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -57,6 +57,7 @@  struct mmc_ext_csd {
 	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		generic_cmd6_time;	/* Units: 10ms */
 	unsigned int            power_off_longtime;     /* Units: ms */
+	u8			power_off_notification;	/* state */
 	unsigned int		hs_max_dtr;
 #define MMC_HIGH_26_MAX_DTR	26000000
 #define MMC_HIGH_52_MAX_DTR	52000000
@@ -225,7 +226,6 @@  struct mmc_card {
 #define MMC_CARD_SDXC		(1<<6)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
-#define MMC_STATE_SLEEP		(1<<9)		/* card is in sleep state */
 	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 */
@@ -241,11 +241,6 @@  struct mmc_card {
 #define MMC_QUIRK_LONG_READ_TIME (1<<9)		/* Data read time > CSD says */
 #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)	/* Skip secure for erase/trim */
 						/* byte mode */
-	unsigned int    poweroff_notify_state;	/* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION	0
-#define MMC_POWERED_ON			1
-#define MMC_POWEROFF_SHORT		2
-#define MMC_POWEROFF_LONG		3
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
@@ -392,7 +387,6 @@  static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_sd_card_uhs(c)	((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_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)
@@ -404,9 +398,7 @@  static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #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_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
 
-#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index d5d9bd4..7abb0e1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -259,10 +259,6 @@  struct mmc_host {
 #define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	/* Write-protect signal active high */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
-	unsigned int        power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE		0
-#define MMC_HOST_PW_NOTIFY_SHORT	1
-#define MMC_HOST_PW_NOTIFY_LONG		2
 
 #ifdef CONFIG_MMC_CLKGATE
 	int			clk_requests;	/* internal reference counter */