Message ID | 1347528053-8521-1-git-send-email-ulf.hansson@stericsson.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
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
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
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
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
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
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
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
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
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.
> > > > 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
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
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
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
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
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
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
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
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
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
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.
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
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
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.
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 --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 */