Blame view
include/linux/pm_domain.h
7.35 KB
f721889ff
|
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
|
13 14 |
#include <linux/mutex.h> #include <linux/pm.h> |
4f042cdad
|
15 |
#include <linux/err.h> |
c8aa130b7
|
16 |
#include <linux/of.h> |
6ff7bb0d0
|
17 |
#include <linux/notifier.h> |
f721889ff
|
18 |
|
c11f6f5bb
|
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
|
21 22 |
enum gpd_status { GPD_STATE_ACTIVE = 0, /* PM domain is active */ |
17b75eca7
|
23 24 |
GPD_STATE_POWER_OFF, /* PM domain is off */ }; |
596ba34bc
|
25 |
|
f721889ff
|
26 27 |
struct dev_power_governor { bool (*power_down_ok)(struct dev_pm_domain *domain); |
b02c999ac
|
28 |
bool (*stop_ok)(struct device *dev); |
f721889ff
|
29 |
}; |
d5e4cbfe2
|
30 31 32 |
struct gpd_dev_ops { int (*start)(struct device *dev); int (*stop)(struct device *dev); |
ecf00475f
|
33 34 |
int (*save_state)(struct device *dev); int (*restore_state)(struct device *dev); |
d5e4cbfe2
|
35 36 |
bool (*active_wakeup)(struct device *dev); }; |
f721889ff
|
37 38 |
struct generic_pm_domain { struct dev_pm_domain domain; /* PM domain operations */ |
5125bbf38
|
39 |
struct list_head gpd_list_node; /* Node in the global PM domains list */ |
5063ce157
|
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
|
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
|
46 |
const char *name; |
c4bb3160c
|
47 |
atomic_t sd_count; /* Number of subdomains with power "on" */ |
17b75eca7
|
48 |
enum gpd_status status; /* Current state of the domain */ |
596ba34bc
|
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
|
53 |
int (*power_off)(struct generic_pm_domain *domain); |
221e9b583
|
54 |
s64 power_off_latency_ns; |
f721889ff
|
55 |
int (*power_on)(struct generic_pm_domain *domain); |
221e9b583
|
56 |
s64 power_on_latency_ns; |
d5e4cbfe2
|
57 |
struct gpd_dev_ops dev_ops; |
221e9b583
|
58 |
s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ |
6ff7bb0d0
|
59 60 |
bool max_off_time_changed; bool cached_power_down_ok; |
c16561e8d
|
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
|
65 |
unsigned int flags; /* Bit field of configs for genpd */ |
f721889ff
|
66 |
}; |
596ba34bc
|
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
|
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
|
77 |
struct gpd_timing_data { |
2b1d88cda
|
78 79 |
s64 suspend_latency_ns; s64 resume_latency_ns; |
a5bef810a
|
80 |
s64 effective_constraint_ns; |
6ff7bb0d0
|
81 82 |
bool constraint_changed; bool cached_stop_ok; |
b02c999ac
|
83 |
}; |
00e7c2959
|
84 85 86 87 |
struct pm_domain_data { struct list_head list_node; struct device *dev; }; |
cd0ea672f
|
88 89 |
struct generic_pm_domain_data { struct pm_domain_data base; |
b02c999ac
|
90 |
struct gpd_timing_data td; |
6ff7bb0d0
|
91 |
struct notifier_block nb; |
cd0ea672f
|
92 |
}; |
9b4f617b1
|
93 |
#ifdef CONFIG_PM_GENERIC_DOMAINS |
cd0ea672f
|
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
|
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
|
102 |
extern struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev); |
b02c999ac
|
103 104 105 |
extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); |
f721889ff
|
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
|
114 |
|
ae3c511c2
|
115 |
extern struct dev_power_governor simple_qos_governor; |
925b44a27
|
116 |
extern struct dev_power_governor pm_domain_always_on_gov; |
f721889ff
|
117 |
#else |
b02c999ac
|
118 |
|
b642631d3
|
119 120 121 122 |
static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) { return ERR_PTR(-ENOSYS); } |
446d999c1
|
123 |
static inline struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev) |
b02c999ac
|
124 |
{ |
446d999c1
|
125 |
return NULL; |
b02c999ac
|
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
|
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
|
148 149 |
static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) |
b02c999ac
|
150 151 |
{ } |
17f2ae7f6
|
152 |
#endif |
b5abb085f
|
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
|
158 |
#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP |
d47e6464a
|
159 160 |
extern void pm_genpd_syscore_poweroff(struct device *dev); extern void pm_genpd_syscore_poweron(struct device *dev); |
77f827de0
|
161 |
#else |
d47e6464a
|
162 163 |
static inline void pm_genpd_syscore_poweroff(struct device *dev) {} static inline void pm_genpd_syscore_poweron(struct device *dev) {} |
77f827de0
|
164 |
#endif |
aa42240ab
|
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
|
180 181 |
struct generic_pm_domain *of_genpd_get_from_provider( struct of_phandle_args *genpdspec); |
aa42240ab
|
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
|
198 199 200 201 202 |
static inline struct generic_pm_domain *of_genpd_get_from_provider( struct of_phandle_args *genpdspec) { return NULL; } |
aa42240ab
|
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
|
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
|
232 |
#endif /* _LINUX_PM_DOMAIN_H */ |