Merge branches 'pm-core' and 'pm-domains'
* pm-core: PM / sleep: Drop unused `info' variable PM / Runtime: Move ignore_children flag under CONFIG_PM PM / Runtime: Fix error path in pm_runtime_force_resume() * pm-domains: PM / Domains: Drop unnecessary wakeup code from pm_genpd_prepare() PM / Domains: Remove redundant pm_runtime_get|put*() in pm_genpd_prepare() PM / Domains: Remove ->save|restore_state() callbacks PM / Domains: Rename pm_genpd_runtime_suspend|resume() PM / Domains: Rename stop_ok to suspend_ok for the genpd governor
This commit is contained in:
commit
aa24781b1c
|
@ -229,17 +229,6 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
|
||||
{
|
||||
return GENPD_DEV_CALLBACK(genpd, int, save_state, dev);
|
||||
}
|
||||
|
||||
static int genpd_restore_dev(struct generic_pm_domain *genpd,
|
||||
struct device *dev)
|
||||
{
|
||||
return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev);
|
||||
}
|
||||
|
||||
static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
|
||||
unsigned long val, void *ptr)
|
||||
{
|
||||
|
@ -372,17 +361,63 @@ static void genpd_power_off_work_fn(struct work_struct *work)
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
|
||||
* __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
|
||||
* @dev: Device to handle.
|
||||
*/
|
||||
static int __genpd_runtime_suspend(struct device *dev)
|
||||
{
|
||||
int (*cb)(struct device *__dev);
|
||||
|
||||
if (dev->type && dev->type->pm)
|
||||
cb = dev->type->pm->runtime_suspend;
|
||||
else if (dev->class && dev->class->pm)
|
||||
cb = dev->class->pm->runtime_suspend;
|
||||
else if (dev->bus && dev->bus->pm)
|
||||
cb = dev->bus->pm->runtime_suspend;
|
||||
else
|
||||
cb = NULL;
|
||||
|
||||
if (!cb && dev->driver && dev->driver->pm)
|
||||
cb = dev->driver->pm->runtime_suspend;
|
||||
|
||||
return cb ? cb(dev) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
|
||||
* @dev: Device to handle.
|
||||
*/
|
||||
static int __genpd_runtime_resume(struct device *dev)
|
||||
{
|
||||
int (*cb)(struct device *__dev);
|
||||
|
||||
if (dev->type && dev->type->pm)
|
||||
cb = dev->type->pm->runtime_resume;
|
||||
else if (dev->class && dev->class->pm)
|
||||
cb = dev->class->pm->runtime_resume;
|
||||
else if (dev->bus && dev->bus->pm)
|
||||
cb = dev->bus->pm->runtime_resume;
|
||||
else
|
||||
cb = NULL;
|
||||
|
||||
if (!cb && dev->driver && dev->driver->pm)
|
||||
cb = dev->driver->pm->runtime_resume;
|
||||
|
||||
return cb ? cb(dev) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
|
||||
* @dev: Device to suspend.
|
||||
*
|
||||
* Carry out a runtime suspend of a device under the assumption that its
|
||||
* pm_domain field points to the domain member of an object of type
|
||||
* struct generic_pm_domain representing a PM domain consisting of I/O devices.
|
||||
*/
|
||||
static int pm_genpd_runtime_suspend(struct device *dev)
|
||||
static int genpd_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
bool (*stop_ok)(struct device *__dev);
|
||||
bool (*suspend_ok)(struct device *__dev);
|
||||
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
|
||||
bool runtime_pm = pm_runtime_enabled(dev);
|
||||
ktime_t time_start;
|
||||
|
@ -401,21 +436,21 @@ static int pm_genpd_runtime_suspend(struct device *dev)
|
|||
* runtime PM is disabled. Under these circumstances, we shall skip
|
||||
* validating/measuring the PM QoS latency.
|
||||
*/
|
||||
stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
|
||||
if (runtime_pm && stop_ok && !stop_ok(dev))
|
||||
suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL;
|
||||
if (runtime_pm && suspend_ok && !suspend_ok(dev))
|
||||
return -EBUSY;
|
||||
|
||||
/* Measure suspend latency. */
|
||||
if (runtime_pm)
|
||||
time_start = ktime_get();
|
||||
|
||||
ret = genpd_save_dev(genpd, dev);
|
||||
ret = __genpd_runtime_suspend(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = genpd_stop_dev(genpd, dev);
|
||||
if (ret) {
|
||||
genpd_restore_dev(genpd, dev);
|
||||
__genpd_runtime_resume(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -446,14 +481,14 @@ static int pm_genpd_runtime_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
|
||||
* genpd_runtime_resume - Resume a device belonging to I/O PM domain.
|
||||
* @dev: Device to resume.
|
||||
*
|
||||
* Carry out a runtime resume of a device under the assumption that its
|
||||
* pm_domain field points to the domain member of an object of type
|
||||
* struct generic_pm_domain representing a PM domain consisting of I/O devices.
|
||||
*/
|
||||
static int pm_genpd_runtime_resume(struct device *dev)
|
||||
static int genpd_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
|
||||
|
@ -491,7 +526,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
|
|||
if (ret)
|
||||
goto err_poweroff;
|
||||
|
||||
ret = genpd_restore_dev(genpd, dev);
|
||||
ret = __genpd_runtime_resume(dev);
|
||||
if (ret)
|
||||
goto err_stop;
|
||||
|
||||
|
@ -695,15 +730,6 @@ static int pm_genpd_prepare(struct device *dev)
|
|||
* at this point and a system wakeup event should be reported if it's
|
||||
* set up to wake up the system from sleep states.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
|
||||
pm_wakeup_event(dev, 0);
|
||||
|
||||
if (pm_wakeup_pending()) {
|
||||
pm_runtime_put(dev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (resume_needed(dev, genpd))
|
||||
pm_runtime_resume(dev);
|
||||
|
||||
|
@ -716,10 +742,8 @@ static int pm_genpd_prepare(struct device *dev)
|
|||
|
||||
mutex_unlock(&genpd->lock);
|
||||
|
||||
if (genpd->suspend_power_off) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
if (genpd->suspend_power_off)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The PM domain must be in the GPD_STATE_ACTIVE state at this point,
|
||||
|
@ -741,7 +765,6 @@ static int pm_genpd_prepare(struct device *dev)
|
|||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
pm_runtime_put(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1427,54 +1450,6 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
|
||||
|
||||
/* Default device callbacks for generic PM domains. */
|
||||
|
||||
/**
|
||||
* pm_genpd_default_save_state - Default "save device state" for PM domains.
|
||||
* @dev: Device to handle.
|
||||
*/
|
||||
static int pm_genpd_default_save_state(struct device *dev)
|
||||
{
|
||||
int (*cb)(struct device *__dev);
|
||||
|
||||
if (dev->type && dev->type->pm)
|
||||
cb = dev->type->pm->runtime_suspend;
|
||||
else if (dev->class && dev->class->pm)
|
||||
cb = dev->class->pm->runtime_suspend;
|
||||
else if (dev->bus && dev->bus->pm)
|
||||
cb = dev->bus->pm->runtime_suspend;
|
||||
else
|
||||
cb = NULL;
|
||||
|
||||
if (!cb && dev->driver && dev->driver->pm)
|
||||
cb = dev->driver->pm->runtime_suspend;
|
||||
|
||||
return cb ? cb(dev) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_genpd_default_restore_state - Default PM domains "restore device state".
|
||||
* @dev: Device to handle.
|
||||
*/
|
||||
static int pm_genpd_default_restore_state(struct device *dev)
|
||||
{
|
||||
int (*cb)(struct device *__dev);
|
||||
|
||||
if (dev->type && dev->type->pm)
|
||||
cb = dev->type->pm->runtime_resume;
|
||||
else if (dev->class && dev->class->pm)
|
||||
cb = dev->class->pm->runtime_resume;
|
||||
else if (dev->bus && dev->bus->pm)
|
||||
cb = dev->bus->pm->runtime_resume;
|
||||
else
|
||||
cb = NULL;
|
||||
|
||||
if (!cb && dev->driver && dev->driver->pm)
|
||||
cb = dev->driver->pm->runtime_resume;
|
||||
|
||||
return cb ? cb(dev) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_genpd_init - Initialize a generic I/O PM domain object.
|
||||
* @genpd: PM domain object to initialize.
|
||||
|
@ -1498,8 +1473,8 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
|
|||
genpd->device_count = 0;
|
||||
genpd->max_off_time_ns = -1;
|
||||
genpd->max_off_time_changed = true;
|
||||
genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
|
||||
genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
|
||||
genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
|
||||
genpd->domain.ops.runtime_resume = genpd_runtime_resume;
|
||||
genpd->domain.ops.prepare = pm_genpd_prepare;
|
||||
genpd->domain.ops.suspend = pm_genpd_suspend;
|
||||
genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
|
||||
|
@ -1520,8 +1495,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
|
|||
genpd->domain.ops.restore_early = pm_genpd_resume_early;
|
||||
genpd->domain.ops.restore = pm_genpd_resume;
|
||||
genpd->domain.ops.complete = pm_genpd_complete;
|
||||
genpd->dev_ops.save_state = pm_genpd_default_save_state;
|
||||
genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
|
||||
|
||||
if (genpd->flags & GENPD_FLAG_PM_CLK) {
|
||||
genpd->dev_ops.stop = pm_clk_suspend;
|
||||
|
|
|
@ -37,10 +37,10 @@ static int dev_update_qos_constraint(struct device *dev, void *data)
|
|||
}
|
||||
|
||||
/**
|
||||
* default_stop_ok - Default PM domain governor routine for stopping devices.
|
||||
* default_suspend_ok - Default PM domain governor routine to suspend devices.
|
||||
* @dev: Device to check.
|
||||
*/
|
||||
static bool default_stop_ok(struct device *dev)
|
||||
static bool default_suspend_ok(struct device *dev)
|
||||
{
|
||||
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
|
||||
unsigned long flags;
|
||||
|
@ -51,13 +51,13 @@ static bool default_stop_ok(struct device *dev)
|
|||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
|
||||
if (!td->constraint_changed) {
|
||||
bool ret = td->cached_stop_ok;
|
||||
bool ret = td->cached_suspend_ok;
|
||||
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
return ret;
|
||||
}
|
||||
td->constraint_changed = false;
|
||||
td->cached_stop_ok = false;
|
||||
td->cached_suspend_ok = false;
|
||||
td->effective_constraint_ns = -1;
|
||||
constraint_ns = __dev_pm_qos_read_value(dev);
|
||||
|
||||
|
@ -83,13 +83,13 @@ static bool default_stop_ok(struct device *dev)
|
|||
return false;
|
||||
}
|
||||
td->effective_constraint_ns = constraint_ns;
|
||||
td->cached_stop_ok = constraint_ns >= 0;
|
||||
td->cached_suspend_ok = constraint_ns >= 0;
|
||||
|
||||
/*
|
||||
* The children have been suspended already, so we don't need to take
|
||||
* their stop latencies into account here.
|
||||
* their suspend latencies into account here.
|
||||
*/
|
||||
return td->cached_stop_ok;
|
||||
return td->cached_suspend_ok;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +150,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
|
|||
*/
|
||||
td = &to_gpd_data(pdd)->td;
|
||||
constraint_ns = td->effective_constraint_ns;
|
||||
/* default_stop_ok() need not be called before us. */
|
||||
/* default_suspend_ok() need not be called before us. */
|
||||
if (constraint_ns < 0) {
|
||||
constraint_ns = dev_pm_qos_read_value(pdd->dev);
|
||||
constraint_ns *= NSEC_PER_USEC;
|
||||
|
@ -227,7 +227,7 @@ static bool always_on_power_down_ok(struct dev_pm_domain *domain)
|
|||
}
|
||||
|
||||
struct dev_power_governor simple_qos_governor = {
|
||||
.stop_ok = default_stop_ok,
|
||||
.suspend_ok = default_suspend_ok,
|
||||
.power_down_ok = default_power_down_ok,
|
||||
};
|
||||
|
||||
|
@ -236,5 +236,5 @@ struct dev_power_governor simple_qos_governor = {
|
|||
*/
|
||||
struct dev_power_governor pm_domain_always_on_gov = {
|
||||
.power_down_ok = always_on_power_down_ok,
|
||||
.stop_ok = default_stop_ok,
|
||||
.suspend_ok = default_suspend_ok,
|
||||
};
|
||||
|
|
|
@ -1556,7 +1556,6 @@ int dpm_suspend(pm_message_t state)
|
|||
static int device_prepare(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int (*callback)(struct device *) = NULL;
|
||||
char *info = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->power.syscore)
|
||||
|
@ -1579,24 +1578,17 @@ static int device_prepare(struct device *dev, pm_message_t state)
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
if (dev->pm_domain) {
|
||||
info = "preparing power domain ";
|
||||
if (dev->pm_domain)
|
||||
callback = dev->pm_domain->ops.prepare;
|
||||
} else if (dev->type && dev->type->pm) {
|
||||
info = "preparing type ";
|
||||
else if (dev->type && dev->type->pm)
|
||||
callback = dev->type->pm->prepare;
|
||||
} else if (dev->class && dev->class->pm) {
|
||||
info = "preparing class ";
|
||||
else if (dev->class && dev->class->pm)
|
||||
callback = dev->class->pm->prepare;
|
||||
} else if (dev->bus && dev->bus->pm) {
|
||||
info = "preparing bus ";
|
||||
else if (dev->bus && dev->bus->pm)
|
||||
callback = dev->bus->pm->prepare;
|
||||
}
|
||||
|
||||
if (!callback && dev->driver && dev->driver->pm) {
|
||||
info = "preparing driver ";
|
||||
if (!callback && dev->driver && dev->driver->pm)
|
||||
callback = dev->driver->pm->prepare;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
ret = callback(dev);
|
||||
|
|
|
@ -1506,11 +1506,16 @@ int pm_runtime_force_resume(struct device *dev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = callback(dev);
|
||||
ret = pm_runtime_set_active(dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
ret = callback(dev);
|
||||
if (ret) {
|
||||
pm_runtime_set_suspended(dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
out:
|
||||
pm_runtime_enable(dev);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
|
||||
|
|
|
@ -956,11 +956,6 @@ static inline bool device_async_suspend_enabled(struct device *dev)
|
|||
return !!dev->power.async_suspend;
|
||||
}
|
||||
|
||||
static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
|
||||
{
|
||||
dev->power.ignore_children = enable;
|
||||
}
|
||||
|
||||
static inline void dev_pm_syscore_device(struct device *dev, bool val)
|
||||
{
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
|
|
@ -563,7 +563,6 @@ struct dev_pm_info {
|
|||
bool is_suspended:1; /* Ditto */
|
||||
bool is_noirq_suspended:1;
|
||||
bool is_late_suspended:1;
|
||||
bool ignore_children:1;
|
||||
bool early_init:1; /* Owned by the PM core */
|
||||
bool direct_complete:1; /* Owned by the PM core */
|
||||
spinlock_t lock;
|
||||
|
@ -591,6 +590,7 @@ struct dev_pm_info {
|
|||
unsigned int deferred_resume:1;
|
||||
unsigned int run_wake:1;
|
||||
unsigned int runtime_auto:1;
|
||||
bool ignore_children:1;
|
||||
unsigned int no_callbacks:1;
|
||||
unsigned int irq_safe:1;
|
||||
unsigned int use_autosuspend:1;
|
||||
|
|
|
@ -28,14 +28,12 @@ enum gpd_status {
|
|||
|
||||
struct dev_power_governor {
|
||||
bool (*power_down_ok)(struct dev_pm_domain *domain);
|
||||
bool (*stop_ok)(struct device *dev);
|
||||
bool (*suspend_ok)(struct device *dev);
|
||||
};
|
||||
|
||||
struct gpd_dev_ops {
|
||||
int (*start)(struct device *dev);
|
||||
int (*stop)(struct device *dev);
|
||||
int (*save_state)(struct device *dev);
|
||||
int (*restore_state)(struct device *dev);
|
||||
bool (*active_wakeup)(struct device *dev);
|
||||
};
|
||||
|
||||
|
@ -94,7 +92,7 @@ struct gpd_timing_data {
|
|||
s64 resume_latency_ns;
|
||||
s64 effective_constraint_ns;
|
||||
bool constraint_changed;
|
||||
bool cached_stop_ok;
|
||||
bool cached_suspend_ok;
|
||||
};
|
||||
|
||||
struct pm_domain_data {
|
||||
|
|
|
@ -56,6 +56,11 @@ extern void pm_runtime_update_max_time_suspended(struct device *dev,
|
|||
s64 delta_ns);
|
||||
extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
|
||||
|
||||
static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
|
||||
{
|
||||
dev->power.ignore_children = enable;
|
||||
}
|
||||
|
||||
static inline bool pm_children_suspended(struct device *dev)
|
||||
{
|
||||
return dev->power.ignore_children
|
||||
|
@ -156,6 +161,7 @@ static inline void __pm_runtime_disable(struct device *dev, bool c) {}
|
|||
static inline void pm_runtime_allow(struct device *dev) {}
|
||||
static inline void pm_runtime_forbid(struct device *dev) {}
|
||||
|
||||
static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
|
||||
static inline bool pm_children_suspended(struct device *dev) { return false; }
|
||||
static inline void pm_runtime_get_noresume(struct device *dev) {}
|
||||
static inline void pm_runtime_put_noidle(struct device *dev) {}
|
||||
|
|
Loading…
Reference in New Issue