Merge branch 'pm-domains'
* pm-domains: PM / Domains: Fix compilation warning related to genpd_start_dev_no_timing() PM / Domains: Operations related to cpuidle using domain names PM / Domains: Document cpuidle-related functions and change their names PM / Domains: Add power-on function using names to identify domains PM / Domains: Make it possible to use names when adding subdomains PM / Domains: Make it possible to use domain names when adding devices
This commit is contained in:
commit
079d364b04
|
@ -53,6 +53,24 @@
|
||||||
static LIST_HEAD(gpd_list);
|
static LIST_HEAD(gpd_list);
|
||||||
static DEFINE_MUTEX(gpd_list_lock);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
struct generic_pm_domain *dev_to_genpd(struct device *dev)
|
struct generic_pm_domain *dev_to_genpd(struct device *dev)
|
||||||
|
@ -75,12 +93,6 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
|
||||||
start_latency_ns, "start");
|
start_latency_ns, "start");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
|
|
||||||
struct device *dev)
|
|
||||||
{
|
|
||||||
return GENPD_DEV_CALLBACK(genpd, int, start, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
|
static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -262,10 +274,28 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
#ifdef CONFIG_PM_RUNTIME
|
#ifdef CONFIG_PM_RUNTIME
|
||||||
|
|
||||||
|
static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
|
||||||
|
struct device *dev)
|
||||||
|
{
|
||||||
|
return GENPD_DEV_CALLBACK(genpd, int, start, dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
|
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
|
||||||
{
|
{
|
||||||
return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
|
return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
|
||||||
|
@ -1465,6 +1495,19 @@ int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
|
||||||
return __pm_genpd_add_device(genpd, dev, td);
|
return __pm_genpd_add_device(genpd, dev, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __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.
|
* pm_genpd_remove_device - Remove a device from an I/O PM domain.
|
||||||
* @genpd: PM domain to remove the device from.
|
* @genpd: PM domain to remove the device from.
|
||||||
|
@ -1557,7 +1600,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
||||||
struct gpd_link *link;
|
struct gpd_link *link;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
|
if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
|
||||||
|
|| genpd == subdomain)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
@ -1603,6 +1647,35 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
||||||
return ret;
|
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.
|
* pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
|
||||||
* @genpd: Master PM domain to remove the subdomain from.
|
* @genpd: Master PM domain to remove the subdomain from.
|
||||||
|
@ -1756,7 +1829,16 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
|
EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
|
||||||
|
|
||||||
int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
|
/**
|
||||||
|
* 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 cpuidle_driver *cpuidle_drv;
|
||||||
struct gpd_cpu_data *cpu_data;
|
struct gpd_cpu_data *cpu_data;
|
||||||
|
@ -1805,7 +1887,24 @@ int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
|
/**
|
||||||
|
* 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_cpu_data *cpu_data;
|
struct gpd_cpu_data *cpu_data;
|
||||||
struct cpuidle_state *idle_state;
|
struct cpuidle_state *idle_state;
|
||||||
|
@ -1836,6 +1935,15 @@ int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
|
||||||
return ret;
|
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. */
|
/* Default device callbacks for generic PM domains. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -138,35 +138,32 @@ extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
struct gpd_timing_data *td);
|
struct gpd_timing_data *td);
|
||||||
|
|
||||||
static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
|
extern int __pm_genpd_name_add_device(const char *domain_name,
|
||||||
struct device *dev)
|
struct device *dev,
|
||||||
{
|
struct gpd_timing_data *td);
|
||||||
return __pm_genpd_add_device(genpd, dev, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
|
|
||||||
struct device *dev)
|
|
||||||
{
|
|
||||||
return __pm_genpd_of_add_device(genpd_node, dev, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
|
extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
|
||||||
struct device *dev);
|
struct device *dev);
|
||||||
extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
|
extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
|
||||||
extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
||||||
struct generic_pm_domain *new_subdomain);
|
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,
|
extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
|
||||||
struct generic_pm_domain *target);
|
struct generic_pm_domain *target);
|
||||||
extern int pm_genpd_add_callbacks(struct device *dev,
|
extern int pm_genpd_add_callbacks(struct device *dev,
|
||||||
struct gpd_dev_ops *ops,
|
struct gpd_dev_ops *ops,
|
||||||
struct gpd_timing_data *td);
|
struct gpd_timing_data *td);
|
||||||
extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
|
extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
|
||||||
extern int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
|
extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
|
||||||
extern int genpd_detach_cpuidle(struct generic_pm_domain *genpd);
|
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,
|
extern void pm_genpd_init(struct generic_pm_domain *genpd,
|
||||||
struct dev_power_governor *gov, bool is_off);
|
struct dev_power_governor *gov, bool is_off);
|
||||||
|
|
||||||
extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
|
extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
|
||||||
|
extern int pm_genpd_name_poweron(const char *domain_name);
|
||||||
|
|
||||||
extern bool default_stop_ok(struct device *dev);
|
extern bool default_stop_ok(struct device *dev);
|
||||||
|
|
||||||
|
@ -187,8 +184,15 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
|
static inline int __pm_genpd_of_add_device(struct device_node *genpd_node,
|
||||||
struct device *dev)
|
struct device *dev,
|
||||||
|
struct gpd_timing_data *td)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
static inline int __pm_genpd_name_add_device(const char *domain_name,
|
||||||
|
struct device *dev,
|
||||||
|
struct gpd_timing_data *td)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -203,6 +207,11 @@ static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
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,
|
static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
|
||||||
struct generic_pm_domain *target)
|
struct generic_pm_domain *target)
|
||||||
{
|
{
|
||||||
|
@ -218,11 +227,19 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
|
static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
|
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;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -234,6 +251,10 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
static inline int pm_genpd_name_poweron(const char *domain_name)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
static inline bool default_stop_ok(struct device *dev)
|
static inline bool default_stop_ok(struct device *dev)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -242,6 +263,24 @@ static inline bool default_stop_ok(struct device *dev)
|
||||||
#define pm_domain_always_on_gov NULL
|
#define pm_domain_always_on_gov NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
|
||||||
|
struct device *dev)
|
||||||
|
{
|
||||||
|
return __pm_genpd_add_device(genpd, dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
|
||||||
|
struct device *dev)
|
||||||
|
{
|
||||||
|
return __pm_genpd_of_add_device(genpd_node, 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);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int pm_genpd_remove_callbacks(struct device *dev)
|
static inline int pm_genpd_remove_callbacks(struct device *dev)
|
||||||
{
|
{
|
||||||
return __pm_genpd_remove_callbacks(dev, true);
|
return __pm_genpd_remove_callbacks(dev, true);
|
||||||
|
|
Loading…
Reference in New Issue