Merge "mmc: sdhci: Notify sdhci-msm with mmc host PM state"

This commit is contained in:
Linux Build Service Account 2015-08-18 17:07:05 -07:00 committed by Gerrit - the friendly Code Review server
commit cd86617027
4 changed files with 55 additions and 8 deletions

View file

@ -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

View file

@ -1687,6 +1687,14 @@ static inline void sdhci_update_power_policy(struct sdhci_host *host,
host->power_policy = policy;
}
static void sdhci_notify_pm_status(struct mmc_host *mmc, enum dev_state state)
{
struct sdhci_host *host = mmc_priv(mmc);
if (host->ops->notify_pm_status)
host->ops->notify_pm_status(host, state);
}
static int sdhci_notify_load(struct mmc_host *mmc, enum mmc_load state)
{
int err = 0;
@ -2871,6 +2879,7 @@ static const struct mmc_host_ops sdhci_ops = {
.stop_request = sdhci_stop_request,
.get_xfer_remain = sdhci_get_xfer_remain,
.notify_load = sdhci_notify_load,
.notify_pm_status = sdhci_notify_pm_status,
};
/*****************************************************************************\

View file

@ -329,6 +329,8 @@ struct sdhci_ops {
void (*reset_workaround)(struct sdhci_host *host, u32 enable);
void (*clear_set_dumpregs)(struct sdhci_host *host, bool set);
int (*notify_load)(struct sdhci_host *host, enum mmc_load state);
void (*notify_pm_status)(struct sdhci_host *host,
enum dev_state state);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

View file

@ -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;