1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * pm_domain.h - Definitions and headers related to device power domains.
5 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
8 #ifndef _LINUX_PM_DOMAIN_H
9 #define _LINUX_PM_DOMAIN_H
11 #include <linux/device.h>
12 #include <linux/ktime.h>
13 #include <linux/mutex.h>
15 #include <linux/err.h>
17 #include <linux/notifier.h>
18 #include <linux/spinlock.h>
19 #include <linux/cpumask.h>
22 * Flags to control the behaviour of a genpd.
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.
28 * GENPD_FLAG_PM_CLK: Instructs genpd to use the PM clk framework,
29 * while powering on/off attached devices.
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.
40 * GENPD_FLAG_ALWAYS_ON: Instructs genpd to always keep the PM domain
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.
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
57 * GENPD_FLAG_RPM_ALWAYS_ON: Instructs genpd to always keep the PM domain
58 * powered on except for system suspend.
60 * GENPD_FLAG_MIN_RESIDENCY: Enable the genpd governor to consider its
61 * components' next wakeup when determining the
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)
73 GENPD_STATE_ON
= 0, /* PM domain is on */
74 GENPD_STATE_OFF
, /* PM domain is off */
77 enum genpd_notication
{
78 GENPD_NOTIFY_PRE_OFF
= 0,
84 struct dev_power_governor
{
85 bool (*power_down_ok
)(struct dev_pm_domain
*domain
);
86 bool (*suspend_ok
)(struct device
*dev
);
90 int (*start
)(struct device
*dev
);
91 int (*stop
)(struct device
*dev
);
94 struct genpd_power_state
{
95 s64 power_off_latency_ns
;
96 s64 power_on_latency_ns
;
100 struct fwnode_handle
*fwnode
;
105 struct genpd_lock_ops
;
109 struct generic_pm_domain
{
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 */
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
,
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
,
144 void (*detach_dev
)(struct generic_pm_domain
*domain
,
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 */
153 ktime_t accounting_time
;
154 const struct genpd_lock_ops
*lock_ops
;
159 unsigned long lock_flags
;
165 static inline struct generic_pm_domain
*pd_to_genpd(struct dev_pm_domain
*pd
)
167 return container_of(pd
, struct generic_pm_domain
, domain
);
171 struct generic_pm_domain
*parent
;
172 struct list_head parent_node
;
173 struct generic_pm_domain
*child
;
174 struct list_head child_node
;
176 /* Sub-domain's per-master domain performance state */
177 unsigned int performance_state
;
178 unsigned int prev_performance_state
;
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
;
189 struct pm_domain_data
{
190 struct list_head list_node
;
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
;
200 unsigned int performance_state
;
205 #ifdef CONFIG_PM_GENERIC_DOMAINS
206 static inline struct generic_pm_domain_data
*to_gpd_data(struct pm_domain_data
*pdd
)
208 return container_of(pdd
, struct generic_pm_domain_data
, base
);
211 static inline struct generic_pm_domain_data
*dev_gpd_data(struct device
*dev
)
213 return to_gpd_data(dev
->power
.subsys_data
->domain_data
);
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
);
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
;
237 static inline struct generic_pm_domain_data
*dev_gpd_data(struct device
*dev
)
239 return ERR_PTR(-ENOSYS
);
241 static inline int pm_genpd_add_device(struct generic_pm_domain
*genpd
,
246 static inline int pm_genpd_remove_device(struct device
*dev
)
250 static inline int pm_genpd_add_subdomain(struct generic_pm_domain
*genpd
,
251 struct generic_pm_domain
*subdomain
)
255 static inline int pm_genpd_remove_subdomain(struct generic_pm_domain
*genpd
,
256 struct generic_pm_domain
*subdomain
)
260 static inline int pm_genpd_init(struct generic_pm_domain
*genpd
,
261 struct dev_power_governor
*gov
, bool is_off
)
265 static inline int pm_genpd_remove(struct generic_pm_domain
*genpd
)
270 static inline int dev_pm_genpd_set_performance_state(struct device
*dev
,
276 static inline int dev_pm_genpd_add_notifier(struct device
*dev
,
277 struct notifier_block
*nb
)
282 static inline int dev_pm_genpd_remove_notifier(struct device
*dev
)
287 static inline void dev_pm_genpd_set_next_wakeup(struct device
*dev
, ktime_t next
)
290 #define simple_qos_governor (*(struct dev_power_governor *)(NULL))
291 #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
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
);
298 static inline void dev_pm_genpd_suspend(struct device
*dev
) {}
299 static inline void dev_pm_genpd_resume(struct device
*dev
) {}
302 /* OF PM domain providers */
305 typedef struct generic_pm_domain
*(*genpd_xlate_t
)(struct of_phandle_args
*args
,
308 struct genpd_onecell_data
{
309 struct generic_pm_domain
**domains
;
310 unsigned int num_domains
;
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
);
331 int genpd_dev_pm_attach(struct device
*dev
);
332 struct device
*genpd_dev_pm_attach_by_id(struct device
*dev
,
334 struct device
*genpd_dev_pm_attach_by_name(struct device
*dev
,
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
)
343 static inline int of_genpd_add_provider_onecell(struct device_node
*np
,
344 struct genpd_onecell_data
*data
)
349 static inline void of_genpd_del_provider(struct device_node
*np
) {}
351 static inline int of_genpd_add_device(struct of_phandle_args
*args
,
357 static inline int of_genpd_add_subdomain(struct of_phandle_args
*parent_spec
,
358 struct of_phandle_args
*subdomain_spec
)
363 static inline int of_genpd_remove_subdomain(struct of_phandle_args
*parent_spec
,
364 struct of_phandle_args
*subdomain_spec
)
369 static inline int of_genpd_parse_idle_states(struct device_node
*dn
,
370 struct genpd_power_state
**states
, int *n
)
375 static inline unsigned int
376 pm_genpd_opp_to_performance_state(struct device
*genpd_dev
,
377 struct dev_pm_opp
*opp
)
382 static inline int genpd_dev_pm_attach(struct device
*dev
)
387 static inline struct device
*genpd_dev_pm_attach_by_id(struct device
*dev
,
393 static inline struct device
*genpd_dev_pm_attach_by_name(struct device
*dev
,
400 struct generic_pm_domain
*of_genpd_remove_last(struct device_node
*np
)
402 return ERR_PTR(-EOPNOTSUPP
);
404 #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
407 int dev_pm_domain_attach(struct device
*dev
, bool power_on
);
408 struct device
*dev_pm_domain_attach_by_id(struct device
*dev
,
410 struct device
*dev_pm_domain_attach_by_name(struct device
*dev
,
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
);
416 static inline int dev_pm_domain_attach(struct device
*dev
, bool power_on
)
420 static inline struct device
*dev_pm_domain_attach_by_id(struct device
*dev
,
425 static inline struct device
*dev_pm_domain_attach_by_name(struct device
*dev
,
430 static inline void dev_pm_domain_detach(struct device
*dev
, bool power_off
) {}
431 static inline int dev_pm_domain_start(struct device
*dev
)
435 static inline void dev_pm_domain_set(struct device
*dev
,
436 struct dev_pm_domain
*pd
) {}
439 #endif /* _LINUX_PM_DOMAIN_H */