From patchwork Tue Nov 15 06:25:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Girish K S X-Patchwork-Id: 5125 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 429D523E0C for ; Tue, 15 Nov 2011 06:25:17 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id 1F36FA18207 for ; Tue, 15 Nov 2011 06:25:17 +0000 (UTC) Received: by faaa26 with SMTP id a26so103511faa.11 for ; Mon, 14 Nov 2011 22:25:17 -0800 (PST) Received: by 10.152.162.10 with SMTP id xw10mr16026389lab.12.1321338316774; Mon, 14 Nov 2011 22:25:16 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.41.198 with SMTP id h6cs27418lal; Mon, 14 Nov 2011 22:25:16 -0800 (PST) Received: by 10.52.26.9 with SMTP id h9mr39802661vdg.99.1321338314225; Mon, 14 Nov 2011 22:25:14 -0800 (PST) Received: from mail-gx0-f178.google.com (mail-gx0-f178.google.com [209.85.161.178]) by mx.google.com with ESMTPS id p16si5490105anb.23.2011.11.14.22.25.13 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 14 Nov 2011 22:25:14 -0800 (PST) Received-SPF: neutral (google.com: 209.85.161.178 is neither permitted nor denied by best guess record for domain of girish.shivananjappa@linaro.org) client-ip=209.85.161.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.161.178 is neither permitted nor denied by best guess record for domain of girish.shivananjappa@linaro.org) smtp.mail=girish.shivananjappa@linaro.org Received: by ggnk5 with SMTP id k5so3398436ggn.37 for ; Mon, 14 Nov 2011 22:25:13 -0800 (PST) Received: by 10.68.31.129 with SMTP id a1mr56027255pbi.131.1321338312803; Mon, 14 Nov 2011 22:25:12 -0800 (PST) Received: from girishks ([115.113.119.130]) by mx.google.com with ESMTPS id p10sm62497797pbd.15.2011.11.14.22.25.09 (version=SSLv3 cipher=OTHER); Mon, 14 Nov 2011 22:25:12 -0800 (PST) From: Girish K S To: linux-mmc@vger.kernel.org Cc: cjb@laptop.org, patches@linaro.org, linux-samsung-soc@vger.kernel.org, Girish K S Subject: [PATCH] mmc: core: Fix power_off_notify during suspend Date: Tue, 15 Nov 2011 11:55:46 +0530 Message-Id: <1321338346-10911-1-git-send-email-girish.shivananjappa@linaro.org> X-Mailer: git-send-email 1.7.1 The eMMC 4.5 devices respond to only RESET and AWAKE command in the sleep state. Hence the mmc switch command to notify power off state should be sent before the device enters sleep state. This patch fixes the same. Signed-off-by: Girish K S --- drivers/mmc/core/core.c | 81 ++++++++++++++++++++++++++++------------------ drivers/mmc/core/mmc.c | 2 +- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 74a012a..7ee2e07 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1225,6 +1225,46 @@ 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; + + /* + * 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; + } +} + /* * Apply power to the MMC stack. This is a two-stage process. * First, we enable power to the card without the clock running. @@ -1281,42 +1321,12 @@ static void mmc_power_up(struct mmc_host *host) void mmc_power_off(struct mmc_host *host) { - struct mmc_card *card; - unsigned int notify_type; - unsigned int timeout; - int err; - mmc_host_clk_hold(host); - card = host->card; host->ios.clock = 0; host->ios.vdd = 0; - 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_poweroff_notify(host); /* * Reset ocr mask to be the highest possible voltage supported for @@ -2314,8 +2324,15 @@ int mmc_suspend_host(struct mmc_host *host) * pre-claim the host. */ if (mmc_try_claim_host(host)) { - if (host->bus_ops->suspend) + if (host->bus_ops->suspend) { + /* + * For eMMC 4.5 device send notify command + * before sleep, because in sleep state eMMC 4.5 + * devices respond to only RESET and AWAKE cmd + */ + mmc_poweroff_notify(host); err = host->bus_ops->suspend(host); + } if (err == -ENOSYS || !host->bus_ops->resume) { /* * We simply "remove" the card in this case. diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 4db73a9..a1223bd 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -875,7 +875,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * set the notification byte in the ext_csd register of device */ if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && - (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) { + (card->ext_csd.rev >= 6)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_POWER_OFF_NOTIFICATION, EXT_CSD_POWER_ON,