1
2
3
4
5
6
7
8
9#ifndef _LINUX_PM_DOMAIN_H
10#define _LINUX_PM_DOMAIN_H
11
12#include <linux/device.h>
13#include <linux/mutex.h>
14#include <linux/pm.h>
15#include <linux/err.h>
16#include <linux/of.h>
17#include <linux/notifier.h>
18
19
20#define GENPD_FLAG_PM_CLK (1U << 0)
21
22#define GENPD_MAX_NUM_STATES 8
23
24enum gpd_status {
25 GPD_STATE_ACTIVE = 0,
26 GPD_STATE_POWER_OFF,
27};
28
29struct dev_power_governor {
30 bool (*power_down_ok)(struct dev_pm_domain *domain);
31 bool (*suspend_ok)(struct device *dev);
32};
33
34struct gpd_dev_ops {
35 int (*start)(struct device *dev);
36 int (*stop)(struct device *dev);
37 bool (*active_wakeup)(struct device *dev);
38};
39
40struct genpd_power_state {
41 s64 power_off_latency_ns;
42 s64 power_on_latency_ns;
43};
44
45struct generic_pm_domain {
46 struct dev_pm_domain domain;
47 struct list_head gpd_list_node;
48 struct list_head master_links;
49 struct list_head slave_links;
50 struct list_head dev_list;
51 struct mutex lock;
52 struct dev_power_governor *gov;
53 struct work_struct power_off_work;
54 struct fwnode_handle *provider;
55 bool has_provider;
56 const char *name;
57 atomic_t sd_count;
58 enum gpd_status status;
59 unsigned int device_count;
60 unsigned int suspended_count;
61 unsigned int prepared_count;
62 int (*power_off)(struct generic_pm_domain *domain);
63 int (*power_on)(struct generic_pm_domain *domain);
64 struct gpd_dev_ops dev_ops;
65 s64 max_off_time_ns;
66 bool max_off_time_changed;
67 bool cached_power_down_ok;
68 int (*attach_dev)(struct generic_pm_domain *domain,
69 struct device *dev);
70 void (*detach_dev)(struct generic_pm_domain *domain,
71 struct device *dev);
72 unsigned int flags;
73 struct genpd_power_state states[GENPD_MAX_NUM_STATES];
74 unsigned int state_count;
75 unsigned int state_idx;
76
77};
78
79static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
80{
81 return container_of(pd, struct generic_pm_domain, domain);
82}
83
84struct gpd_link {
85 struct generic_pm_domain *master;
86 struct list_head master_node;
87 struct generic_pm_domain *slave;
88 struct list_head slave_node;
89};
90
91struct gpd_timing_data {
92 s64 suspend_latency_ns;
93 s64 resume_latency_ns;
94 s64 effective_constraint_ns;
95 bool constraint_changed;
96 bool cached_suspend_ok;
97};
98
99struct pm_domain_data {
100 struct list_head list_node;
101 struct device *dev;
102};
103
104struct generic_pm_domain_data {
105 struct pm_domain_data base;
106 struct gpd_timing_data td;
107 struct notifier_block nb;
108};
109
110#ifdef CONFIG_PM_GENERIC_DOMAINS
111static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
112{
113 return container_of(pdd, struct generic_pm_domain_data, base);
114}
115
116static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
117{
118 return to_gpd_data(dev->power.subsys_data->domain_data);
119}
120
121extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
122 struct device *dev,
123 struct gpd_timing_data *td);
124
125extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
126 struct device *dev);
127extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
128 struct generic_pm_domain *new_subdomain);
129extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
130 struct generic_pm_domain *target);
131extern int pm_genpd_init(struct generic_pm_domain *genpd,
132 struct dev_power_governor *gov, bool is_off);
133extern int pm_genpd_remove(struct generic_pm_domain *genpd);
134
135extern struct dev_power_governor simple_qos_governor;
136extern struct dev_power_governor pm_domain_always_on_gov;
137#else
138
139static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
140{
141 return ERR_PTR(-ENOSYS);
142}
143static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
144 struct device *dev,
145 struct gpd_timing_data *td)
146{
147 return -ENOSYS;
148}
149static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
150 struct device *dev)
151{
152 return -ENOSYS;
153}
154static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
155 struct generic_pm_domain *new_sd)
156{
157 return -ENOSYS;
158}
159static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
160 struct generic_pm_domain *target)
161{
162 return -ENOSYS;
163}
164static inline int pm_genpd_init(struct generic_pm_domain *genpd,
165 struct dev_power_governor *gov, bool is_off)
166{
167 return -ENOSYS;
168}
169static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
170{
171 return -ENOTSUPP;
172}
173#endif
174
175static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
176 struct device *dev)
177{
178 return __pm_genpd_add_device(genpd, dev, NULL);
179}
180
181#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
182extern void pm_genpd_syscore_poweroff(struct device *dev);
183extern void pm_genpd_syscore_poweron(struct device *dev);
184#else
185static inline void pm_genpd_syscore_poweroff(struct device *dev) {}
186static inline void pm_genpd_syscore_poweron(struct device *dev) {}
187#endif
188
189
190struct of_device_id;
191
192struct genpd_onecell_data {
193 struct generic_pm_domain **domains;
194 unsigned int num_domains;
195};
196
197#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
198int of_genpd_add_provider_simple(struct device_node *np,
199 struct generic_pm_domain *genpd);
200int of_genpd_add_provider_onecell(struct device_node *np,
201 struct genpd_onecell_data *data);
202void of_genpd_del_provider(struct device_node *np);
203extern int of_genpd_add_device(struct of_phandle_args *args,
204 struct device *dev);
205extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
206 struct of_phandle_args *new_subdomain);
207extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
208
209int genpd_dev_pm_attach(struct device *dev);
210#else
211static inline int of_genpd_add_provider_simple(struct device_node *np,
212 struct generic_pm_domain *genpd)
213{
214 return -ENOTSUPP;
215}
216
217static inline int of_genpd_add_provider_onecell(struct device_node *np,
218 struct genpd_onecell_data *data)
219{
220 return -ENOTSUPP;
221}
222
223static inline void of_genpd_del_provider(struct device_node *np) {}
224
225static inline int of_genpd_add_device(struct of_phandle_args *args,
226 struct device *dev)
227{
228 return -ENODEV;
229}
230
231static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
232 struct of_phandle_args *new_subdomain)
233{
234 return -ENODEV;
235}
236
237static inline int genpd_dev_pm_attach(struct device *dev)
238{
239 return -ENODEV;
240}
241
242static inline
243struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
244{
245 return ERR_PTR(-ENOTSUPP);
246}
247#endif
248
249#ifdef CONFIG_PM
250extern int dev_pm_domain_attach(struct device *dev, bool power_on);
251extern void dev_pm_domain_detach(struct device *dev, bool power_off);
252extern void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
253#else
254static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
255{
256 return -ENODEV;
257}
258static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
259static inline void dev_pm_domain_set(struct device *dev,
260 struct dev_pm_domain *pd) {}
261#endif
262
263#endif
264