0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _LINUX_PM_DOMAIN_H
0009 #define _LINUX_PM_DOMAIN_H
0010
0011 #include <linux/device.h>
0012 #include <linux/ktime.h>
0013 #include <linux/mutex.h>
0014 #include <linux/pm.h>
0015 #include <linux/err.h>
0016 #include <linux/of.h>
0017 #include <linux/notifier.h>
0018 #include <linux/spinlock.h>
0019 #include <linux/cpumask.h>
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #define GENPD_FLAG_PM_CLK (1U << 0)
0065 #define GENPD_FLAG_IRQ_SAFE (1U << 1)
0066 #define GENPD_FLAG_ALWAYS_ON (1U << 2)
0067 #define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3)
0068 #define GENPD_FLAG_CPU_DOMAIN (1U << 4)
0069 #define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
0070 #define GENPD_FLAG_MIN_RESIDENCY (1U << 6)
0071
0072 enum gpd_status {
0073 GENPD_STATE_ON = 0,
0074 GENPD_STATE_OFF,
0075 };
0076
0077 enum genpd_notication {
0078 GENPD_NOTIFY_PRE_OFF = 0,
0079 GENPD_NOTIFY_OFF,
0080 GENPD_NOTIFY_PRE_ON,
0081 GENPD_NOTIFY_ON,
0082 };
0083
0084 struct dev_power_governor {
0085 bool (*power_down_ok)(struct dev_pm_domain *domain);
0086 bool (*suspend_ok)(struct device *dev);
0087 };
0088
0089 struct gpd_dev_ops {
0090 int (*start)(struct device *dev);
0091 int (*stop)(struct device *dev);
0092 };
0093
0094 struct genpd_governor_data {
0095 s64 max_off_time_ns;
0096 bool max_off_time_changed;
0097 ktime_t next_wakeup;
0098 bool cached_power_down_ok;
0099 bool cached_power_down_state_idx;
0100 };
0101
0102 struct genpd_power_state {
0103 s64 power_off_latency_ns;
0104 s64 power_on_latency_ns;
0105 s64 residency_ns;
0106 u64 usage;
0107 u64 rejected;
0108 struct fwnode_handle *fwnode;
0109 u64 idle_time;
0110 void *data;
0111 };
0112
0113 struct genpd_lock_ops;
0114 struct dev_pm_opp;
0115 struct opp_table;
0116
0117 struct generic_pm_domain {
0118 struct device dev;
0119 struct dev_pm_domain domain;
0120 struct list_head gpd_list_node;
0121 struct list_head parent_links;
0122 struct list_head child_links;
0123 struct list_head dev_list;
0124 struct dev_power_governor *gov;
0125 struct genpd_governor_data *gd;
0126 struct work_struct power_off_work;
0127 struct fwnode_handle *provider;
0128 bool has_provider;
0129 const char *name;
0130 atomic_t sd_count;
0131 enum gpd_status status;
0132 unsigned int device_count;
0133 unsigned int suspended_count;
0134 unsigned int prepared_count;
0135 unsigned int performance_state;
0136 cpumask_var_t cpus;
0137 int (*power_off)(struct generic_pm_domain *domain);
0138 int (*power_on)(struct generic_pm_domain *domain);
0139 struct raw_notifier_head power_notifiers;
0140 struct opp_table *opp_table;
0141 unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd,
0142 struct dev_pm_opp *opp);
0143 int (*set_performance_state)(struct generic_pm_domain *genpd,
0144 unsigned int state);
0145 struct gpd_dev_ops dev_ops;
0146 int (*attach_dev)(struct generic_pm_domain *domain,
0147 struct device *dev);
0148 void (*detach_dev)(struct generic_pm_domain *domain,
0149 struct device *dev);
0150 unsigned int flags;
0151 struct genpd_power_state *states;
0152 void (*free_states)(struct genpd_power_state *states,
0153 unsigned int state_count);
0154 unsigned int state_count;
0155 unsigned int state_idx;
0156 u64 on_time;
0157 u64 accounting_time;
0158 const struct genpd_lock_ops *lock_ops;
0159 union {
0160 struct mutex mlock;
0161 struct {
0162 spinlock_t slock;
0163 unsigned long lock_flags;
0164 };
0165 };
0166
0167 };
0168
0169 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
0170 {
0171 return container_of(pd, struct generic_pm_domain, domain);
0172 }
0173
0174 struct gpd_link {
0175 struct generic_pm_domain *parent;
0176 struct list_head parent_node;
0177 struct generic_pm_domain *child;
0178 struct list_head child_node;
0179
0180
0181 unsigned int performance_state;
0182 unsigned int prev_performance_state;
0183 };
0184
0185 struct gpd_timing_data {
0186 s64 suspend_latency_ns;
0187 s64 resume_latency_ns;
0188 s64 effective_constraint_ns;
0189 ktime_t next_wakeup;
0190 bool constraint_changed;
0191 bool cached_suspend_ok;
0192 };
0193
0194 struct pm_domain_data {
0195 struct list_head list_node;
0196 struct device *dev;
0197 };
0198
0199 struct generic_pm_domain_data {
0200 struct pm_domain_data base;
0201 struct gpd_timing_data *td;
0202 struct notifier_block nb;
0203 struct notifier_block *power_nb;
0204 int cpu;
0205 unsigned int performance_state;
0206 unsigned int default_pstate;
0207 unsigned int rpm_pstate;
0208 void *data;
0209 };
0210
0211 #ifdef CONFIG_PM_GENERIC_DOMAINS
0212 static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
0213 {
0214 return container_of(pdd, struct generic_pm_domain_data, base);
0215 }
0216
0217 static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
0218 {
0219 return to_gpd_data(dev->power.subsys_data->domain_data);
0220 }
0221
0222 int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev);
0223 int pm_genpd_remove_device(struct device *dev);
0224 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
0225 struct generic_pm_domain *subdomain);
0226 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
0227 struct generic_pm_domain *subdomain);
0228 int pm_genpd_init(struct generic_pm_domain *genpd,
0229 struct dev_power_governor *gov, bool is_off);
0230 int pm_genpd_remove(struct generic_pm_domain *genpd);
0231 int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
0232 int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb);
0233 int dev_pm_genpd_remove_notifier(struct device *dev);
0234 void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next);
0235
0236 extern struct dev_power_governor simple_qos_governor;
0237 extern struct dev_power_governor pm_domain_always_on_gov;
0238 #ifdef CONFIG_CPU_IDLE
0239 extern struct dev_power_governor pm_domain_cpu_gov;
0240 #endif
0241 #else
0242
0243 static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
0244 {
0245 return ERR_PTR(-ENOSYS);
0246 }
0247 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
0248 struct device *dev)
0249 {
0250 return -ENOSYS;
0251 }
0252 static inline int pm_genpd_remove_device(struct device *dev)
0253 {
0254 return -ENOSYS;
0255 }
0256 static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
0257 struct generic_pm_domain *subdomain)
0258 {
0259 return -ENOSYS;
0260 }
0261 static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
0262 struct generic_pm_domain *subdomain)
0263 {
0264 return -ENOSYS;
0265 }
0266 static inline int pm_genpd_init(struct generic_pm_domain *genpd,
0267 struct dev_power_governor *gov, bool is_off)
0268 {
0269 return -ENOSYS;
0270 }
0271 static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
0272 {
0273 return -EOPNOTSUPP;
0274 }
0275
0276 static inline int dev_pm_genpd_set_performance_state(struct device *dev,
0277 unsigned int state)
0278 {
0279 return -EOPNOTSUPP;
0280 }
0281
0282 static inline int dev_pm_genpd_add_notifier(struct device *dev,
0283 struct notifier_block *nb)
0284 {
0285 return -EOPNOTSUPP;
0286 }
0287
0288 static inline int dev_pm_genpd_remove_notifier(struct device *dev)
0289 {
0290 return -EOPNOTSUPP;
0291 }
0292
0293 static inline void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)
0294 { }
0295
0296 #define simple_qos_governor (*(struct dev_power_governor *)(NULL))
0297 #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
0298 #endif
0299
0300 #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
0301 void dev_pm_genpd_suspend(struct device *dev);
0302 void dev_pm_genpd_resume(struct device *dev);
0303 #else
0304 static inline void dev_pm_genpd_suspend(struct device *dev) {}
0305 static inline void dev_pm_genpd_resume(struct device *dev) {}
0306 #endif
0307
0308
0309 struct of_device_id;
0310
0311 typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
0312 void *data);
0313
0314 struct genpd_onecell_data {
0315 struct generic_pm_domain **domains;
0316 unsigned int num_domains;
0317 genpd_xlate_t xlate;
0318 };
0319
0320 #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
0321 int of_genpd_add_provider_simple(struct device_node *np,
0322 struct generic_pm_domain *genpd);
0323 int of_genpd_add_provider_onecell(struct device_node *np,
0324 struct genpd_onecell_data *data);
0325 void of_genpd_del_provider(struct device_node *np);
0326 int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
0327 int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
0328 struct of_phandle_args *subdomain_spec);
0329 int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
0330 struct of_phandle_args *subdomain_spec);
0331 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
0332 int of_genpd_parse_idle_states(struct device_node *dn,
0333 struct genpd_power_state **states, int *n);
0334 unsigned int pm_genpd_opp_to_performance_state(struct device *genpd_dev,
0335 struct dev_pm_opp *opp);
0336
0337 int genpd_dev_pm_attach(struct device *dev);
0338 struct device *genpd_dev_pm_attach_by_id(struct device *dev,
0339 unsigned int index);
0340 struct device *genpd_dev_pm_attach_by_name(struct device *dev,
0341 const char *name);
0342 #else
0343 static inline int of_genpd_add_provider_simple(struct device_node *np,
0344 struct generic_pm_domain *genpd)
0345 {
0346 return -EOPNOTSUPP;
0347 }
0348
0349 static inline int of_genpd_add_provider_onecell(struct device_node *np,
0350 struct genpd_onecell_data *data)
0351 {
0352 return -EOPNOTSUPP;
0353 }
0354
0355 static inline void of_genpd_del_provider(struct device_node *np) {}
0356
0357 static inline int of_genpd_add_device(struct of_phandle_args *args,
0358 struct device *dev)
0359 {
0360 return -ENODEV;
0361 }
0362
0363 static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
0364 struct of_phandle_args *subdomain_spec)
0365 {
0366 return -ENODEV;
0367 }
0368
0369 static inline int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
0370 struct of_phandle_args *subdomain_spec)
0371 {
0372 return -ENODEV;
0373 }
0374
0375 static inline int of_genpd_parse_idle_states(struct device_node *dn,
0376 struct genpd_power_state **states, int *n)
0377 {
0378 return -ENODEV;
0379 }
0380
0381 static inline unsigned int
0382 pm_genpd_opp_to_performance_state(struct device *genpd_dev,
0383 struct dev_pm_opp *opp)
0384 {
0385 return 0;
0386 }
0387
0388 static inline int genpd_dev_pm_attach(struct device *dev)
0389 {
0390 return 0;
0391 }
0392
0393 static inline struct device *genpd_dev_pm_attach_by_id(struct device *dev,
0394 unsigned int index)
0395 {
0396 return NULL;
0397 }
0398
0399 static inline struct device *genpd_dev_pm_attach_by_name(struct device *dev,
0400 const char *name)
0401 {
0402 return NULL;
0403 }
0404
0405 static inline
0406 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
0407 {
0408 return ERR_PTR(-EOPNOTSUPP);
0409 }
0410 #endif
0411
0412 #ifdef CONFIG_PM
0413 int dev_pm_domain_attach(struct device *dev, bool power_on);
0414 struct device *dev_pm_domain_attach_by_id(struct device *dev,
0415 unsigned int index);
0416 struct device *dev_pm_domain_attach_by_name(struct device *dev,
0417 const char *name);
0418 void dev_pm_domain_detach(struct device *dev, bool power_off);
0419 int dev_pm_domain_start(struct device *dev);
0420 void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
0421 #else
0422 static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
0423 {
0424 return 0;
0425 }
0426 static inline struct device *dev_pm_domain_attach_by_id(struct device *dev,
0427 unsigned int index)
0428 {
0429 return NULL;
0430 }
0431 static inline struct device *dev_pm_domain_attach_by_name(struct device *dev,
0432 const char *name)
0433 {
0434 return NULL;
0435 }
0436 static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
0437 static inline int dev_pm_domain_start(struct device *dev)
0438 {
0439 return 0;
0440 }
0441 static inline void dev_pm_domain_set(struct device *dev,
0442 struct dev_pm_domain *pd) {}
0443 #endif
0444
0445 #endif