aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
authorGirish K S <girish.shivananjappa@linaro.org>2011-10-13 02:34:16 -0400
committerChris Ball <cjb@laptop.org>2011-10-26 16:32:23 -0400
commitbec8726abc72bf30d2743a722aa37cd69e7a0580 (patch)
treeeed4a3c441ff64f5719b021fce419de0fc5196d9 /drivers/mmc/core/core.c
parent326adda53a50ece492c3edaa60afc26fba5e3232 (diff)
mmc: core: Add Power Off Notify Feature eMMC 4.5
This patch adds support for the power off notify feature, available in eMMC 4.5 devices. If the host has support for this feature, then the mmc core will notify the device by setting the POWER_OFF_NOTIFICATION byte in the extended csd register with a value of 1 (POWER_ON). For suspend mode short timeout is used, whereas for the normal poweroff long timeout is used. Signed-off-by: Girish K S <girish.shivananjappa@linaro.org> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 61d7730bc8b..a3c4e0fe943 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1212,11 +1212,43 @@ static void mmc_power_up(struct mmc_host *host)
1212 1212
1213void mmc_power_off(struct mmc_host *host) 1213void mmc_power_off(struct mmc_host *host)
1214{ 1214{
1215 struct mmc_card *card;
1216 unsigned int notify_type;
1217 unsigned int timeout;
1218 int err;
1219
1215 mmc_host_clk_hold(host); 1220 mmc_host_clk_hold(host);
1216 1221
1222 card = host->card;
1217 host->ios.clock = 0; 1223 host->ios.clock = 0;
1218 host->ios.vdd = 0; 1224 host->ios.vdd = 0;
1219 1225
1226 if (card && mmc_card_mmc(card) &&
1227 (card->poweroff_notify_state == MMC_POWERED_ON)) {
1228
1229 if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
1230 notify_type = EXT_CSD_POWER_OFF_SHORT;
1231 timeout = card->ext_csd.generic_cmd6_time;
1232 card->poweroff_notify_state = MMC_POWEROFF_SHORT;
1233 } else {
1234 notify_type = EXT_CSD_POWER_OFF_LONG;
1235 timeout = card->ext_csd.power_off_longtime;
1236 card->poweroff_notify_state = MMC_POWEROFF_LONG;
1237 }
1238
1239 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1240 EXT_CSD_POWER_OFF_NOTIFICATION,
1241 notify_type, timeout);
1242
1243 if (err && err != -EBADMSG)
1244 pr_err("Device failed to respond within %d poweroff "
1245 "time. Forcefully powering down the device\n",
1246 timeout);
1247
1248 /* Set the card state to no notification after the poweroff */
1249 card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
1250 }
1251
1220 /* 1252 /*
1221 * Reset ocr mask to be the highest possible voltage supported for 1253 * Reset ocr mask to be the highest possible voltage supported for
1222 * this mmc host. This value will be used at next power up. 1254 * this mmc host. This value will be used at next power up.
@@ -2208,6 +2240,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
2208 2240
2209 spin_lock_irqsave(&host->lock, flags); 2241 spin_lock_irqsave(&host->lock, flags);
2210 host->rescan_disable = 1; 2242 host->rescan_disable = 1;
2243 host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
2211 spin_unlock_irqrestore(&host->lock, flags); 2244 spin_unlock_irqrestore(&host->lock, flags);
2212 cancel_delayed_work_sync(&host->detect); 2245 cancel_delayed_work_sync(&host->detect);
2213 2246
@@ -2231,6 +2264,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
2231 2264
2232 spin_lock_irqsave(&host->lock, flags); 2265 spin_lock_irqsave(&host->lock, flags);
2233 host->rescan_disable = 0; 2266 host->rescan_disable = 0;
2267 host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
2234 spin_unlock_irqrestore(&host->lock, flags); 2268 spin_unlock_irqrestore(&host->lock, flags);
2235 mmc_detect_change(host, 0); 2269 mmc_detect_change(host, 0);
2236 2270