mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 20:04:01 +00:00
mmc: host: Notify LLD with mmc dev PM status
This adds support in mmc host layer to notify LLD with mmc suspend/resume state. This information is needed by LLD for optimizing suspend/resume latency. Change-Id: Ib8d8f63b4b228079f0e7ef79164e243a55eb2559 Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
This commit is contained in:
parent
139176ea57
commit
f2ac898d2c
2 changed files with 44 additions and 8 deletions
|
@ -49,10 +49,14 @@ static int mmc_host_runtime_suspend(struct device *dev)
|
|||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||
int ret = 0;
|
||||
ktime_t start = ktime_get();
|
||||
enum dev_state status = 0;
|
||||
|
||||
if (!mmc_use_core_runtime_pm(host))
|
||||
return 0;
|
||||
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, DEV_SUSPENDING);
|
||||
|
||||
if (host->card && mmc_card_cmdq(host->card)) {
|
||||
BUG_ON(host->cmdq_ctx.active_reqs);
|
||||
|
||||
|
@ -61,7 +65,7 @@ static int mmc_host_runtime_suspend(struct device *dev)
|
|||
if (ret) {
|
||||
mmc_card_clr_suspended(host->card);
|
||||
pr_err("%s: halt: failed: %d\n", __func__, ret);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
mmc_host_clk_hold(host);
|
||||
host->cmdq_ops->disable(host, true);
|
||||
|
@ -91,6 +95,10 @@ static int mmc_host_runtime_suspend(struct device *dev)
|
|||
*/
|
||||
if (ret == -ENOMEDIUM)
|
||||
ret = 0;
|
||||
out:
|
||||
status = !ret ? DEV_SUSPENDED : DEV_ERROR;
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, status);
|
||||
|
||||
trace_mmc_host_runtime_suspend(mmc_hostname(host), ret,
|
||||
ktime_to_us(ktime_sub(ktime_get(), start)));
|
||||
|
@ -102,10 +110,14 @@ static int mmc_host_runtime_resume(struct device *dev)
|
|||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||
int ret = 0;
|
||||
ktime_t start = ktime_get();
|
||||
enum dev_state status = 0;
|
||||
|
||||
if (!mmc_use_core_runtime_pm(host))
|
||||
return 0;
|
||||
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, DEV_RESUMING);
|
||||
|
||||
ret = mmc_resume_host(host);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: %s: resume host: failed: ret: %d\n",
|
||||
|
@ -121,6 +133,11 @@ static int mmc_host_runtime_resume(struct device *dev)
|
|||
else
|
||||
mmc_card_clr_suspended(host->card);
|
||||
}
|
||||
|
||||
status = !ret ? DEV_RESUMED : DEV_ERROR;
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, status);
|
||||
|
||||
trace_mmc_host_runtime_resume(mmc_hostname(host), ret,
|
||||
ktime_to_us(ktime_sub(ktime_get(), start)));
|
||||
return ret;
|
||||
|
@ -133,9 +150,14 @@ static int mmc_host_suspend(struct device *dev)
|
|||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
enum dev_state status = 0;
|
||||
|
||||
if (!mmc_use_core_pm(host))
|
||||
return 0;
|
||||
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, DEV_SUSPENDING);
|
||||
|
||||
spin_lock_irqsave(&host->clk_lock, flags);
|
||||
/*
|
||||
* let the driver know that suspend is in progress and must
|
||||
|
@ -152,7 +174,7 @@ static int mmc_host_suspend(struct device *dev)
|
|||
if (ret) {
|
||||
mmc_card_clr_suspended(host->card);
|
||||
pr_err("%s: halt: failed: %d\n", __func__, ret);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
mmc_host_clk_hold(host);
|
||||
host->cmdq_ops->disable(host, true);
|
||||
|
@ -179,6 +201,10 @@ static int mmc_host_suspend(struct device *dev)
|
|||
spin_lock_irqsave(&host->clk_lock, flags);
|
||||
host->dev_status = DEV_SUSPENDED;
|
||||
spin_unlock_irqrestore(&host->clk_lock, flags);
|
||||
out:
|
||||
status = !ret ? DEV_SUSPENDED : DEV_ERROR;
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -186,10 +212,13 @@ static int mmc_host_resume(struct device *dev)
|
|||
{
|
||||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||
int ret = 0;
|
||||
enum dev_state status = 0;
|
||||
|
||||
if (!mmc_use_core_pm(host))
|
||||
return 0;
|
||||
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, DEV_RESUMING);
|
||||
if (!pm_runtime_suspended(dev)) {
|
||||
ret = mmc_resume_host(host);
|
||||
if (ret < 0) {
|
||||
|
@ -205,6 +234,10 @@ static int mmc_host_resume(struct device *dev)
|
|||
}
|
||||
}
|
||||
host->dev_status = DEV_RESUMED;
|
||||
status = !ret ? DEV_RESUMED : DEV_ERROR;
|
||||
if (host->ops->notify_pm_status)
|
||||
host->ops->notify_pm_status(host, status);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -91,6 +91,14 @@ enum mmc_load {
|
|||
MMC_LOAD_LOW,
|
||||
};
|
||||
|
||||
enum dev_state {
|
||||
DEV_SUSPENDING = 1,
|
||||
DEV_SUSPENDED,
|
||||
DEV_RESUMING,
|
||||
DEV_RESUMED,
|
||||
DEV_ERROR,
|
||||
};
|
||||
|
||||
struct mmc_cmdq_host_ops {
|
||||
int (*enable)(struct mmc_host *host);
|
||||
void (*disable)(struct mmc_host *host, bool soft);
|
||||
|
@ -164,6 +172,7 @@ struct mmc_host_ops {
|
|||
unsigned long (*get_max_frequency)(struct mmc_host *host);
|
||||
unsigned long (*get_min_frequency)(struct mmc_host *host);
|
||||
int (*notify_load)(struct mmc_host *, enum mmc_load);
|
||||
void (*notify_pm_status)(struct mmc_host *, enum dev_state);
|
||||
int (*stop_request)(struct mmc_host *host);
|
||||
unsigned int (*get_xfer_remain)(struct mmc_host *host);
|
||||
};
|
||||
|
@ -281,12 +290,6 @@ struct mmc_supply {
|
|||
struct regulator *vqmmc; /* Optional Vccq supply */
|
||||
};
|
||||
|
||||
enum dev_state {
|
||||
DEV_SUSPENDING = 1,
|
||||
DEV_SUSPENDED,
|
||||
DEV_RESUMED,
|
||||
};
|
||||
|
||||
struct mmc_host {
|
||||
struct device *parent;
|
||||
struct device class_dev;
|
||||
|
|
Loading…
Reference in a new issue