]> Pileus Git - ~andy/linux/blob - include/linux/pm_domain.h
PM / Domains: Introduce "save/restore state" device callbacks
[~andy/linux] / include / linux / pm_domain.h
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>
13
14 enum gpd_status {
15         GPD_STATE_ACTIVE = 0,   /* PM domain is active */
16         GPD_STATE_WAIT_MASTER,  /* PM domain's master is being waited for */
17         GPD_STATE_BUSY,         /* Something is happening to the PM domain */
18         GPD_STATE_REPEAT,       /* Power off in progress, to be repeated */
19         GPD_STATE_POWER_OFF,    /* PM domain is off */
20 };
21
22 struct dev_power_governor {
23         bool (*power_down_ok)(struct dev_pm_domain *domain);
24 };
25
26 struct gpd_dev_ops {
27         int (*start)(struct device *dev);
28         int (*stop)(struct device *dev);
29         int (*save_state)(struct device *dev);
30         int (*restore_state)(struct device *dev);
31         bool (*active_wakeup)(struct device *dev);
32 };
33
34 struct generic_pm_domain {
35         struct dev_pm_domain domain;    /* PM domain operations */
36         struct list_head gpd_list_node; /* Node in the global PM domains list */
37         struct list_head master_links;  /* Links with PM domain as a master */
38         struct list_head slave_links;   /* Links with PM domain as a slave */
39         struct list_head dev_list;      /* List of devices */
40         struct mutex lock;
41         struct dev_power_governor *gov;
42         struct work_struct power_off_work;
43         unsigned int in_progress;       /* Number of devices being suspended now */
44         atomic_t sd_count;      /* Number of subdomains with power "on" */
45         enum gpd_status status; /* Current state of the domain */
46         wait_queue_head_t status_wait_queue;
47         struct task_struct *poweroff_task;      /* Powering off task */
48         unsigned int resume_count;      /* Number of devices being resumed */
49         unsigned int device_count;      /* Number of devices */
50         unsigned int suspended_count;   /* System suspend device counter */
51         unsigned int prepared_count;    /* Suspend counter of prepared devices */
52         bool suspend_power_off; /* Power status before system suspend */
53         bool dev_irq_safe;      /* Device callbacks are IRQ-safe */
54         int (*power_off)(struct generic_pm_domain *domain);
55         int (*power_on)(struct generic_pm_domain *domain);
56         struct gpd_dev_ops dev_ops;
57 };
58
59 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
60 {
61         return container_of(pd, struct generic_pm_domain, domain);
62 }
63
64 struct gpd_link {
65         struct generic_pm_domain *master;
66         struct list_head master_node;
67         struct generic_pm_domain *slave;
68         struct list_head slave_node;
69 };
70
71 struct generic_pm_domain_data {
72         struct pm_domain_data base;
73         struct gpd_dev_ops ops;
74         bool need_restore;
75 };
76
77 static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
78 {
79         return container_of(pdd, struct generic_pm_domain_data, base);
80 }
81
82 #ifdef CONFIG_PM_GENERIC_DOMAINS
83 static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
84 {
85         return to_gpd_data(dev->power.subsys_data->domain_data);
86 }
87
88 extern int pm_genpd_add_device(struct generic_pm_domain *genpd,
89                                struct device *dev);
90 extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
91                                   struct device *dev);
92 extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
93                                   struct generic_pm_domain *new_subdomain);
94 extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
95                                      struct generic_pm_domain *target);
96 extern int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops);
97 extern int pm_genpd_remove_callbacks(struct device *dev);
98 extern void pm_genpd_init(struct generic_pm_domain *genpd,
99                           struct dev_power_governor *gov, bool is_off);
100 extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
101 #else
102 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
103                                       struct device *dev)
104 {
105         return -ENOSYS;
106 }
107 static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
108                                          struct device *dev)
109 {
110         return -ENOSYS;
111 }
112 static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
113                                          struct generic_pm_domain *new_sd)
114 {
115         return -ENOSYS;
116 }
117 static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
118                                             struct generic_pm_domain *target)
119 {
120         return -ENOSYS;
121 }
122 static inline int pm_genpd_add_callbacks(struct device *dev,
123                                          struct gpd_dev_ops *ops)
124 {
125         return -ENOSYS;
126 }
127 static inline int pm_genpd_remove_callbacks(struct device *dev)
128 {
129         return -ENOSYS;
130 }
131 static inline void pm_genpd_init(struct generic_pm_domain *genpd,
132                                  struct dev_power_governor *gov, bool is_off) {}
133 static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
134 {
135         return -ENOSYS;
136 }
137 #endif
138
139 #ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME
140 extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd);
141 extern void pm_genpd_poweroff_unused(void);
142 #else
143 static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
144 static inline void pm_genpd_poweroff_unused(void) {}
145 #endif
146
147 #endif /* _LINUX_PM_DOMAIN_H */