PCI: Rework ASPM disable code
[pandora-kernel.git] / 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 generic_pm_domain {
27         struct dev_pm_domain domain;    /* PM domain operations */
28         struct list_head gpd_list_node; /* Node in the global PM domains list */
29         struct list_head master_links;  /* Links with PM domain as a master */
30         struct list_head slave_links;   /* Links with PM domain as a slave */
31         struct list_head dev_list;      /* List of devices */
32         struct mutex lock;
33         struct dev_power_governor *gov;
34         struct work_struct power_off_work;
35         unsigned int in_progress;       /* Number of devices being suspended now */
36         atomic_t sd_count;      /* Number of subdomains with power "on" */
37         enum gpd_status status; /* Current state of the domain */
38         wait_queue_head_t status_wait_queue;
39         struct task_struct *poweroff_task;      /* Powering off task */
40         unsigned int resume_count;      /* Number of devices being resumed */
41         unsigned int device_count;      /* Number of devices */
42         unsigned int suspended_count;   /* System suspend device counter */
43         unsigned int prepared_count;    /* Suspend counter of prepared devices */
44         bool suspend_power_off; /* Power status before system suspend */
45         bool dev_irq_safe;      /* Device callbacks are IRQ-safe */
46         int (*power_off)(struct generic_pm_domain *domain);
47         int (*power_on)(struct generic_pm_domain *domain);
48         int (*start_device)(struct device *dev);
49         int (*stop_device)(struct device *dev);
50         bool (*active_wakeup)(struct device *dev);
51 };
52
53 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
54 {
55         return container_of(pd, struct generic_pm_domain, domain);
56 }
57
58 struct gpd_link {
59         struct generic_pm_domain *master;
60         struct list_head master_node;
61         struct generic_pm_domain *slave;
62         struct list_head slave_node;
63 };
64
65 struct generic_pm_domain_data {
66         struct pm_domain_data base;
67         bool need_restore;
68 };
69
70 static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
71 {
72         return container_of(pdd, struct generic_pm_domain_data, base);
73 }
74
75 #ifdef CONFIG_PM_GENERIC_DOMAINS
76 extern int pm_genpd_add_device(struct generic_pm_domain *genpd,
77                                struct device *dev);
78 extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
79                                   struct device *dev);
80 extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
81                                   struct generic_pm_domain *new_subdomain);
82 extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
83                                      struct generic_pm_domain *target);
84 extern void pm_genpd_init(struct generic_pm_domain *genpd,
85                           struct dev_power_governor *gov, bool is_off);
86 extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
87 #else
88 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
89                                       struct device *dev)
90 {
91         return -ENOSYS;
92 }
93 static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
94                                          struct device *dev)
95 {
96         return -ENOSYS;
97 }
98 static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
99                                          struct generic_pm_domain *new_sd)
100 {
101         return -ENOSYS;
102 }
103 static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
104                                             struct generic_pm_domain *target)
105 {
106         return -ENOSYS;
107 }
108 static inline void pm_genpd_init(struct generic_pm_domain *genpd,
109                                  struct dev_power_governor *gov, bool is_off) {}
110 static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
111 {
112         return -ENOSYS;
113 }
114 #endif
115
116 #ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME
117 extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd);
118 extern void pm_genpd_poweroff_unused(void);
119 #else
120 static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
121 static inline void pm_genpd_poweroff_unused(void) {}
122 #endif
123
124 #endif /* _LINUX_PM_DOMAIN_H */