summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTatyana Brokhman <tlinder@codeaurora.org>2014-12-04 22:03:42 +0200
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:25:49 -0700
commit15209ec725e499e1e53b6e1104b6249e0430bf94 (patch)
tree98ff7bdd0f4a8d2f6c58270d0d15ef1e2fbcef53 /drivers
parent83d95c50fb7c138177290641436a926ed4700e9b (diff)
mmc: Add long power off notification support
At the moment only POWER_OFF_SHORT is sent to the device in case the host is suspended. This patch adds the support of sending POWER_OFF_LONG notification in case the device is powered off. According to device vendors the POWER_OFF_LONG notification will shorten the initialization time of the eMMC card during next boot up. Change-Id: I3c6f224398450cf10463cbb316613fd430d1e8d2 Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org> Signed-off-by: Sujit Reddy Thumma <sthumma@codeaurora.org> [merez@codeaurora.org: fix conflicts as some of the code was already included] Signed-off-by: Maya Erez <merez@codeaurora.org> [venkatg@codeaurora.org: Remove PM related code] Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/mmc.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 440d7a0a99be..461a150109fb 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -19,6 +19,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
+#include <linux/reboot.h>
#include "core.h"
#include "host.h"
@@ -1364,6 +1365,20 @@ out:
return err;
}
+static int mmc_reboot_notify(struct notifier_block *notify_block,
+ unsigned long event, void *unused)
+{
+ struct mmc_card *card = container_of(
+ notify_block, struct mmc_card, reboot_notify);
+
+ if (event != SYS_RESTART)
+ card->issue_long_pon = true;
+ else
+ card->issue_long_pon = false;
+
+ return NOTIFY_OK;
+}
+
/*
* Activate High Speed or HS200 mode if supported.
*/
@@ -1495,6 +1510,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
card->rca = 1;
memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
host->card = card;
+ card->reboot_notify.notifier_call = mmc_reboot_notify;
}
/*
@@ -1838,6 +1854,22 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
return err;
}
+int mmc_send_long_pon(struct mmc_card *card)
+{
+ int err = 0;
+ struct mmc_host *host = card->host;
+
+ mmc_claim_host(host);
+ if (card->issue_long_pon && mmc_can_poweroff_notify(card)) {
+ err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_LONG);
+ if (err)
+ pr_warning("%s: error %d sending Long PON",
+ mmc_hostname(host), err);
+ }
+ mmc_release_host(host);
+ return err;
+}
+
/*
* Host is being removed. Free up the current card.
*/
@@ -1846,6 +1878,7 @@ static void mmc_remove(struct mmc_host *host)
BUG_ON(!host);
BUG_ON(!host->card);
+ unregister_reboot_notifier(&host->card->reboot_notify);
mmc_remove_card(host->card);
mmc_claim_host(host);
@@ -2166,6 +2199,9 @@ int mmc_attach_mmc(struct mmc_host *host)
goto remove_card;
mmc_claim_host(host);
+
+ register_reboot_notifier(&host->card->reboot_notify);
+
return 0;
remove_card: