Blame view

include/linux/pm_domain.h 7.35 KB
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   * pm_domain.h - Definitions and headers related to device power domains.
   *
   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
   *
   * This file is released under the GPLv2.
   */
  
  #ifndef _LINUX_PM_DOMAIN_H
  #define _LINUX_PM_DOMAIN_H
  
  #include <linux/device.h>
313162d0b   Paul Gortmaker   device.h: audit a...
13
14
  #include <linux/mutex.h>
  #include <linux/pm.h>
4f042cdad   Guennadi Liakhovetski   PM / Domains: fix...
15
  #include <linux/err.h>
c8aa130b7   Thomas Abraham   PM / Domains: Add...
16
  #include <linux/of.h>
6ff7bb0d0   Rafael J. Wysocki   PM / Domains: Cac...
17
  #include <linux/notifier.h>
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
18

c11f6f5bb   Ulf Hansson   PM / Domains: Ini...
19
20
  /* Defines used for the flags field in the struct generic_pm_domain */
  #define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */
17b75eca7   Rafael J. Wysocki   PM / Domains: Do ...
21
22
  enum gpd_status {
  	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
17b75eca7   Rafael J. Wysocki   PM / Domains: Do ...
23
24
  	GPD_STATE_POWER_OFF,	/* PM domain is off */
  };
596ba34bc   Rafael J. Wysocki   PM / Domains: Sys...
25

f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
26
27
  struct dev_power_governor {
  	bool (*power_down_ok)(struct dev_pm_domain *domain);
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
28
  	bool (*stop_ok)(struct device *dev);
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
29
  };
d5e4cbfe2   Rafael J. Wysocki   PM / Domains: Mak...
30
31
32
  struct gpd_dev_ops {
  	int (*start)(struct device *dev);
  	int (*stop)(struct device *dev);
ecf00475f   Rafael J. Wysocki   PM / Domains: Int...
33
34
  	int (*save_state)(struct device *dev);
  	int (*restore_state)(struct device *dev);
d5e4cbfe2   Rafael J. Wysocki   PM / Domains: Mak...
35
36
  	bool (*active_wakeup)(struct device *dev);
  };
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
37
38
  struct generic_pm_domain {
  	struct dev_pm_domain domain;	/* PM domain operations */
5125bbf38   Rafael J. Wysocki   PM / Domains: Int...
39
  	struct list_head gpd_list_node;	/* Node in the global PM domains list */
5063ce157   Rafael J. Wysocki   PM / Domains: All...
40
41
  	struct list_head master_links;	/* Links with PM domain as a master */
  	struct list_head slave_links;	/* Links with PM domain as a slave */
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
42
43
44
45
  	struct list_head dev_list;	/* List of devices */
  	struct mutex lock;
  	struct dev_power_governor *gov;
  	struct work_struct power_off_work;
d07e9c178   Geert Uytterhoeven   PM / domains: Mak...
46
  	const char *name;
c4bb3160c   Rafael J. Wysocki   PM / Domains: Imp...
47
  	atomic_t sd_count;	/* Number of subdomains with power "on" */
17b75eca7   Rafael J. Wysocki   PM / Domains: Do ...
48
  	enum gpd_status status;	/* Current state of the domain */
596ba34bc   Rafael J. Wysocki   PM / Domains: Sys...
49
50
51
52
  	unsigned int device_count;	/* Number of devices */
  	unsigned int suspended_count;	/* System suspend device counter */
  	unsigned int prepared_count;	/* Suspend counter of prepared devices */
  	bool suspend_power_off;	/* Power status before system suspend */
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
53
  	int (*power_off)(struct generic_pm_domain *domain);
221e9b583   Rafael J. Wysocki   PM / Domains: Add...
54
  	s64 power_off_latency_ns;
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
55
  	int (*power_on)(struct generic_pm_domain *domain);
221e9b583   Rafael J. Wysocki   PM / Domains: Add...
56
  	s64 power_on_latency_ns;
d5e4cbfe2   Rafael J. Wysocki   PM / Domains: Mak...
57
  	struct gpd_dev_ops dev_ops;
221e9b583   Rafael J. Wysocki   PM / Domains: Add...
58
  	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */
6ff7bb0d0   Rafael J. Wysocki   PM / Domains: Cac...
59
60
  	bool max_off_time_changed;
  	bool cached_power_down_ok;
c16561e8d   Ulf Hansson   PM / Domains: Cha...
61
62
63
64
  	int (*attach_dev)(struct generic_pm_domain *domain,
  			  struct device *dev);
  	void (*detach_dev)(struct generic_pm_domain *domain,
  			   struct device *dev);
c11f6f5bb   Ulf Hansson   PM / Domains: Ini...
65
  	unsigned int flags;		/* Bit field of configs for genpd */
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
66
  };
