All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulf Hansson <ulf.hansson@linaro.org>
To: Saugata Das <saugata.das@stericsson.com>
Cc: linux-mmc@vger.kernel.org, patches@linaro.org,
	ulf.hansson@stericsson.com, venkat@linaro.org,
	Saugata Das <saugata.das@linaro.org>,
	Girish K S <girish.shivananjappa@linaro.org>,
	Asutosh Das <asutoshd@codeaurora.org>
Subject: Re: [PATCH] MMC-4.5 Power OFF Notify Rework
Date: Mon, 20 Aug 2012 16:13:11 +0200	[thread overview]
Message-ID: <CAPDyKFq3q1+XOrx4RWrM6ZCOycgTMr7tSLHCCwLtuJarQ-uzoA@mail.gmail.com> (raw)
In-Reply-To: <1340960593-24158-1-git-send-email-saugata.das@stericsson.com>

Hi Saugata,

Sorry for a very late reply, I just came back from vacation.

Anyway, this patch looks good to me. You have my Ack.

Kind regards
Ulf Hansson

On 29 June 2012 11:03, Saugata Das <saugata.das@stericsson.com> wrote:
> From: Saugata Das <saugata.das@linaro.org>
>
> This is a rework of the existing POWER OFF NOTIFY patch. The CMD0 based
> reinitialization of the eMMC during mmc_resume is introduced back. Function
> poweroff_notify has been added as a bus_ops (as desired by the reviewers on
> a previous version of the patch). Removed the configuration of notify type
> ("power_notify_type") from the host drivers. This is now passed as parameter
> to poweroff_notify.
>
> Signed-off-by: Saugata Das <saugata.das@linaro.org>
> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
> Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
> ---
>  drivers/mmc/core/core.c   |  108 ++++++++++++++++++--------------------------
>  drivers/mmc/core/core.h   |    1 +
>  drivers/mmc/core/mmc.c    |   44 +++++++++++++++---
>  drivers/mmc/host/dw_mmc.c |    5 --
>  drivers/mmc/host/sdhci.c  |    9 ----
>  include/linux/mmc/card.h  |    5 +-
>  include/linux/mmc/core.h  |    1 +
>  include/linux/mmc/host.h  |    4 --
>  include/linux/mmc/mmc.h   |    7 +++
>  9 files changed, 92 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 0b6141d..fe616b9 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1101,48 +1101,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.
> @@ -1202,8 +1160,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;
>
> @@ -1212,22 +1168,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
> @@ -1726,6 +1666,15 @@ int mmc_can_secure_erase_trim(struct mmc_card *card)
>  }
>  EXPORT_SYMBOL(mmc_can_secure_erase_trim);
>
> +int mmc_can_poweroff_notify(const struct mmc_card *card)
> +{
> +       return card &&
> +               mmc_card_mmc(card) &&
> +               card->host->bus_ops->poweroff_notify &&
> +               (card->poweroff_notify_state == MMC_POWERED_ON);
> +}
> +EXPORT_SYMBOL(mmc_can_poweroff_notify);
> +
>  int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
>                             unsigned int nr)
>  {
> @@ -2096,6 +2045,15 @@ void mmc_stop_host(struct mmc_host *host)
>
>         mmc_bus_get(host);
>         if (host->bus_ops && !host->bus_dead) {
> +               mmc_claim_host(host);
> +               if (mmc_can_poweroff_notify(host->card)) {
> +                       int err = host->bus_ops->poweroff_notify(host,
> +                                               MMC_PW_OFF_NOTIFY_LONG);
> +                       if (err)
> +                               pr_info("%s: error [%d] in poweroff notify\n",
> +                                       mmc_hostname(host), err);
> +               }
> +               mmc_release_host(host);
>                 /* Calling bus_ops->remove() with a claimed host can deadlock */
>                 if (host->bus_ops->remove)
>                         host->bus_ops->remove(host);
> @@ -2131,6 +2089,15 @@ int mmc_power_save_host(struct mmc_host *host)
>
>         if (host->bus_ops->power_save)
>                 ret = host->bus_ops->power_save(host);
> +       mmc_claim_host(host);
> +       if (mmc_can_poweroff_notify(host->card)) {
> +               int err = host->bus_ops->poweroff_notify(host,
> +                                       MMC_PW_OFF_NOTIFY_SHORT);
> +               if (err)
> +                       pr_info("%s: error [%d] in poweroff notify\n",
> +                               mmc_hostname(host), err);
> +       }
> +       mmc_release_host(host);
>
>         mmc_bus_put(host);
>
> @@ -2173,8 +2140,11 @@ int mmc_card_awake(struct mmc_host *host)
>
>         mmc_bus_get(host);
>
> -       if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
> +       if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) {
>                 err = host->bus_ops->awake(host);
> +               if (!err)
> +                       mmc_card_clr_sleep(host->card);
> +       }
>
>         mmc_bus_put(host);
>
> @@ -2191,8 +2161,11 @@ int mmc_card_sleep(struct mmc_host *host)
>
>         mmc_bus_get(host);
>
> -       if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
> +       if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) {
>                 err = host->bus_ops->sleep(host);
> +               if (!err)
> +                       mmc_card_set_sleep(host->card);
> +       }
>
>         mmc_bus_put(host);
>
> @@ -2385,12 +2358,20 @@ 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);
>
>                 if (!host->bus_ops || host->bus_ops->suspend)
>                         break;
> +               mmc_claim_host(host);
> +               if (mmc_can_poweroff_notify(host->card)) {
> +                       int err = host->bus_ops->poweroff_notify(host,
> +                                               MMC_PW_OFF_NOTIFY_SHORT);
> +                       if (err)
> +                               pr_info("%s: error [%d] in poweroff notify\n",
> +                                       mmc_hostname(host), err);
> +               }
> +               mmc_release_host(host);
>
>                 /* Calling bus_ops->remove() with a claimed host can deadlock */
>                 if (host->bus_ops->remove)
> @@ -2409,7 +2390,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/core.h b/drivers/mmc/core/core.h
> index 3bdafbc..15b918d 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -25,6 +25,7 @@ struct mmc_bus_ops {
>         int (*power_save)(struct mmc_host *);
>         int (*power_restore)(struct mmc_host *);
>         int (*alive)(struct mmc_host *);
> +       int (*poweroff_notify)(struct mmc_host *, int notify);
>  };
>
>  void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 2f0e11c..8684577 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1259,6 +1259,40 @@ err:
>         return err;
>  }
>
> +static int mmc_poweroff_notify(struct mmc_host *host, int notify)
> +{
> +       struct mmc_card *card;
> +       unsigned int timeout;
> +       unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
> +       int err;
> +
> +       card = host->card;
> +
> +       if (notify == MMC_PW_OFF_NOTIFY_SHORT) {
> +               notify_type = EXT_CSD_POWER_OFF_SHORT;
> +               timeout = card->ext_csd.generic_cmd6_time;
> +       } else if (notify == MMC_PW_OFF_NOTIFY_LONG) {
> +               notify_type = EXT_CSD_POWER_OFF_LONG;
> +               timeout = card->ext_csd.power_off_longtime;
> +       } else {
> +               pr_err("%s: mmc_poweroff_notify called "
> +                       "with notify type %d\n", mmc_hostname(host), notify);
> +               return -EINVAL;
> +       }
> +
> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> +                        EXT_CSD_POWER_OFF_NOTIFICATION,
> +                        notify_type, timeout);
> +
> +       if (err)
> +               pr_err("%s: Device failed to respond within %d "
> +                      "poweroff timeout.\n", mmc_hostname(host), timeout);
> +       else
> +               card->poweroff_notify_state =
> +                                       MMC_NO_POWER_NOTIFICATION;
> +
> +       return err;
> +}
>  /*
>   * Host is being removed. Free up the current card.
>   */
> @@ -1321,8 +1355,6 @@ static int mmc_suspend(struct mmc_host *host)
>         mmc_claim_host(host);
>         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))
>                 mmc_deselect_cards(host);
>         host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
> @@ -1345,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;
> @@ -1407,6 +1435,7 @@ static const struct mmc_bus_ops mmc_ops = {
>         .resume = NULL,
>         .power_restore = mmc_power_restore,
>         .alive = mmc_alive,
> +       .poweroff_notify = mmc_poweroff_notify,
>  };
>
>  static const struct mmc_bus_ops mmc_ops_unsafe = {
> @@ -1418,6 +1447,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = {
>         .resume = mmc_resume,
>         .power_restore = mmc_power_restore,
>         .alive = mmc_alive,
> +       .poweroff_notify = mmc_poweroff_notify,
>  };
>
>  static void mmc_attach_bus_ops(struct mmc_host *host)
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 1532357..463130f 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1788,11 +1788,6 @@ static int __init 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 e626732..c0a5a91 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2812,15 +2812,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 d76513b..040eec4 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -239,11 +239,10 @@ struct mmc_card {
>  #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8)  /* Avoid sending 512 bytes in */
>  #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
>                                                 /* byte mode */
> -       unsigned int    poweroff_notify_state;  /* eMMC4.5 notify feature */
> +       unsigned int            poweroff_notify_state; /* MMC-4.5 poweroff
> +                                                       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 */
> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
> index 1b431c7..54894d6 100644
> --- a/include/linux/mmc/core.h
> +++ b/include/linux/mmc/core.h
> @@ -161,6 +161,7 @@ extern int mmc_can_trim(struct mmc_card *card);
>  extern int mmc_can_discard(struct mmc_card *card);
>  extern int mmc_can_sanitize(struct mmc_card *card);
>  extern int mmc_can_secure_erase_trim(struct mmc_card *card);
> +extern int mmc_can_poweroff_notify(const struct mmc_card *card);
>  extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
>                                    unsigned int nr);
>  extern unsigned int mmc_calc_max_discard(struct mmc_card *card);
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 0707d22..b685dff 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -240,10 +240,6 @@ struct mmc_host {
>  #define MMC_CAP2_HC_ERASE_SZ   (1 << 9)        /* High-capacity erase size */
>
>         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 */
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> index d425cab..b11876b 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -386,4 +386,11 @@ struct _mmc_csd {
>  #define MMC_SWITCH_MODE_CLEAR_BITS     0x02    /* Clear bits which are 1 in value */
>  #define MMC_SWITCH_MODE_WRITE_BYTE     0x03    /* Set target to value */
>
> +/*
> + * MMC Poweroff Notify types
> + */
> +#define MMC_PW_OFF_NOTIFY_NONE         0
> +#define MMC_PW_OFF_NOTIFY_SHORT                1
> +#define MMC_PW_OFF_NOTIFY_LONG         2
> +
>  #endif /* LINUX_MMC_MMC_H */
> --
> 1.7.4.3
>
> --
> 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

  reply	other threads:[~2012-08-20 14:13 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-29  9:03 [PATCH] MMC-4.5 Power OFF Notify Rework Saugata Das
2012-08-20 14:13 ` Ulf Hansson [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-06-15  4:08 Saugata Das
2012-06-15 12:57 ` S, Venkatraman
2012-04-19 12:41 [PATCH] MMC-4.5 Power OFF Notify rework Girish K S
2012-04-20 11:33 ` Girish K S
2012-04-20 12:55   ` Ulf Hansson
2012-04-23 14:11   ` Ulf Hansson
2012-04-27  4:40     ` Girish K S
2012-04-27  7:40       ` Ulf Hansson
2012-04-27  8:42         ` Saugata Das
2012-04-27  8:53           ` Girish K S

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPDyKFq3q1+XOrx4RWrM6ZCOycgTMr7tSLHCCwLtuJarQ-uzoA@mail.gmail.com \
    --to=ulf.hansson@linaro.org \
    --cc=asutoshd@codeaurora.org \
    --cc=girish.shivananjappa@linaro.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=patches@linaro.org \
    --cc=saugata.das@linaro.org \
    --cc=saugata.das@stericsson.com \
    --cc=ulf.hansson@stericsson.com \
    --cc=venkat@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.