Loading drivers/base/power/domain.c +25 −255 Original line number Diff line number Diff line Loading @@ -53,24 +53,6 @@ static LIST_HEAD(gpd_list); static DEFINE_MUTEX(gpd_list_lock); static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name) { struct generic_pm_domain *genpd = NULL, *gpd; if (IS_ERR_OR_NULL(domain_name)) return NULL; mutex_lock(&gpd_list_lock); list_for_each_entry(gpd, &gpd_list, gpd_list_node) { if (!strcmp(gpd->name, domain_name)) { genpd = gpd; break; } } mutex_unlock(&gpd_list_lock); return genpd; } /* * Get the generic PM domain for a particular struct device. * This validates the struct device pointer, the PM domain pointer, Loading Loading @@ -140,19 +122,6 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) smp_mb__after_atomic(); } static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) { s64 usecs64; if (!genpd->cpuidle_data) return; usecs64 = genpd->power_on_latency_ns; do_div(usecs64, NSEC_PER_USEC); usecs64 += genpd->cpuidle_data->saved_exit_latency; genpd->cpuidle_data->idle_state->exit_latency = usecs64; } static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) { ktime_t time_start; Loading @@ -176,7 +145,6 @@ static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) genpd->power_on_latency_ns = elapsed_ns; genpd->max_off_time_changed = true; genpd_recalc_cpu_exit_latency(genpd); pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", genpd->name, "on", elapsed_ns); Loading Loading @@ -213,10 +181,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool timed) } /** * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff(). * genpd_queue_power_off_work - Queue up the execution of genpd_poweroff(). * @genpd: PM domait to power off. * * Queue up the execution of pm_genpd_poweroff() unless it's already been done * Queue up the execution of genpd_poweroff() unless it's already been done * before. */ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) Loading @@ -224,14 +192,16 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) queue_work(pm_wq, &genpd->power_off_work); } static int genpd_poweron(struct generic_pm_domain *genpd); /** * __pm_genpd_poweron - Restore power to a given PM domain and its masters. * __genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. * * Restore power to @genpd and all of its masters so that it is possible to * resume a device belonging to it. */ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) static int __genpd_poweron(struct generic_pm_domain *genpd) { struct gpd_link *link; int ret = 0; Loading @@ -240,13 +210,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) || (genpd->prepared_count > 0 && genpd->suspend_power_off)) return 0; if (genpd->cpuidle_data) { cpuidle_pause_and_lock(); genpd->cpuidle_data->idle_state->disabled = true; cpuidle_resume_and_unlock(); goto out; } /* * The list is guaranteed not to change while the loop below is being * executed, unless one of the masters' .power_on() callbacks fiddles Loading @@ -255,7 +218,7 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) list_for_each_entry(link, &genpd->slave_links, slave_node) { genpd_sd_counter_inc(link->master); ret = pm_genpd_poweron(link->master); ret = genpd_poweron(link->master); if (ret) { genpd_sd_counter_dec(link->master); goto err; Loading @@ -266,7 +229,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) if (ret) goto err; out: genpd->status = GPD_STATE_ACTIVE; return 0; Loading @@ -282,31 +244,19 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) } /** * pm_genpd_poweron - Restore power to a given PM domain and its masters. * genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. */ int pm_genpd_poweron(struct generic_pm_domain *genpd) static int genpd_poweron(struct generic_pm_domain *genpd) { int ret; mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); ret = __genpd_poweron(genpd); mutex_unlock(&genpd->lock); return ret; } /** * pm_genpd_name_poweron - Restore power to a given PM domain and its masters. * @domain_name: Name of the PM domain to power up. */ int pm_genpd_name_poweron(const char *domain_name) { struct generic_pm_domain *genpd; genpd = pm_genpd_lookup_name(domain_name); return genpd ? pm_genpd_poweron(genpd) : -EINVAL; } static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) { return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, Loading Loading @@ -365,13 +315,14 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, } /** * pm_genpd_poweroff - Remove power from a given PM domain. * genpd_poweroff - Remove power from a given PM domain. * @genpd: PM domain to power down. * @is_async: PM domain is powered down from a scheduled work * * If all of the @genpd's devices have been suspended and all of its subdomains * have been powered down, remove power from @genpd. */ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async) { struct pm_domain_data *pdd; struct gpd_link *link; Loading Loading @@ -403,7 +354,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) not_suspended++; } if (not_suspended > genpd->in_progress) if (not_suspended > 1 || (not_suspended == 1 && is_async)) return -EBUSY; if (genpd->gov && genpd->gov->power_down_ok) { Loading @@ -411,21 +362,6 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) return -EAGAIN; } if (genpd->cpuidle_data) { /* * If cpuidle_data is set, cpuidle should turn the domain off * when the CPU in it is idle. In that case we don't decrement * the subdomain counts of the master domains, so that power is * not removed from the current domain prematurely as a result * of cutting off the masters' power. */ genpd->status = GPD_STATE_POWER_OFF; cpuidle_pause_and_lock(); genpd->cpuidle_data->idle_state->disabled = false; cpuidle_resume_and_unlock(); return 0; } if (genpd->power_off) { int ret; Loading @@ -434,10 +370,10 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) /* * If sd_count > 0 at this point, one of the subdomains hasn't * managed to call pm_genpd_poweron() for the master yet after * incrementing it. In that case pm_genpd_poweron() will wait * managed to call genpd_poweron() for the master yet after * incrementing it. In that case genpd_poweron() will wait * for us to drop the lock, so we can call .power_off() and let * the pm_genpd_poweron() restore power for us (this shouldn't * the genpd_poweron() restore power for us (this shouldn't * happen very often). */ ret = genpd_power_off(genpd, true); Loading Loading @@ -466,7 +402,7 @@ static void genpd_power_off_work_fn(struct work_struct *work) genpd = container_of(work, struct generic_pm_domain, power_off_work); mutex_lock(&genpd->lock); pm_genpd_poweroff(genpd); genpd_poweroff(genpd, true); mutex_unlock(&genpd->lock); } Loading Loading @@ -512,9 +448,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) return 0; mutex_lock(&genpd->lock); genpd->in_progress++; pm_genpd_poweroff(genpd); genpd->in_progress--; genpd_poweroff(genpd, false); mutex_unlock(&genpd->lock); return 0; Loading Loading @@ -547,7 +481,7 @@ static int pm_genpd_runtime_resume(struct device *dev) } mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); ret = __genpd_poweron(genpd); mutex_unlock(&genpd->lock); if (ret) Loading @@ -569,15 +503,15 @@ static int __init pd_ignore_unused_setup(char *__unused) __setup("pd_ignore_unused", pd_ignore_unused_setup); /** * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. * genpd_poweroff_unused - Power off all PM domains with no devices in use. */ void pm_genpd_poweroff_unused(void) static int __init genpd_poweroff_unused(void) { struct generic_pm_domain *genpd; if (pd_ignore_unused) { pr_warn("genpd: Not disabling unused power domains\n"); return; return 0; } mutex_lock(&gpd_list_lock); Loading @@ -586,11 +520,7 @@ void pm_genpd_poweroff_unused(void) genpd_queue_power_off_work(genpd); mutex_unlock(&gpd_list_lock); } static int __init genpd_poweroff_unused(void) { pm_genpd_poweroff_unused(); return 0; } late_initcall(genpd_poweroff_unused); Loading Loading @@ -764,7 +694,7 @@ static int pm_genpd_prepare(struct device *dev) /* * The PM domain must be in the GPD_STATE_ACTIVE state at this point, * so pm_genpd_poweron() will return immediately, but if the device * so genpd_poweron() will return immediately, but if the device * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need * to make it operational. */ Loading Loading @@ -1316,18 +1246,6 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, return ret; } /** * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it. * @domain_name: Name of the PM domain to add the device to. * @dev: Device to be added. * @td: Set of PM QoS timing parameters to attach to the device. */ int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td) { return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td); } /** * pm_genpd_remove_device - Remove a device from an I/O PM domain. * @genpd: PM domain to remove the device from. Loading Loading @@ -1428,35 +1346,6 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, return ret; } /** * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain. * @master_name: Name of the master PM domain to add the subdomain to. * @subdomain_name: Name of the subdomain to be added. */ int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name) { struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd; if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name)) return -EINVAL; mutex_lock(&gpd_list_lock); list_for_each_entry(gpd, &gpd_list, gpd_list_node) { if (!master && !strcmp(gpd->name, master_name)) master = gpd; if (!subdomain && !strcmp(gpd->name, subdomain_name)) subdomain = gpd; if (master && subdomain) break; } mutex_unlock(&gpd_list_lock); return pm_genpd_add_subdomain(master, subdomain); } /** * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. * @genpd: Master PM domain to remove the subdomain from. Loading Loading @@ -1504,124 +1393,6 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, return ret; } /** * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle. * @genpd: PM domain to be connected with cpuidle. * @state: cpuidle state this domain can disable/enable. * * Make a PM domain behave as though it contained a CPU core, that is, instead * of calling its power down routine it will enable the given cpuidle state so * that the cpuidle subsystem can power it down (if possible and desirable). */ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) { struct cpuidle_driver *cpuidle_drv; struct gpd_cpuidle_data *cpuidle_data; struct cpuidle_state *idle_state; int ret = 0; if (IS_ERR_OR_NULL(genpd) || state < 0) return -EINVAL; mutex_lock(&genpd->lock); if (genpd->cpuidle_data) { ret = -EEXIST; goto out; } cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL); if (!cpuidle_data) { ret = -ENOMEM; goto out; } cpuidle_drv = cpuidle_driver_ref(); if (!cpuidle_drv) { ret = -ENODEV; goto err_drv; } if (cpuidle_drv->state_count <= state) { ret = -EINVAL; goto err; } idle_state = &cpuidle_drv->states[state]; if (!idle_state->disabled) { ret = -EAGAIN; goto err; } cpuidle_data->idle_state = idle_state; cpuidle_data->saved_exit_latency = idle_state->exit_latency; genpd->cpuidle_data = cpuidle_data; genpd_recalc_cpu_exit_latency(genpd); out: mutex_unlock(&genpd->lock); return ret; err: cpuidle_driver_unref(); err_drv: kfree(cpuidle_data); goto out; } /** * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it. * @name: Name of the domain to connect to cpuidle. * @state: cpuidle state this domain can manipulate. */ int pm_genpd_name_attach_cpuidle(const char *name, int state) { return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state); } /** * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain. * @genpd: PM domain to remove the cpuidle connection from. * * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the * given PM domain. */ int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) { struct gpd_cpuidle_data *cpuidle_data; struct cpuidle_state *idle_state; int ret = 0; if (IS_ERR_OR_NULL(genpd)) return -EINVAL; mutex_lock(&genpd->lock); cpuidle_data = genpd->cpuidle_data; if (!cpuidle_data) { ret = -ENODEV; goto out; } idle_state = cpuidle_data->idle_state; if (!idle_state->disabled) { ret = -EAGAIN; goto out; } idle_state->exit_latency = cpuidle_data->saved_exit_latency; cpuidle_driver_unref(); genpd->cpuidle_data = NULL; kfree(cpuidle_data); out: mutex_unlock(&genpd->lock); return ret; } /** * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it. * @name: Name of the domain to disconnect cpuidle from. */ int pm_genpd_name_detach_cpuidle(const char *name) { return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name)); } /* Default device callbacks for generic PM domains. */ /** Loading Loading @@ -1688,7 +1459,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd, mutex_init(&genpd->lock); genpd->gov = gov; INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); genpd->in_progress = 0; atomic_set(&genpd->sd_count, 0); genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; genpd->device_count = 0; Loading Loading @@ -2023,7 +1793,7 @@ int genpd_dev_pm_attach(struct device *dev) dev->pm_domain->detach = genpd_dev_pm_detach; dev->pm_domain->sync = genpd_dev_pm_sync; ret = pm_genpd_poweron(pd); ret = genpd_poweron(pd); out: return ret ? -EPROBE_DEFER : 0; Loading drivers/soc/dove/pmu.c +0 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,6 @@ int __init dove_init_pmu(void) __pmu_domain_register(domain, np); } pm_genpd_poweroff_unused(); /* Loss of the interrupt controller is not a fatal error. */ parent_irq = irq_of_parse_and_map(pmu->of_node, 0); Loading include/linux/pm_domain.h +0 −64 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/notifier.h> #include <linux/cpuidle.h> /* Defines used for the flags field in the struct generic_pm_domain */ #define GENPD_FLAG_PM_CLK (1U << 0) /* PM domain uses PM clk */ Loading @@ -38,11 +37,6 @@ struct gpd_dev_ops { bool (*active_wakeup)(struct device *dev); }; struct gpd_cpuidle_data { unsigned int saved_exit_latency; struct cpuidle_state *idle_state; }; struct generic_pm_domain { struct dev_pm_domain domain; /* PM domain operations */ struct list_head gpd_list_node; /* Node in the global PM domains list */ Loading @@ -53,7 +47,6 @@ struct generic_pm_domain { struct dev_power_governor *gov; struct work_struct power_off_work; const char *name; unsigned int in_progress; /* Number of devices being suspended now */ atomic_t sd_count; /* Number of subdomains with power "on" */ enum gpd_status status; /* Current state of the domain */ unsigned int device_count; /* Number of devices */ Loading @@ -68,7 +61,6 @@ struct generic_pm_domain { s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; bool cached_power_down_ok; struct gpd_cpuidle_data *cpuidle_data; int (*attach_dev)(struct generic_pm_domain *domain, struct device *dev); void (*detach_dev)(struct generic_pm_domain *domain, Loading Loading @@ -125,29 +117,15 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); extern int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td); extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_subdomain); extern int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); extern int pm_genpd_name_attach_cpuidle(const char *name, int state); extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd); extern int pm_genpd_name_detach_cpuidle(const char *name); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); extern int pm_genpd_poweron(struct generic_pm_domain *genpd); extern int pm_genpd_name_poweron(const char *domain_name); extern void pm_genpd_poweroff_unused(void); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; #else Loading @@ -166,12 +144,6 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, { return -ENOSYS; } static inline int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td) { return -ENOSYS; } static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev) { Loading @@ -182,45 +154,15 @@ static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, { return -ENOSYS; } static inline int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name) { return -ENOSYS; } static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target) { return -ENOSYS; } static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) { return -ENOSYS; } static inline int pm_genpd_name_attach_cpuidle(const char *name, int state) { return -ENOSYS; } static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) { return -ENOSYS; } static inline int pm_genpd_name_detach_cpuidle(const char *name) { return -ENOSYS; } static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { } static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) { return -ENOSYS; } static inline int pm_genpd_name_poweron(const char *domain_name) { return -ENOSYS; } static inline void pm_genpd_poweroff_unused(void) {} #endif static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, Loading @@ -229,12 +171,6 @@ static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, return __pm_genpd_add_device(genpd, dev, NULL); } static inline int pm_genpd_name_add_device(const char *domain_name, struct device *dev) { return __pm_genpd_name_add_device(domain_name, dev, NULL); } #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP extern void pm_genpd_syscore_poweroff(struct device *dev); extern void pm_genpd_syscore_poweron(struct device *dev); Loading Loading
drivers/base/power/domain.c +25 −255 Original line number Diff line number Diff line Loading @@ -53,24 +53,6 @@ static LIST_HEAD(gpd_list); static DEFINE_MUTEX(gpd_list_lock); static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name) { struct generic_pm_domain *genpd = NULL, *gpd; if (IS_ERR_OR_NULL(domain_name)) return NULL; mutex_lock(&gpd_list_lock); list_for_each_entry(gpd, &gpd_list, gpd_list_node) { if (!strcmp(gpd->name, domain_name)) { genpd = gpd; break; } } mutex_unlock(&gpd_list_lock); return genpd; } /* * Get the generic PM domain for a particular struct device. * This validates the struct device pointer, the PM domain pointer, Loading Loading @@ -140,19 +122,6 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) smp_mb__after_atomic(); } static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) { s64 usecs64; if (!genpd->cpuidle_data) return; usecs64 = genpd->power_on_latency_ns; do_div(usecs64, NSEC_PER_USEC); usecs64 += genpd->cpuidle_data->saved_exit_latency; genpd->cpuidle_data->idle_state->exit_latency = usecs64; } static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) { ktime_t time_start; Loading @@ -176,7 +145,6 @@ static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) genpd->power_on_latency_ns = elapsed_ns; genpd->max_off_time_changed = true; genpd_recalc_cpu_exit_latency(genpd); pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", genpd->name, "on", elapsed_ns); Loading Loading @@ -213,10 +181,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool timed) } /** * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff(). * genpd_queue_power_off_work - Queue up the execution of genpd_poweroff(). * @genpd: PM domait to power off. * * Queue up the execution of pm_genpd_poweroff() unless it's already been done * Queue up the execution of genpd_poweroff() unless it's already been done * before. */ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) Loading @@ -224,14 +192,16 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) queue_work(pm_wq, &genpd->power_off_work); } static int genpd_poweron(struct generic_pm_domain *genpd); /** * __pm_genpd_poweron - Restore power to a given PM domain and its masters. * __genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. * * Restore power to @genpd and all of its masters so that it is possible to * resume a device belonging to it. */ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) static int __genpd_poweron(struct generic_pm_domain *genpd) { struct gpd_link *link; int ret = 0; Loading @@ -240,13 +210,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) || (genpd->prepared_count > 0 && genpd->suspend_power_off)) return 0; if (genpd->cpuidle_data) { cpuidle_pause_and_lock(); genpd->cpuidle_data->idle_state->disabled = true; cpuidle_resume_and_unlock(); goto out; } /* * The list is guaranteed not to change while the loop below is being * executed, unless one of the masters' .power_on() callbacks fiddles Loading @@ -255,7 +218,7 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) list_for_each_entry(link, &genpd->slave_links, slave_node) { genpd_sd_counter_inc(link->master); ret = pm_genpd_poweron(link->master); ret = genpd_poweron(link->master); if (ret) { genpd_sd_counter_dec(link->master); goto err; Loading @@ -266,7 +229,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) if (ret) goto err; out: genpd->status = GPD_STATE_ACTIVE; return 0; Loading @@ -282,31 +244,19 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) } /** * pm_genpd_poweron - Restore power to a given PM domain and its masters. * genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. */ int pm_genpd_poweron(struct generic_pm_domain *genpd) static int genpd_poweron(struct generic_pm_domain *genpd) { int ret; mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); ret = __genpd_poweron(genpd); mutex_unlock(&genpd->lock); return ret; } /** * pm_genpd_name_poweron - Restore power to a given PM domain and its masters. * @domain_name: Name of the PM domain to power up. */ int pm_genpd_name_poweron(const char *domain_name) { struct generic_pm_domain *genpd; genpd = pm_genpd_lookup_name(domain_name); return genpd ? pm_genpd_poweron(genpd) : -EINVAL; } static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) { return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, Loading Loading @@ -365,13 +315,14 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, } /** * pm_genpd_poweroff - Remove power from a given PM domain. * genpd_poweroff - Remove power from a given PM domain. * @genpd: PM domain to power down. * @is_async: PM domain is powered down from a scheduled work * * If all of the @genpd's devices have been suspended and all of its subdomains * have been powered down, remove power from @genpd. */ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async) { struct pm_domain_data *pdd; struct gpd_link *link; Loading Loading @@ -403,7 +354,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) not_suspended++; } if (not_suspended > genpd->in_progress) if (not_suspended > 1 || (not_suspended == 1 && is_async)) return -EBUSY; if (genpd->gov && genpd->gov->power_down_ok) { Loading @@ -411,21 +362,6 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) return -EAGAIN; } if (genpd->cpuidle_data) { /* * If cpuidle_data is set, cpuidle should turn the domain off * when the CPU in it is idle. In that case we don't decrement * the subdomain counts of the master domains, so that power is * not removed from the current domain prematurely as a result * of cutting off the masters' power. */ genpd->status = GPD_STATE_POWER_OFF; cpuidle_pause_and_lock(); genpd->cpuidle_data->idle_state->disabled = false; cpuidle_resume_and_unlock(); return 0; } if (genpd->power_off) { int ret; Loading @@ -434,10 +370,10 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) /* * If sd_count > 0 at this point, one of the subdomains hasn't * managed to call pm_genpd_poweron() for the master yet after * incrementing it. In that case pm_genpd_poweron() will wait * managed to call genpd_poweron() for the master yet after * incrementing it. In that case genpd_poweron() will wait * for us to drop the lock, so we can call .power_off() and let * the pm_genpd_poweron() restore power for us (this shouldn't * the genpd_poweron() restore power for us (this shouldn't * happen very often). */ ret = genpd_power_off(genpd, true); Loading Loading @@ -466,7 +402,7 @@ static void genpd_power_off_work_fn(struct work_struct *work) genpd = container_of(work, struct generic_pm_domain, power_off_work); mutex_lock(&genpd->lock); pm_genpd_poweroff(genpd); genpd_poweroff(genpd, true); mutex_unlock(&genpd->lock); } Loading Loading @@ -512,9 +448,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) return 0; mutex_lock(&genpd->lock); genpd->in_progress++; pm_genpd_poweroff(genpd); genpd->in_progress--; genpd_poweroff(genpd, false); mutex_unlock(&genpd->lock); return 0; Loading Loading @@ -547,7 +481,7 @@ static int pm_genpd_runtime_resume(struct device *dev) } mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); ret = __genpd_poweron(genpd); mutex_unlock(&genpd->lock); if (ret) Loading @@ -569,15 +503,15 @@ static int __init pd_ignore_unused_setup(char *__unused) __setup("pd_ignore_unused", pd_ignore_unused_setup); /** * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. * genpd_poweroff_unused - Power off all PM domains with no devices in use. */ void pm_genpd_poweroff_unused(void) static int __init genpd_poweroff_unused(void) { struct generic_pm_domain *genpd; if (pd_ignore_unused) { pr_warn("genpd: Not disabling unused power domains\n"); return; return 0; } mutex_lock(&gpd_list_lock); Loading @@ -586,11 +520,7 @@ void pm_genpd_poweroff_unused(void) genpd_queue_power_off_work(genpd); mutex_unlock(&gpd_list_lock); } static int __init genpd_poweroff_unused(void) { pm_genpd_poweroff_unused(); return 0; } late_initcall(genpd_poweroff_unused); Loading Loading @@ -764,7 +694,7 @@ static int pm_genpd_prepare(struct device *dev) /* * The PM domain must be in the GPD_STATE_ACTIVE state at this point, * so pm_genpd_poweron() will return immediately, but if the device * so genpd_poweron() will return immediately, but if the device * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need * to make it operational. */ Loading Loading @@ -1316,18 +1246,6 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, return ret; } /** * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it. * @domain_name: Name of the PM domain to add the device to. * @dev: Device to be added. * @td: Set of PM QoS timing parameters to attach to the device. */ int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td) { return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td); } /** * pm_genpd_remove_device - Remove a device from an I/O PM domain. * @genpd: PM domain to remove the device from. Loading Loading @@ -1428,35 +1346,6 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, return ret; } /** * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain. * @master_name: Name of the master PM domain to add the subdomain to. * @subdomain_name: Name of the subdomain to be added. */ int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name) { struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd; if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name)) return -EINVAL; mutex_lock(&gpd_list_lock); list_for_each_entry(gpd, &gpd_list, gpd_list_node) { if (!master && !strcmp(gpd->name, master_name)) master = gpd; if (!subdomain && !strcmp(gpd->name, subdomain_name)) subdomain = gpd; if (master && subdomain) break; } mutex_unlock(&gpd_list_lock); return pm_genpd_add_subdomain(master, subdomain); } /** * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. * @genpd: Master PM domain to remove the subdomain from. Loading Loading @@ -1504,124 +1393,6 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, return ret; } /** * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle. * @genpd: PM domain to be connected with cpuidle. * @state: cpuidle state this domain can disable/enable. * * Make a PM domain behave as though it contained a CPU core, that is, instead * of calling its power down routine it will enable the given cpuidle state so * that the cpuidle subsystem can power it down (if possible and desirable). */ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) { struct cpuidle_driver *cpuidle_drv; struct gpd_cpuidle_data *cpuidle_data; struct cpuidle_state *idle_state; int ret = 0; if (IS_ERR_OR_NULL(genpd) || state < 0) return -EINVAL; mutex_lock(&genpd->lock); if (genpd->cpuidle_data) { ret = -EEXIST; goto out; } cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL); if (!cpuidle_data) { ret = -ENOMEM; goto out; } cpuidle_drv = cpuidle_driver_ref(); if (!cpuidle_drv) { ret = -ENODEV; goto err_drv; } if (cpuidle_drv->state_count <= state) { ret = -EINVAL; goto err; } idle_state = &cpuidle_drv->states[state]; if (!idle_state->disabled) { ret = -EAGAIN; goto err; } cpuidle_data->idle_state = idle_state; cpuidle_data->saved_exit_latency = idle_state->exit_latency; genpd->cpuidle_data = cpuidle_data; genpd_recalc_cpu_exit_latency(genpd); out: mutex_unlock(&genpd->lock); return ret; err: cpuidle_driver_unref(); err_drv: kfree(cpuidle_data); goto out; } /** * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it. * @name: Name of the domain to connect to cpuidle. * @state: cpuidle state this domain can manipulate. */ int pm_genpd_name_attach_cpuidle(const char *name, int state) { return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state); } /** * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain. * @genpd: PM domain to remove the cpuidle connection from. * * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the * given PM domain. */ int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) { struct gpd_cpuidle_data *cpuidle_data; struct cpuidle_state *idle_state; int ret = 0; if (IS_ERR_OR_NULL(genpd)) return -EINVAL; mutex_lock(&genpd->lock); cpuidle_data = genpd->cpuidle_data; if (!cpuidle_data) { ret = -ENODEV; goto out; } idle_state = cpuidle_data->idle_state; if (!idle_state->disabled) { ret = -EAGAIN; goto out; } idle_state->exit_latency = cpuidle_data->saved_exit_latency; cpuidle_driver_unref(); genpd->cpuidle_data = NULL; kfree(cpuidle_data); out: mutex_unlock(&genpd->lock); return ret; } /** * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it. * @name: Name of the domain to disconnect cpuidle from. */ int pm_genpd_name_detach_cpuidle(const char *name) { return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name)); } /* Default device callbacks for generic PM domains. */ /** Loading Loading @@ -1688,7 +1459,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd, mutex_init(&genpd->lock); genpd->gov = gov; INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); genpd->in_progress = 0; atomic_set(&genpd->sd_count, 0); genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; genpd->device_count = 0; Loading Loading @@ -2023,7 +1793,7 @@ int genpd_dev_pm_attach(struct device *dev) dev->pm_domain->detach = genpd_dev_pm_detach; dev->pm_domain->sync = genpd_dev_pm_sync; ret = pm_genpd_poweron(pd); ret = genpd_poweron(pd); out: return ret ? -EPROBE_DEFER : 0; Loading
drivers/soc/dove/pmu.c +0 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,6 @@ int __init dove_init_pmu(void) __pmu_domain_register(domain, np); } pm_genpd_poweroff_unused(); /* Loss of the interrupt controller is not a fatal error. */ parent_irq = irq_of_parse_and_map(pmu->of_node, 0); Loading
include/linux/pm_domain.h +0 −64 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/notifier.h> #include <linux/cpuidle.h> /* Defines used for the flags field in the struct generic_pm_domain */ #define GENPD_FLAG_PM_CLK (1U << 0) /* PM domain uses PM clk */ Loading @@ -38,11 +37,6 @@ struct gpd_dev_ops { bool (*active_wakeup)(struct device *dev); }; struct gpd_cpuidle_data { unsigned int saved_exit_latency; struct cpuidle_state *idle_state; }; struct generic_pm_domain { struct dev_pm_domain domain; /* PM domain operations */ struct list_head gpd_list_node; /* Node in the global PM domains list */ Loading @@ -53,7 +47,6 @@ struct generic_pm_domain { struct dev_power_governor *gov; struct work_struct power_off_work; const char *name; unsigned int in_progress; /* Number of devices being suspended now */ atomic_t sd_count; /* Number of subdomains with power "on" */ enum gpd_status status; /* Current state of the domain */ unsigned int device_count; /* Number of devices */ Loading @@ -68,7 +61,6 @@ struct generic_pm_domain { s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; bool cached_power_down_ok; struct gpd_cpuidle_data *cpuidle_data; int (*attach_dev)(struct generic_pm_domain *domain, struct device *dev); void (*detach_dev)(struct generic_pm_domain *domain, Loading Loading @@ -125,29 +117,15 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); extern int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td); extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *new_subdomain); extern int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name); extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target); extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); extern int pm_genpd_name_attach_cpuidle(const char *name, int state); extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd); extern int pm_genpd_name_detach_cpuidle(const char *name); extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); extern int pm_genpd_poweron(struct generic_pm_domain *genpd); extern int pm_genpd_name_poweron(const char *domain_name); extern void pm_genpd_poweroff_unused(void); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; #else Loading @@ -166,12 +144,6 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, { return -ENOSYS; } static inline int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, struct gpd_timing_data *td) { return -ENOSYS; } static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev) { Loading @@ -182,45 +154,15 @@ static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, { return -ENOSYS; } static inline int pm_genpd_add_subdomain_names(const char *master_name, const char *subdomain_name) { return -ENOSYS; } static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *target) { return -ENOSYS; } static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) { return -ENOSYS; } static inline int pm_genpd_name_attach_cpuidle(const char *name, int state) { return -ENOSYS; } static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) { return -ENOSYS; } static inline int pm_genpd_name_detach_cpuidle(const char *name) { return -ENOSYS; } static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { } static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) { return -ENOSYS; } static inline int pm_genpd_name_poweron(const char *domain_name) { return -ENOSYS; } static inline void pm_genpd_poweroff_unused(void) {} #endif static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, Loading @@ -229,12 +171,6 @@ static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, return __pm_genpd_add_device(genpd, dev, NULL); } static inline int pm_genpd_name_add_device(const char *domain_name, struct device *dev) { return __pm_genpd_name_add_device(domain_name, dev, NULL); } #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP extern void pm_genpd_syscore_poweroff(struct device *dev); extern void pm_genpd_syscore_poweron(struct device *dev); Loading