diff options
Diffstat (limited to 'include/linux/pm_domain.h')
| -rw-r--r-- | include/linux/pm_domain.h | 103 | 
1 files changed, 96 insertions, 7 deletions
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 65633e5a2bc..a03a0ad998b 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -10,6 +10,7 @@  #define _LINUX_PM_DOMAIN_H  #include <linux/device.h> +#include <linux/err.h>  enum gpd_status {  	GPD_STATE_ACTIVE = 0,	/* PM domain is active */ @@ -21,6 +22,23 @@ enum gpd_status {  struct dev_power_governor {  	bool (*power_down_ok)(struct dev_pm_domain *domain); +	bool (*stop_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); +	int (*suspend)(struct device *dev); +	int (*suspend_late)(struct device *dev); +	int (*resume_early)(struct device *dev); +	int (*resume)(struct device *dev); +	int (*freeze)(struct device *dev); +	int (*freeze_late)(struct device *dev); +	int (*thaw_early)(struct device *dev); +	int (*thaw)(struct device *dev); +	bool (*active_wakeup)(struct device *dev);  };  struct generic_pm_domain { @@ -32,6 +50,7 @@ struct generic_pm_domain {  	struct mutex lock;  	struct dev_power_governor *gov;  	struct work_struct power_off_work; +	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 */ @@ -44,10 +63,13 @@ struct generic_pm_domain {  	bool suspend_power_off;	/* Power status before system suspend */  	bool dev_irq_safe;	/* Device callbacks are IRQ-safe */  	int (*power_off)(struct generic_pm_domain *domain); +	s64 power_off_latency_ns;  	int (*power_on)(struct generic_pm_domain *domain); -	int (*start_device)(struct device *dev); -	int (*stop_device)(struct device *dev); -	bool (*active_wakeup)(struct device *dev); +	s64 power_on_latency_ns; +	struct gpd_dev_ops dev_ops; +	s64 break_even_ns;	/* Power break even for the entire domain. */ +	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */ +	ktime_t power_off_time;  };  static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) @@ -62,8 +84,18 @@ struct gpd_link {  	struct list_head slave_node;  }; +struct gpd_timing_data { +	s64 stop_latency_ns; +	s64 start_latency_ns; +	s64 save_state_latency_ns; +	s64 restore_state_latency_ns; +	s64 break_even_ns; +}; +  struct generic_pm_domain_data {  	struct pm_domain_data base; +	struct gpd_dev_ops ops; +	struct gpd_timing_data td;  	bool need_restore;  }; @@ -73,18 +105,54 @@ static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *  }  #ifdef CONFIG_PM_GENERIC_DOMAINS -extern int pm_genpd_add_device(struct generic_pm_domain *genpd, -			       struct device *dev); +static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) +{ +	return to_gpd_data(dev->power.subsys_data->domain_data); +} + +extern struct dev_power_governor simple_qos_governor; + +extern struct generic_pm_domain *dev_to_genpd(struct device *dev); +extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, +				 struct device *dev, +				 struct gpd_timing_data *td); + +static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, +				      struct device *dev) +{ +	return __pm_genpd_add_device(genpd, dev, NULL); +} +  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_remove_subdomain(struct generic_pm_domain *genpd,  				     struct generic_pm_domain *target); +extern int pm_genpd_add_callbacks(struct device *dev, +				  struct gpd_dev_ops *ops, +				  struct gpd_timing_data *td); +extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);  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 bool default_stop_ok(struct device *dev); + +extern struct dev_power_governor pm_domain_always_on_gov;  #else + +static inline struct generic_pm_domain *dev_to_genpd(struct device *dev) +{ +	return ERR_PTR(-ENOSYS); +} +static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, +					struct device *dev, +					struct gpd_timing_data *td) +{ +	return -ENOSYS; +}  static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,  				      struct device *dev)  { @@ -105,14 +173,35 @@ static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,  {  	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_add_callbacks(struct device *dev, +					 struct gpd_dev_ops *ops, +					 struct gpd_timing_data *td) +{ +	return -ENOSYS; +} +static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) +{ +	return -ENOSYS; +} +static inline void pm_genpd_init(struct generic_pm_domain *genpd, bool is_off) +{ +}  static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)  {  	return -ENOSYS;  } +static inline bool default_stop_ok(struct device *dev) +{ +	return false; +} +#define pm_domain_always_on_gov NULL  #endif +static inline int pm_genpd_remove_callbacks(struct device *dev) +{ +	return __pm_genpd_remove_callbacks(dev, true); +} +  #ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME  extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd);  extern void pm_genpd_poweroff_unused(void);  |