596ba34bc   Rafael J. Wysocki   PM / Domains: Sys...
67
68
69
70
  static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
  {
  	return container_of(pd, struct generic_pm_domain, domain);
  }
5063ce157   Rafael J. Wysocki   PM / Domains: All...
71
72
73
74
75
76
  struct gpd_link {
  	struct generic_pm_domain *master;
  	struct list_head master_node;
  	struct generic_pm_domain *slave;
  	struct list_head slave_node;
  };
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
77
  struct gpd_timing_data {
2b1d88cda   Ulf Hansson   PM / Domains: Mer...
78
79
  	s64 suspend_latency_ns;
  	s64 resume_latency_ns;
a5bef810a   Rafael J. Wysocki   PM / Domains: Rew...
80
  	s64 effective_constraint_ns;
6ff7bb0d0   Rafael J. Wysocki   PM / Domains: Cac...
81
82
  	bool constraint_changed;
  	bool cached_stop_ok;
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
83
  };
00e7c2959   Ulf Hansson   PM / Domains: Mov...
84
85
86
87
  struct pm_domain_data {
  	struct list_head list_node;
  	struct device *dev;
  };
cd0ea672f   Rafael J. Wysocki   PM / Domains: Spl...
88
89
  struct generic_pm_domain_data {
  	struct pm_domain_data base;
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
90
  	struct gpd_timing_data td;
6ff7bb0d0   Rafael J. Wysocki   PM / Domains: Cac...
91
  	struct notifier_block nb;
cd0ea672f   Rafael J. Wysocki   PM / Domains: Spl...
92
  };
9b4f617b1   Guennadi Liakhovetski   PM / Domains: Pro...
93
  #ifdef CONFIG_PM_GENERIC_DOMAINS
cd0ea672f   Rafael J. Wysocki   PM / Domains: Spl...
94
95
96
97
  static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
  {
  	return container_of(pdd, struct generic_pm_domain_data, base);
  }
d5e4cbfe2   Rafael J. Wysocki   PM / Domains: Mak...
98
99
100
101
  static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
  {
  	return to_gpd_data(dev->power.subsys_data->domain_data);
  }
446d999c1   Russell King   PM / domains: fac...
102
  extern struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev);
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
103
104
105
  extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
  				 struct device *dev,
  				 struct gpd_timing_data *td);
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
106
107
108
109
110
111
112
113
  extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
  				  struct device *dev);
  extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
  				  struct generic_pm_domain *new_subdomain);
  extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
  				     struct generic_pm_domain *target);
  extern void pm_genpd_init(struct generic_pm_domain *genpd,
  			  struct dev_power_governor *gov, bool is_off);
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
114

ae3c511c2   Ulf Hansson   PM / domains: Kee...
115
  extern struct dev_power_governor simple_qos_governor;
925b44a27   Mark Brown   PM / Domains: Pro...
116
  extern struct dev_power_governor pm_domain_always_on_gov;
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
117
  #else
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
118

b642631d3   Magnus Damm   PM / Domains: Fix...
119
120
121
122
  static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
  {
  	return ERR_PTR(-ENOSYS);
  }
446d999c1   Russell King   PM / domains: fac...
123
  static inline struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev)
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
124
  {
446d999c1   Russell King   PM / domains: fac...
125
  	return NULL;
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
126
127
128
129
130
131
132
  }
  static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
  					struct device *dev,
  					struct gpd_timing_data *td)
  {
  	return -ENOSYS;
  }
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
  					 struct device *dev)
  {
  	return -ENOSYS;
  }
  static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
  					 struct generic_pm_domain *new_sd)
  {
  	return -ENOSYS;
  }
  static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
  					    struct generic_pm_domain *target)
  {
  	return -ENOSYS;
  }
