Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */
2 : /*
3 : * pm_domain.h - Definitions and headers related to device power domains.
4 : *
5 : * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
6 : */
7 :
8 : #ifndef _LINUX_PM_DOMAIN_H
9 : #define _LINUX_PM_DOMAIN_H
10 :
11 : #include <linux/device.h>
12 : #include <linux/ktime.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 : #include <linux/spinlock.h>
19 : #include <linux/cpumask.h>
20 :
21 : /*
22 : * Flags to control the behaviour of a genpd.
23 : *
24 : * These flags may be set in the struct generic_pm_domain's flags field by a
25 : * genpd backend driver. The flags must be set before it calls pm_genpd_init(),
26 : * which initializes a genpd.
27 : *
28 : * GENPD_FLAG_PM_CLK: Instructs genpd to use the PM clk framework,
29 : * while powering on/off attached devices.
30 : *
31 : * GENPD_FLAG_IRQ_SAFE: This informs genpd that its backend callbacks,
32 : * ->power_on|off(), doesn't sleep. Hence, these
33 : * can be invoked from within atomic context, which
34 : * enables genpd to power on/off the PM domain,
35 : * even when pm_runtime_is_irq_safe() returns true,
36 : * for any of its attached devices. Note that, a
37 : * genpd having this flag set, requires its
38 : * masterdomains to also have it set.
39 : *
40 : * GENPD_FLAG_ALWAYS_ON: Instructs genpd to always keep the PM domain
41 : * powered on.
42 : *
43 : * GENPD_FLAG_ACTIVE_WAKEUP: Instructs genpd to keep the PM domain powered
44 : * on, in case any of its attached devices is used
45 : * in the wakeup path to serve system wakeups.
46 : *
47 : * GENPD_FLAG_CPU_DOMAIN: Instructs genpd that it should expect to get
48 : * devices attached, which may belong to CPUs or
49 : * possibly have subdomains with CPUs attached.
50 : * This flag enables the genpd backend driver to
51 : * deploy idle power management support for CPUs
52 : * and groups of CPUs. Note that, the backend
53 : * driver must then comply with the so called,
54 : * last-man-standing algorithm, for the CPUs in the
55 : * PM domain.
56 : *
57 : * GENPD_FLAG_RPM_ALWAYS_ON: Instructs genpd to always keep the PM domain
58 : * powered on except for system suspend.
59 : *
60 : * GENPD_FLAG_MIN_RESIDENCY: Enable the genpd governor to consider its
61 : * components' next wakeup when determining the
62 : * optimal idle state.
63 : */
64 : #define GENPD_FLAG_PM_CLK (1U << 0)
65 : #define GENPD_FLAG_IRQ_SAFE (1U << 1)
66 : #define GENPD_FLAG_ALWAYS_ON (1U << 2)
67 : #define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3)
68 : #define GENPD_FLAG_CPU_DOMAIN (1U << 4)
69 : #define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
70 : #define GENPD_FLAG_MIN_RESIDENCY (1U << 6)
71 :
72 : enum gpd_status {
73 : GENPD_STATE_ON = 0, /* PM domain is on */
74 : GENPD_STATE_OFF, /* PM domain is off */
75 : };
76 :
77 : enum genpd_notication {
78 : GENPD_NOTIFY_PRE_OFF = 0,
79 : GENPD_NOTIFY_OFF,
80 : GENPD_NOTIFY_PRE_ON,
81 : GENPD_NOTIFY_ON,
82 : };
83 :
84 : struct dev_power_governor {
85 : bool (*power_down_ok)(struct dev_pm_domain *domain);
86 : bool (*suspend_ok)(struct device *dev);
87 : };
88 :
89 : struct gpd_dev_ops {
90 : int (*start)(struct device *dev);
91 : int (*stop)(struct device *dev);
92 : };
93 :
94 : struct genpd_power_state {
95 : s64 power_off_latency_ns;
96 : s64 power_on_latency_ns;
97 : s64 residency_ns;
98 : u64 usage;
99 : u64 rejected;
100 : struct fwnode_handle *fwnode;
101 : ktime_t idle_time;
102 : void *data;
103 : };
104 :
105 : struct genpd_lock_ops;
106 : struct dev_pm_opp;
107 : struct opp_table;
108 :
109 : struct generic_pm_domain {
110 : struct device dev;
111 : struct dev_pm_domain domain; /* PM domain operations */
112 : struct list_head gpd_list_node; /* Node in the global PM domains list */
113 : struct list_head parent_links; /* Links with PM domain as a parent */
114 : struct list_head child_links; /* Links with PM domain as a child */
115 : struct list_head dev_list; /* List of devices */
116 : struct dev_power_governor *gov;
117 : struct work_struct power_off_work;
118 : struct fwnode_handle *provider; /* Identity of the domain provider */
119 : bool has_provider;
120 : const char *name;
121 : atomic_t sd_count; /* Number of subdomains with power "on" */
122 : enum gpd_status status; /* Current state of the domain */
123 : unsigned int device_count; /* Number of devices */
124 : unsigned int suspended_count; /* System suspend device counter */
125 : unsigned int prepared_count; /* Suspend counter of prepared devices */
126 : unsigned int performance_state; /* Aggregated max performance state */
127 : cpumask_var_t cpus; /* A cpumask of the attached CPUs */
128 : int (*power_off)(struct generic_pm_domain *domain);
129 : int (*power_on)(struct generic_pm_domain *domain);
130 : struct raw_notifier_head power_notifiers; /* Power on/off notifiers */
131 : struct opp_table *opp_table; /* OPP table of the genpd */
132 : unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd,
133 : struct dev_pm_opp *opp);
134 : int (*set_performance_state)(struct generic_pm_domain *genpd,
135 : unsigned int state);
136 : struct gpd_dev_ops dev_ops;
137 : s64 max_off_time_ns; /* Maximum allowed "suspended" time. */
138 : ktime_t next_wakeup; /* Maintained by the domain governor */
139 : bool max_off_time_changed;
140 : bool cached_power_down_ok;
141 : bool cached_power_down_state_idx;
142 : int (*attach_dev)(struct generic_pm_domain *domain,
143 : struct device *dev);
144 : void (*detach_dev)(struct generic_pm_domain *domain,
145 : struct device *dev);
146 : unsigned int flags; /* Bit field of configs for genpd */
147 : struct genpd_power_state *states;
148 : void (*free_states)(struct genpd_power_state *states,
149 : unsigned int state_count);
150 : unsigned int state_count; /* number of states */
151 : unsigned int state_idx; /* state that genpd will go to when off */
152 : ktime_t on_time;
153 : ktime_t accounting_time;
154 : const struct genpd_lock_ops *lock_ops;
155 : union {
156 : struct mutex mlock;
157 : struct {
158 : spinlock_t slock;
159 : unsigned long lock_flags;
160 : };
161 : };
162 :
163 : };
164 :
165 : static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
166 : {
167 : return container_of(pd, struct generic_pm_domain, domain);
168 : }
169 :
170 : struct gpd_link {
171 : struct generic_pm_domain *parent;
172 : struct list_head parent_node;
173 : struct generic_pm_domain *child;
174 : struct list_head child_node;
175 :
176 : /* Sub-domain's per-master domain performance state */
177 : unsigned int performance_state;
178 : unsigned int prev_performance_state;
179 : };
180 :
181 : struct gpd_timing_data {
182 : s64 suspend_latency_ns;
183 : s64 resume_latency_ns;
184 : s64 effective_constraint_ns;
185 : bool constraint_changed;
186 : bool cached_suspend_ok;
187 : };
188 :
189 : struct pm_domain_data {
190 : struct list_head list_node;
191 : struct device *dev;
192 : };
193 :
194 : struct generic_pm_domain_data {
195 : struct pm_domain_data base;
196 : struct gpd_timing_data td;
197 : struct notifier_block nb;
198 : struct notifier_block *power_nb;
199 : int cpu;
200 : unsigned int performance_state;
201 : ktime_t next_wakeup;
202 : void *data;
203 : };
204 :
205 : #ifdef CONFIG_PM_GENERIC_DOMAINS
206 : static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
207 : {
208 : return container_of(pdd, struct generic_pm_domain_data, base);
209 : }
210 :
211 : static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
212 : {
213 : return to_gpd_data(dev->power.subsys_data->domain_data);
214 : }
215 :
216 : int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev);
217 : int pm_genpd_remove_device(struct device *dev);
218 : int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
219 : struct generic_pm_domain *subdomain);
220 : int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
221 : struct generic_pm_domain *subdomain);
222 : int pm_genpd_init(struct generic_pm_domain *genpd,
223 : struct dev_power_governor *gov, bool is_off);
224 : int pm_genpd_remove(struct generic_pm_domain *genpd);
225 : int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
226 : int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb);
227 : int dev_pm_genpd_remove_notifier(struct device *dev);
228 : void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next);
229 :
230 : extern struct dev_power_governor simple_qos_governor;
231 : extern struct dev_power_governor pm_domain_always_on_gov;
232 : #ifdef CONFIG_CPU_IDLE
233 : extern struct dev_power_governor pm_domain_cpu_gov;
234 : #endif
235 : #else
236 :
237 : static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
238 : {
239 : return ERR_PTR(-ENOSYS);
240 : }
241 : static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
242 : struct device *dev)
243 : {
244 : return -ENOSYS;
245 : }
246 : static inline int pm_genpd_remove_device(struct device *dev)
247 : {
248 : return -ENOSYS;
249 : }
250 : static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
251 : struct generic_pm_domain *subdomain)
252 : {
253 : return -ENOSYS;
254 : }
255 : static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
256 : struct generic_pm_domain *subdomain)
257 : {
258 : return -ENOSYS;
259 : }
260 : static inline int pm_genpd_init(struct generic_pm_domain *genpd,
261 : struct dev_power_governor *gov, bool is_off)
262 : {
263 : return -ENOSYS;
264 : }
265 : static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
266 : {
267 : return -EOPNOTSUPP;
268 : }
269 :
270 : static inline int dev_pm_genpd_set_performance_state(struct device *dev,
271 : unsigned int state)
272 : {
273 : return -EOPNOTSUPP;
274 : }
275 :
276 : static inline int dev_pm_genpd_add_notifier(struct device *dev,
277 : struct notifier_block *nb)
278 : {
279 : return -EOPNOTSUPP;
280 : }
281 :
282 : static inline int dev_pm_genpd_remove_notifier(struct device *dev)
283 : {
284 : return -EOPNOTSUPP;
285 : }
286 :
287 : static inline void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)
288 : { }
289 :
290 : #define simple_qos_governor (*(struct dev_power_governor *)(NULL))
291 : #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
292 : #endif
293 :
294 : #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
295 : void dev_pm_genpd_suspend(struct device *dev);
296 : void dev_pm_genpd_resume(struct device *dev);
297 : #else
298 : static inline void dev_pm_genpd_suspend(struct device *dev) {}
299 : static inline void dev_pm_genpd_resume(struct device *dev) {}
300 : #endif
301 :
302 : /* OF PM domain providers */
303 : struct of_device_id;
304 :
305 : typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
306 : void *data);
307 :
308 : struct genpd_onecell_data {
309 : struct generic_pm_domain **domains;
310 : unsigned int num_domains;
311 : genpd_xlate_t xlate;
312 : };
313 :
314 : #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
315 : int of_genpd_add_provider_simple(struct device_node *np,
316 : struct generic_pm_domain *genpd);
317 : int of_genpd_add_provider_onecell(struct device_node *np,
318 : struct genpd_onecell_data *data);
319 : void of_genpd_del_provider(struct device_node *np);
320 : int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
321 : int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
322 : struct of_phandle_args *subdomain_spec);
323 : int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
324 : struct of_phandle_args *subdomain_spec);
325 : struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
326 : int of_genpd_parse_idle_states(struct device_node *dn,
327 : struct genpd_power_state **states, int *n);
328 : unsigned int pm_genpd_opp_to_performance_state(struct device *genpd_dev,
329 : struct dev_pm_opp *opp);
330 :
331 : int genpd_dev_pm_attach(struct device *dev);
332 : struct device *genpd_dev_pm_attach_by_id(struct device *dev,
333 : unsigned int index);
334 : struct device *genpd_dev_pm_attach_by_name(struct device *dev,
335 : const char *name);
336 : #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
337 : static inline int of_genpd_add_provider_simple(struct device_node *np,
338 : struct generic_pm_domain *genpd)
339 : {
340 : return -EOPNOTSUPP;
341 : }
342 :
343 : static inline int of_genpd_add_provider_onecell(struct device_node *np,
344 : struct genpd_onecell_data *data)
345 : {
346 : return -EOPNOTSUPP;
347 : }
348 :
349 : static inline void of_genpd_del_provider(struct device_node *np) {}
350 :
351 : static inline int of_genpd_add_device(struct of_phandle_args *args,
352 : struct device *dev)
353 : {
354 : return -ENODEV;
355 : }
356 :
357 : static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
358 : struct of_phandle_args *subdomain_spec)
359 : {
360 : return -ENODEV;
361 : }
362 :
363 : static inline int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
364 : struct of_phandle_args *subdomain_spec)
365 : {
366 : return -ENODEV;
367 : }
368 :
369 : static inline int of_genpd_parse_idle_states(struct device_node *dn,
370 : struct genpd_power_state **states, int *n)
371 : {
372 : return -ENODEV;
373 : }
374 :
375 : static inline unsigned int
376 : pm_genpd_opp_to_performance_state(struct device *genpd_dev,
377 : struct dev_pm_opp *opp)
378 : {
379 : return 0;
380 : }
381 :
382 : static inline int genpd_dev_pm_attach(struct device *dev)
383 : {
384 : return 0;
385 : }
386 :
387 : static inline struct device *genpd_dev_pm_attach_by_id(struct device *dev,
388 : unsigned int index)
389 : {
390 : return NULL;
391 : }
392 :
393 : static inline struct device *genpd_dev_pm_attach_by_name(struct device *dev,
394 : const char *name)
395 : {
396 : return NULL;
397 : }
398 :
399 : static inline
400 : struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
401 : {
402 : return ERR_PTR(-EOPNOTSUPP);
403 : }
404 : #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
405 :
406 : #ifdef CONFIG_PM
407 : int dev_pm_domain_attach(struct device *dev, bool power_on);
408 : struct device *dev_pm_domain_attach_by_id(struct device *dev,
409 : unsigned int index);
410 : struct device *dev_pm_domain_attach_by_name(struct device *dev,
411 : const char *name);
412 : void dev_pm_domain_detach(struct device *dev, bool power_off);
413 : int dev_pm_domain_start(struct device *dev);
414 : void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
415 : #else
416 4 : static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
417 : {
418 4 : return 0;
419 : }
420 : static inline struct device *dev_pm_domain_attach_by_id(struct device *dev,
421 : unsigned int index)
422 : {
423 : return NULL;
424 : }
425 : static inline struct device *dev_pm_domain_attach_by_name(struct device *dev,
426 : const char *name)
427 : {
428 : return NULL;
429 : }
430 0 : static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
431 : static inline int dev_pm_domain_start(struct device *dev)
432 : {
433 : return 0;
434 : }
435 : static inline void dev_pm_domain_set(struct device *dev,
436 : struct dev_pm_domain *pd) {}
437 : #endif
438 :
439 : #endif /* _LINUX_PM_DOMAIN_H */
|