PM / Domains: Make device removal more straightforward
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / include / linux / pm_domain.h
CommitLineData
f721889f
RW
1/*
2 * pm_domain.h - Definitions and headers related to device power domains.
3 *
4 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#ifndef _LINUX_PM_DOMAIN_H
10#define _LINUX_PM_DOMAIN_H
11
12#include <linux/device.h>
313162d0
PG
13#include <linux/mutex.h>
14#include <linux/pm.h>
4f042cda 15#include <linux/err.h>
c8aa130b 16#include <linux/of.h>
f721889f 17
17b75eca
RW
18enum gpd_status {
19 GPD_STATE_ACTIVE = 0, /* PM domain is active */
17877eb5 20 GPD_STATE_WAIT_MASTER, /* PM domain's master is being waited for */
17b75eca 21 GPD_STATE_BUSY, /* Something is happening to the PM domain */
c6d22b37 22 GPD_STATE_REPEAT, /* Power off in progress, to be repeated */
17b75eca
RW
23 GPD_STATE_POWER_OFF, /* PM domain is off */
24};
596ba34b 25
f721889f
RW
26struct dev_power_governor {
27 bool (*power_down_ok)(struct dev_pm_domain *domain);
b02c999a 28 bool (*stop_ok)(struct device *dev);
f721889f
RW
29};
30
d5e4cbfe
RW
31struct gpd_dev_ops {
32 int (*start)(struct device *dev);
33 int (*stop)(struct device *dev);
ecf00475
RW
34 int (*save_state)(struct device *dev);
35 int (*restore_state)(struct device *dev);
d23b9b00
RW
36 int (*suspend)(struct device *dev);
37 int (*suspend_late)(struct device *dev);
38 int (*resume_early)(struct device *dev);
39 int (*resume)(struct device *dev);
40 int (*freeze)(struct device *dev);
41 int (*freeze_late)(struct device *dev);
42 int (*thaw_early)(struct device *dev);
43 int (*thaw)(struct device *dev);
d5e4cbfe
RW
44 bool (*active_wakeup)(struct device *dev);
45};
46
f721889f
RW
47struct generic_pm_domain {
48 struct dev_pm_domain domain; /* PM domain operations */
5125bbf3 49 struct list_head gpd_list_node; /* Node in the global PM domains list */
5063ce15
RW
50 struct list_head master_links; /* Links with PM domain as a master */
51 struct list_head slave_links; /* Links with PM domain as a slave */
f721889f
RW
52 struct list_head dev_list; /* List of devices */
53 struct mutex lock;
54 struct dev_power_governor *gov;
55 struct work_struct power_off_work;
e84b2c20 56 char *name;
f721889f 57 unsigned int in_progress; /* Number of devices being suspended now */
c4bb3160 58 atomic_t sd_count; /* Number of subdomains with power "on" */
17b75eca
RW
59 enum gpd_status status; /* Current state of the domain */
60 wait_queue_head_t status_wait_queue;
c6d22b37
RW
61 struct task_struct *poweroff_task; /* Powering off task */
62 unsigned int resume_count; /* Number of devices being resumed */
596ba34b
RW
63 unsigned int device_count; /* Number of devices */
64 unsigned int suspended_count; /* System suspend device counter */
65 unsigned int prepared_count; /* Suspend counter of prepared devices */
66 bool suspend_power_off; /* Power status before system suspend */
0aa2a221 67 bool dev_irq_safe; /* Device callbacks are IRQ-safe */
f721889f 68 int (*power_off)(struct generic_pm_domain *domain);
221e9b58 69 s64 power_off_latency_ns;
f721889f 70 int (*power_on)(struct generic_pm_domain *domain);
221e9b58 71 s64 power_on_latency_ns;
d5e4cbfe 72 struct gpd_dev_ops dev_ops;
221e9b58 73 s64 max_off_time_ns; /* Maximum allowed "suspended" time. */
c8aa130b 74 struct device_node *of_node; /* Node in device tree */
f721889f
RW
75};
76
596ba34b
RW
77static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
78{
79 return container_of(pd, struct generic_pm_domain, domain);
80}
81
5063ce15
RW
82struct gpd_link {
83 struct generic_pm_domain *master;
84 struct list_head master_node;
85 struct generic_pm_domain *slave;
86 struct list_head slave_node;
87};
88
b02c999a
RW
89struct gpd_timing_data {
90 s64 stop_latency_ns;
91 s64 start_latency_ns;
221e9b58
RW
92 s64 save_state_latency_ns;
93 s64 restore_state_latency_ns;
a5bef810 94 s64 effective_constraint_ns;
b02c999a
RW
95};
96
cd0ea672
RW
97struct generic_pm_domain_data {
98 struct pm_domain_data base;
d5e4cbfe 99 struct gpd_dev_ops ops;
b02c999a 100 struct gpd_timing_data td;
cd0ea672 101 bool need_restore;
1e78a0c7 102 bool always_on;
cd0ea672
RW
103};
104
9b4f617b 105#ifdef CONFIG_PM_GENERIC_DOMAINS
cd0ea672
RW
106static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
107{
108 return container_of(pdd, struct generic_pm_domain_data, base);
109}
110
d5e4cbfe
RW
111static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
112{
113 return to_gpd_data(dev->power.subsys_data->domain_data);
114}
115
b02c999a
RW
116extern struct dev_power_governor simple_qos_governor;
117
118extern struct generic_pm_domain *dev_to_genpd(struct device *dev);
119extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
120 struct device *dev,
121 struct gpd_timing_data *td);
122
c8aa130b
TA
123extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
124 struct device *dev,
125 struct gpd_timing_data *td);
126
b02c999a
RW
127static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
128 struct device *dev)
129{
130 return __pm_genpd_add_device(genpd, dev, NULL);
131}
132
c8aa130b
TA
133static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
134 struct device *dev)
135{
136 return __pm_genpd_of_add_device(genpd_node, dev, NULL);
137}
138
f721889f
RW
139extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
140 struct device *dev);
1e78a0c7 141extern void pm_genpd_dev_always_on(struct device *dev, bool val);
f721889f
RW
142extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
143 struct generic_pm_domain *new_subdomain);
144extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
145 struct generic_pm_domain *target);
b02c999a
RW
146extern int pm_genpd_add_callbacks(struct device *dev,
147 struct gpd_dev_ops *ops,
148 struct gpd_timing_data *td);
149extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
f721889f
RW
150extern void pm_genpd_init(struct generic_pm_domain *genpd,
151 struct dev_power_governor *gov, bool is_off);
b02c999a 152
18b4f3f5 153extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
b02c999a
RW
154
155extern bool default_stop_ok(struct device *dev);
156
925b44a2 157extern struct dev_power_governor pm_domain_always_on_gov;
f721889f 158#else
b02c999a 159
b642631d
MD
160static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
161{
162 return ERR_PTR(-ENOSYS);
163}
b02c999a
RW
164static inline struct generic_pm_domain *dev_to_genpd(struct device *dev)
165{
166 return ERR_PTR(-ENOSYS);
167}
168static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
169 struct device *dev,
170 struct gpd_timing_data *td)
171{
172 return -ENOSYS;
173}
f721889f
RW
174static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
175 struct device *dev)
176{
177 return -ENOSYS;
178}
179static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
180 struct device *dev)
181{
182 return -ENOSYS;
183}
1e78a0c7 184static inline void pm_genpd_dev_always_on(struct device *dev, bool val) {}
f721889f
RW
185static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
186 struct generic_pm_domain *new_sd)
187{
188 return -ENOSYS;
189}
190static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
191 struct generic_pm_domain *target)
192{
193 return -ENOSYS;
194}
d5e4cbfe 195static inline int pm_genpd_add_callbacks(struct device *dev,
b02c999a
RW
196 struct gpd_dev_ops *ops,
197 struct gpd_timing_data *td)
d5e4cbfe
RW
198{
199 return -ENOSYS;
200}
b02c999a 201static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
d5e4cbfe
RW
202{
203 return -ENOSYS;
204}
b642631d
MD
205static inline void pm_genpd_init(struct generic_pm_domain *genpd,
206 struct dev_power_governor *gov, bool is_off)
b02c999a
RW
207{
208}
18b4f3f5
MD
209static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
210{
211 return -ENOSYS;
212}
b02c999a
RW
213static inline bool default_stop_ok(struct device *dev)
214{
215 return false;
216}
b642631d 217#define simple_qos_governor NULL
925b44a2 218#define pm_domain_always_on_gov NULL
17f2ae7f
RW
219#endif
220
b02c999a
RW
221static inline int pm_genpd_remove_callbacks(struct device *dev)
222{
223 return __pm_genpd_remove_callbacks(dev, true);
224}
225
17f2ae7f
RW
226#ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME
227extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd);
228extern void pm_genpd_poweroff_unused(void);
229#else
0bc5b2de 230static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
17f2ae7f 231static inline void pm_genpd_poweroff_unused(void) {}
f721889f
RW
232#endif
233
234#endif /* _LINUX_PM_DOMAIN_H */