b642631d3   Magnus Damm   PM / Domains: Fix...
148
149
  static inline void pm_genpd_init(struct generic_pm_domain *genpd,
  				 struct dev_power_governor *gov, bool is_off)
b02c999ac   Rafael J. Wysocki   PM / Domains: Add...
150
151
  {
  }
17f2ae7f6   Rafael J. Wysocki   PM / Domains: Fix...
152
  #endif
b5abb085f   Rafael J. Wysocki   PM / Domains: Mak...
153
154
155
156
157
  static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
  				      struct device *dev)
  {
  	return __pm_genpd_add_device(genpd, dev, NULL);
  }
77f827de0   Rafael J. Wysocki   PM / Domains: Add...
158
  #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
d47e6464a   Ulf Hansson   PM / domains: Rem...
159
160
  extern void pm_genpd_syscore_poweroff(struct device *dev);
  extern void pm_genpd_syscore_poweron(struct device *dev);
77f827de0   Rafael J. Wysocki   PM / Domains: Add...
161
  #else
d47e6464a   Ulf Hansson   PM / domains: Rem...
162
163
  static inline void pm_genpd_syscore_poweroff(struct device *dev) {}
  static inline void pm_genpd_syscore_poweron(struct device *dev) {}
77f827de0   Rafael J. Wysocki   PM / Domains: Add...
164
  #endif
aa42240ab   Tomasz Figa   PM / Domains: Add...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  /* OF PM domain providers */
  struct of_device_id;
  
  struct genpd_onecell_data {
  	struct generic_pm_domain **domains;
  	unsigned int num_domains;
  };
  
  typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
  						void *data);
  
  #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
  int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
  			void *data);
  void of_genpd_del_provider(struct device_node *np);
7496fcbe8   Amit Daniel Kachhap   PM / Domains: Exp...
180
181
  struct generic_pm_domain *of_genpd_get_from_provider(
  			struct of_phandle_args *genpdspec);
aa42240ab   Tomasz Figa   PM / Domains: Add...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  
  struct generic_pm_domain *__of_genpd_xlate_simple(
  					struct of_phandle_args *genpdspec,
  					void *data);
  struct generic_pm_domain *__of_genpd_xlate_onecell(
  					struct of_phandle_args *genpdspec,
  					void *data);
  
  int genpd_dev_pm_attach(struct device *dev);
  #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
  static inline int __of_genpd_add_provider(struct device_node *np,
  					genpd_xlate_t xlate, void *data)
  {
  	return 0;
  }
  static inline void of_genpd_del_provider(struct device_node *np) {}
7496fcbe8   Amit Daniel Kachhap   PM / Domains: Exp...
198
199
200
201
202
  static inline struct generic_pm_domain *of_genpd_get_from_provider(
  			struct of_phandle_args *genpdspec)
  {
  	return NULL;
  }
aa42240ab   Tomasz Figa   PM / Domains: Add...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  #define __of_genpd_xlate_simple		NULL
  #define __of_genpd_xlate_onecell	NULL
  
  static inline int genpd_dev_pm_attach(struct device *dev)
  {
  	return -ENODEV;
  }
  #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
  
  static inline int of_genpd_add_provider_simple(struct device_node *np,
  					struct generic_pm_domain *genpd)
  {
  	return __of_genpd_add_provider(np, __of_genpd_xlate_simple, genpd);
  }
  static inline int of_genpd_add_provider_onecell(struct device_node *np,
  					struct genpd_onecell_data *data)
  {
  	return __of_genpd_add_provider(np, __of_genpd_xlate_onecell, data);
  }
f48c767ce   Ulf Hansson   PM / Domains: Mov...
222
223
224
225
226
227
228
229
230
231
  #ifdef CONFIG_PM
  extern int dev_pm_domain_attach(struct device *dev, bool power_on);
  extern void dev_pm_domain_detach(struct device *dev, bool power_off);
  #else
  static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
  {
  	return -ENODEV;
  }
  static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
  #endif
f721889ff   Rafael J. Wysocki   PM / Domains: Sup...
232
  #endif /* _LINUX_PM_DOMAIN_H */