diff options
-rw-r--r-- | drivers/base/power/main.c | 6 | ||||
-rw-r--r-- | drivers/base/power/power.h | 10 | ||||
-rw-r--r-- | drivers/base/power/qos.c | 160 | ||||
-rw-r--r-- | include/linux/pm.h | 10 | ||||
-rw-r--r-- | include/linux/pm_qos.h | 12 |
5 files changed, 114 insertions, 84 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 956443f86254..c6291ab725a3 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
25 | #include <linux/pm_qos.h> | ||
26 | #include <linux/resume-trace.h> | 25 | #include <linux/resume-trace.h> |
27 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
28 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
@@ -66,6 +65,7 @@ void device_pm_init(struct device *dev) | |||
66 | spin_lock_init(&dev->power.lock); | 65 | spin_lock_init(&dev->power.lock); |
67 | pm_runtime_init(dev); | 66 | pm_runtime_init(dev); |
68 | INIT_LIST_HEAD(&dev->power.entry); | 67 | INIT_LIST_HEAD(&dev->power.entry); |
68 | dev->power.power_state = PMSG_INVALID; | ||
69 | } | 69 | } |
70 | 70 | ||
71 | /** | 71 | /** |
@@ -97,8 +97,8 @@ void device_pm_add(struct device *dev) | |||
97 | dev_warn(dev, "parent %s should not be sleeping\n", | 97 | dev_warn(dev, "parent %s should not be sleeping\n", |
98 | dev_name(dev->parent)); | 98 | dev_name(dev->parent)); |
99 | list_add_tail(&dev->power.entry, &dpm_list); | 99 | list_add_tail(&dev->power.entry, &dpm_list); |
100 | mutex_unlock(&dpm_list_mtx); | ||
101 | dev_pm_qos_constraints_init(dev); | 100 | dev_pm_qos_constraints_init(dev); |
101 | mutex_unlock(&dpm_list_mtx); | ||
102 | } | 102 | } |
103 | 103 | ||
104 | /** | 104 | /** |
@@ -109,9 +109,9 @@ void device_pm_remove(struct device *dev) | |||
109 | { | 109 | { |
110 | pr_debug("PM: Removing info for %s:%s\n", | 110 | pr_debug("PM: Removing info for %s:%s\n", |
111 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); | 111 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
112 | dev_pm_qos_constraints_destroy(dev); | ||
113 | complete_all(&dev->power.completion); | 112 | complete_all(&dev->power.completion); |
114 | mutex_lock(&dpm_list_mtx); | 113 | mutex_lock(&dpm_list_mtx); |
114 | dev_pm_qos_constraints_destroy(dev); | ||
115 | list_del_init(&dev->power.entry); | 115 | list_del_init(&dev->power.entry); |
116 | mutex_unlock(&dpm_list_mtx); | 116 | mutex_unlock(&dpm_list_mtx); |
117 | device_wakeup_disable(dev); | 117 | device_wakeup_disable(dev); |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index f2a25f18fde7..9bf62323aaf3 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -1,3 +1,5 @@ | |||
1 | #include <linux/pm_qos.h> | ||
2 | |||
1 | #ifdef CONFIG_PM_RUNTIME | 3 | #ifdef CONFIG_PM_RUNTIME |
2 | 4 | ||
3 | extern void pm_runtime_init(struct device *dev); | 5 | extern void pm_runtime_init(struct device *dev); |
@@ -35,15 +37,21 @@ extern void device_pm_move_last(struct device *); | |||
35 | static inline void device_pm_init(struct device *dev) | 37 | static inline void device_pm_init(struct device *dev) |
36 | { | 38 | { |
37 | spin_lock_init(&dev->power.lock); | 39 | spin_lock_init(&dev->power.lock); |
40 | dev->power.power_state = PMSG_INVALID; | ||
38 | pm_runtime_init(dev); | 41 | pm_runtime_init(dev); |
39 | } | 42 | } |
40 | 43 | ||
44 | static inline void device_pm_add(struct device *dev) | ||
45 | { | ||
46 | dev_pm_qos_constraints_init(dev); | ||
47 | } | ||
48 | |||
41 | static inline void device_pm_remove(struct device *dev) | 49 | static inline void device_pm_remove(struct device *dev) |
42 | { | 50 | { |
51 | dev_pm_qos_constraints_destroy(dev); | ||
43 | pm_runtime_remove(dev); | 52 | pm_runtime_remove(dev); |
44 | } | 53 | } |
45 | 54 | ||
46 | static inline void device_pm_add(struct device *dev) {} | ||
47 | static inline void device_pm_move_before(struct device *deva, | 55 | static inline void device_pm_move_before(struct device *deva, |
48 | struct device *devb) {} | 56 | struct device *devb) {} |
49 | static inline void device_pm_move_after(struct device *deva, | 57 | static inline void device_pm_move_after(struct device *deva, |
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 8d0b81151c14..91e061417382 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -30,15 +30,6 @@ | |||
30 | * . To minimize the data usage by the per-device constraints, the data struct | 30 | * . To minimize the data usage by the per-device constraints, the data struct |
31 | * is only allocated at the first call to dev_pm_qos_add_request. | 31 | * is only allocated at the first call to dev_pm_qos_add_request. |
32 | * . The data is later free'd when the device is removed from the system. | 32 | * . The data is later free'd when the device is removed from the system. |
33 | * . The constraints_state variable from dev_pm_info tracks the data struct | ||
34 | * allocation state: | ||
35 | * DEV_PM_QOS_NO_DEVICE: No device present or device removed, no data | ||
36 | * allocated, | ||
37 | * DEV_PM_QOS_DEVICE_PRESENT: Device present, data not allocated and will be | ||
38 | * allocated at the first call to dev_pm_qos_add_request, | ||
39 | * DEV_PM_QOS_ALLOCATED: Device present, data allocated. The per-device | ||
40 | * PM QoS constraints framework is operational and constraints can be | ||
41 | * added, updated or removed using the dev_pm_qos_* API. | ||
42 | * . A global mutex protects the constraints users from the data being | 33 | * . A global mutex protects the constraints users from the data being |
43 | * allocated and free'd. | 34 | * allocated and free'd. |
44 | */ | 35 | */ |
@@ -51,8 +42,30 @@ | |||
51 | 42 | ||
52 | 43 | ||
53 | static DEFINE_MUTEX(dev_pm_qos_mtx); | 44 | static DEFINE_MUTEX(dev_pm_qos_mtx); |
45 | |||
54 | static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); | 46 | static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); |
55 | 47 | ||
48 | /** | ||
49 | * dev_pm_qos_read_value - Get PM QoS constraint for a given device. | ||
50 | * @dev: Device to get the PM QoS constraint value for. | ||
51 | */ | ||
52 | s32 dev_pm_qos_read_value(struct device *dev) | ||
53 | { | ||
54 | struct pm_qos_constraints *c; | ||
55 | unsigned long flags; | ||
56 | s32 ret = 0; | ||
57 | |||
58 | spin_lock_irqsave(&dev->power.lock, flags); | ||
59 | |||
60 | c = dev->power.constraints; | ||
61 | if (c) | ||
62 | ret = pm_qos_read_value(c); | ||
63 | |||
64 | spin_unlock_irqrestore(&dev->power.lock, flags); | ||
65 | |||
66 | return ret; | ||
67 | } | ||
68 | |||
56 | /* | 69 | /* |
57 | * apply_constraint | 70 | * apply_constraint |
58 | * @req: constraint request to apply | 71 | * @req: constraint request to apply |
@@ -105,27 +118,31 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) | |||
105 | } | 118 | } |
106 | BLOCKING_INIT_NOTIFIER_HEAD(n); | 119 | BLOCKING_INIT_NOTIFIER_HEAD(n); |
107 | 120 | ||
121 | plist_head_init(&c->list); | ||
122 | c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; | ||
123 | c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; | ||
124 | c->type = PM_QOS_MIN; | ||
125 | c->notifiers = n; | ||
126 | |||
127 | spin_lock_irq(&dev->power.lock); | ||
108 | dev->power.constraints = c; | 128 | dev->power.constraints = c; |
109 | plist_head_init(&dev->power.constraints->list); | 129 | spin_unlock_irq(&dev->power.lock); |
110 | dev->power.constraints->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; | ||
111 | dev->power.constraints->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; | ||
112 | dev->power.constraints->type = PM_QOS_MIN; | ||
113 | dev->power.constraints->notifiers = n; | ||
114 | dev->power.constraints_state = DEV_PM_QOS_ALLOCATED; | ||
115 | 130 | ||
116 | return 0; | 131 | return 0; |
117 | } | 132 | } |
118 | 133 | ||
119 | /** | 134 | /** |
120 | * dev_pm_qos_constraints_init | 135 | * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer. |
121 | * @dev: target device | 136 | * @dev: target device |
122 | * | 137 | * |
123 | * Called from the device PM subsystem at device insertion | 138 | * Called from the device PM subsystem during device insertion under |
139 | * device_pm_lock(). | ||
124 | */ | 140 | */ |
125 | void dev_pm_qos_constraints_init(struct device *dev) | 141 | void dev_pm_qos_constraints_init(struct device *dev) |
126 | { | 142 | { |
127 | mutex_lock(&dev_pm_qos_mtx); | 143 | mutex_lock(&dev_pm_qos_mtx); |
128 | dev->power.constraints_state = DEV_PM_QOS_DEVICE_PRESENT; | 144 | dev->power.constraints = NULL; |
145 | dev->power.power_state = PMSG_ON; | ||
129 | mutex_unlock(&dev_pm_qos_mtx); | 146 | mutex_unlock(&dev_pm_qos_mtx); |
130 | } | 147 | } |
131 | 148 | ||
@@ -133,34 +150,38 @@ void dev_pm_qos_constraints_init(struct device *dev) | |||
133 | * dev_pm_qos_constraints_destroy | 150 | * dev_pm_qos_constraints_destroy |
134 | * @dev: target device | 151 | * @dev: target device |
135 | * | 152 | * |
136 | * Called from the device PM subsystem at device removal | 153 | * Called from the device PM subsystem on device removal under device_pm_lock(). |
137 | */ | 154 | */ |
138 | void dev_pm_qos_constraints_destroy(struct device *dev) | 155 | void dev_pm_qos_constraints_destroy(struct device *dev) |
139 | { | 156 | { |
140 | struct dev_pm_qos_request *req, *tmp; | 157 | struct dev_pm_qos_request *req, *tmp; |
158 | struct pm_qos_constraints *c; | ||
141 | 159 | ||
142 | mutex_lock(&dev_pm_qos_mtx); | 160 | mutex_lock(&dev_pm_qos_mtx); |
143 | 161 | ||
144 | if (dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) { | 162 | dev->power.power_state = PMSG_INVALID; |
145 | /* Flush the constraints list for the device */ | 163 | c = dev->power.constraints; |
146 | plist_for_each_entry_safe(req, tmp, | 164 | if (!c) |
147 | &dev->power.constraints->list, | 165 | goto out; |
148 | node) { | ||
149 | /* | ||
150 | * Update constraints list and call the notification | ||
151 | * callbacks if needed | ||
152 | */ | ||
153 | apply_constraint(req, PM_QOS_REMOVE_REQ, | ||
154 | PM_QOS_DEFAULT_VALUE); | ||
155 | memset(req, 0, sizeof(*req)); | ||
156 | } | ||
157 | 166 | ||
158 | kfree(dev->power.constraints->notifiers); | 167 | /* Flush the constraints list for the device */ |
159 | kfree(dev->power.constraints); | 168 | plist_for_each_entry_safe(req, tmp, &c->list, node) { |
160 | dev->power.constraints = NULL; | 169 | /* |
170 | * Update constraints list and call the notification | ||
171 | * callbacks if needed | ||
172 | */ | ||
173 | apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); | ||
174 | memset(req, 0, sizeof(*req)); | ||
161 | } | 175 | } |
162 | dev->power.constraints_state = DEV_PM_QOS_NO_DEVICE; | ||
163 | 176 | ||
177 | spin_lock_irq(&dev->power.lock); | ||
178 | dev->power.constraints = NULL; | ||
179 | spin_unlock_irq(&dev->power.lock); | ||
180 | |||
181 | kfree(c->notifiers); | ||
182 | kfree(c); | ||
183 | |||
184 | out: | ||
164 | mutex_unlock(&dev_pm_qos_mtx); | 185 | mutex_unlock(&dev_pm_qos_mtx); |
165 | } | 186 | } |
166 | 187 | ||
@@ -178,8 +199,9 @@ void dev_pm_qos_constraints_destroy(struct device *dev) | |||
178 | * | 199 | * |
179 | * Returns 1 if the aggregated constraint value has changed, | 200 | * Returns 1 if the aggregated constraint value has changed, |
180 | * 0 if the aggregated constraint value has not changed, | 201 | * 0 if the aggregated constraint value has not changed, |
181 | * -EINVAL in case of wrong parameters, -ENODEV if the device has been | 202 | * -EINVAL in case of wrong parameters, -ENOMEM if there's not enough memory |
182 | * removed from the system | 203 | * to allocate for data structures, -ENODEV if the device has just been removed |
204 | * from the system. | ||
183 | */ | 205 | */ |
184 | int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, | 206 | int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, |
185 | s32 value) | 207 | s32 value) |
@@ -195,28 +217,32 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, | |||
195 | return -EINVAL; | 217 | return -EINVAL; |
196 | } | 218 | } |
197 | 219 | ||
198 | mutex_lock(&dev_pm_qos_mtx); | ||
199 | req->dev = dev; | 220 | req->dev = dev; |
200 | 221 | ||
201 | /* Return if the device has been removed */ | 222 | mutex_lock(&dev_pm_qos_mtx); |
202 | if (req->dev->power.constraints_state == DEV_PM_QOS_NO_DEVICE) { | ||
203 | ret = -ENODEV; | ||
204 | goto out; | ||
205 | } | ||
206 | 223 | ||
207 | /* | 224 | if (!dev->power.constraints) { |
208 | * Allocate the constraints data on the first call to add_request, | 225 | if (dev->power.power_state.event == PM_EVENT_INVALID) { |
209 | * i.e. only if the data is not already allocated and if the device has | 226 | /* The device has been removed from the system. */ |
210 | * not been removed | 227 | req->dev = NULL; |
211 | */ | 228 | ret = -ENODEV; |
212 | if (dev->power.constraints_state == DEV_PM_QOS_DEVICE_PRESENT) | 229 | goto out; |
213 | ret = dev_pm_qos_constraints_allocate(dev); | 230 | } else { |
231 | /* | ||
232 | * Allocate the constraints data on the first call to | ||
233 | * add_request, i.e. only if the data is not already | ||
234 | * allocated and if the device has not been removed. | ||
235 | */ | ||
236 | ret = dev_pm_qos_constraints_allocate(dev); | ||
237 | } | ||
238 | } | ||
214 | 239 | ||
215 | if (!ret) | 240 | if (!ret) |
216 | ret = apply_constraint(req, PM_QOS_ADD_REQ, value); | 241 | ret = apply_constraint(req, PM_QOS_ADD_REQ, value); |
217 | 242 | ||
218 | out: | 243 | out: |
219 | mutex_unlock(&dev_pm_qos_mtx); | 244 | mutex_unlock(&dev_pm_qos_mtx); |
245 | |||
220 | return ret; | 246 | return ret; |
221 | } | 247 | } |
222 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); | 248 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); |
@@ -252,7 +278,7 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, | |||
252 | 278 | ||
253 | mutex_lock(&dev_pm_qos_mtx); | 279 | mutex_lock(&dev_pm_qos_mtx); |
254 | 280 | ||
255 | if (req->dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) { | 281 | if (req->dev->power.constraints) { |
256 | if (new_value != req->node.prio) | 282 | if (new_value != req->node.prio) |
257 | ret = apply_constraint(req, PM_QOS_UPDATE_REQ, | 283 | ret = apply_constraint(req, PM_QOS_UPDATE_REQ, |
258 | new_value); | 284 | new_value); |
@@ -293,7 +319,7 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) | |||
293 | 319 | ||
294 | mutex_lock(&dev_pm_qos_mtx); | 320 | mutex_lock(&dev_pm_qos_mtx); |
295 | 321 | ||
296 | if (req->dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) { | 322 | if (req->dev->power.constraints) { |
297 | ret = apply_constraint(req, PM_QOS_REMOVE_REQ, | 323 | ret = apply_constraint(req, PM_QOS_REMOVE_REQ, |
298 | PM_QOS_DEFAULT_VALUE); | 324 | PM_QOS_DEFAULT_VALUE); |
299 | memset(req, 0, sizeof(*req)); | 325 | memset(req, 0, sizeof(*req)); |
@@ -323,15 +349,12 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) | |||
323 | 349 | ||
324 | mutex_lock(&dev_pm_qos_mtx); | 350 | mutex_lock(&dev_pm_qos_mtx); |
325 | 351 | ||
326 | /* Silently return if the device has been removed */ | 352 | /* Silently return if the constraints object is not present. */ |
327 | if (dev->power.constraints_state != DEV_PM_QOS_ALLOCATED) | 353 | if (dev->power.constraints) |
328 | goto out; | 354 | retval = blocking_notifier_chain_register( |
329 | 355 | dev->power.constraints->notifiers, | |
330 | retval = blocking_notifier_chain_register( | 356 | notifier); |
331 | dev->power.constraints->notifiers, | ||
332 | notifier); | ||
333 | 357 | ||
334 | out: | ||
335 | mutex_unlock(&dev_pm_qos_mtx); | 358 | mutex_unlock(&dev_pm_qos_mtx); |
336 | return retval; | 359 | return retval; |
337 | } | 360 | } |
@@ -354,15 +377,12 @@ int dev_pm_qos_remove_notifier(struct device *dev, | |||
354 | 377 | ||
355 | mutex_lock(&dev_pm_qos_mtx); | 378 | mutex_lock(&dev_pm_qos_mtx); |
356 | 379 | ||
357 | /* Silently return if the device has been removed */ | 380 | /* Silently return if the constraints object is not present. */ |
358 | if (dev->power.constraints_state != DEV_PM_QOS_ALLOCATED) | 381 | if (dev->power.constraints) |
359 | goto out; | 382 | retval = blocking_notifier_chain_unregister( |
360 | 383 | dev->power.constraints->notifiers, | |
361 | retval = blocking_notifier_chain_unregister( | 384 | notifier); |
362 | dev->power.constraints->notifiers, | ||
363 | notifier); | ||
364 | 385 | ||
365 | out: | ||
366 | mutex_unlock(&dev_pm_qos_mtx); | 386 | mutex_unlock(&dev_pm_qos_mtx); |
367 | return retval; | 387 | return retval; |
368 | } | 388 | } |
diff --git a/include/linux/pm.h b/include/linux/pm.h index d78187e9ca99..62a876ec4d4e 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -326,6 +326,7 @@ extern struct dev_pm_ops generic_subsys_pm_ops; | |||
326 | * requested by a driver. | 326 | * requested by a driver. |
327 | */ | 327 | */ |
328 | 328 | ||
329 | #define PM_EVENT_INVALID (-1) | ||
329 | #define PM_EVENT_ON 0x0000 | 330 | #define PM_EVENT_ON 0x0000 |
330 | #define PM_EVENT_FREEZE 0x0001 | 331 | #define PM_EVENT_FREEZE 0x0001 |
331 | #define PM_EVENT_SUSPEND 0x0002 | 332 | #define PM_EVENT_SUSPEND 0x0002 |
@@ -346,6 +347,7 @@ extern struct dev_pm_ops generic_subsys_pm_ops; | |||
346 | #define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND) | 347 | #define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND) |
347 | #define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME) | 348 | #define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME) |
348 | 349 | ||
350 | #define PMSG_INVALID ((struct pm_message){ .event = PM_EVENT_INVALID, }) | ||
349 | #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) | 351 | #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) |
350 | #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) | 352 | #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) |
351 | #define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, }) | 353 | #define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, }) |
@@ -419,13 +421,6 @@ enum rpm_request { | |||
419 | RPM_REQ_RESUME, | 421 | RPM_REQ_RESUME, |
420 | }; | 422 | }; |
421 | 423 | ||
422 | /* Per-device PM QoS constraints data struct state */ | ||
423 | enum dev_pm_qos_state { | ||
424 | DEV_PM_QOS_NO_DEVICE, /* No device present */ | ||
425 | DEV_PM_QOS_DEVICE_PRESENT, /* Device present, data not allocated */ | ||
426 | DEV_PM_QOS_ALLOCATED, /* Device present, data allocated */ | ||
427 | }; | ||
428 | |||
429 | struct wakeup_source; | 424 | struct wakeup_source; |
430 | 425 | ||
431 | struct pm_domain_data { | 426 | struct pm_domain_data { |
@@ -488,7 +483,6 @@ struct dev_pm_info { | |||
488 | #endif | 483 | #endif |
489 | struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ | 484 | struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ |
490 | struct pm_qos_constraints *constraints; | 485 | struct pm_qos_constraints *constraints; |
491 | enum dev_pm_qos_state constraints_state; | ||
492 | }; | 486 | }; |
493 | 487 | ||
494 | extern void update_pm_runtime_accounting(struct device *dev); | 488 | extern void update_pm_runtime_accounting(struct device *dev); |
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index ca7bd3f98cb4..83b0ea302a80 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/plist.h> | 7 | #include <linux/plist.h> |
8 | #include <linux/notifier.h> | 8 | #include <linux/notifier.h> |
9 | #include <linux/miscdevice.h> | 9 | #include <linux/miscdevice.h> |
10 | #include <linux/device.h> | ||
10 | 11 | ||
11 | #define PM_QOS_RESERVED 0 | 12 | #define PM_QOS_RESERVED 0 |
12 | #define PM_QOS_CPU_DMA_LATENCY 1 | 13 | #define PM_QOS_CPU_DMA_LATENCY 1 |
@@ -77,6 +78,7 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); | |||
77 | int pm_qos_request_active(struct pm_qos_request *req); | 78 | int pm_qos_request_active(struct pm_qos_request *req); |
78 | s32 pm_qos_read_value(struct pm_qos_constraints *c); | 79 | s32 pm_qos_read_value(struct pm_qos_constraints *c); |
79 | 80 | ||
81 | s32 dev_pm_qos_read_value(struct device *dev); | ||
80 | int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, | 82 | int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, |
81 | s32 value); | 83 | s32 value); |
82 | int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value); | 84 | int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value); |
@@ -117,6 +119,8 @@ static inline int pm_qos_request_active(struct pm_qos_request *req) | |||
117 | static inline s32 pm_qos_read_value(struct pm_qos_constraints *c) | 119 | static inline s32 pm_qos_read_value(struct pm_qos_constraints *c) |
118 | { return 0; } | 120 | { return 0; } |
119 | 121 | ||
122 | static inline s32 dev_pm_qos_read_value(struct device *dev) | ||
123 | { return 0; } | ||
120 | static inline int dev_pm_qos_add_request(struct device *dev, | 124 | static inline int dev_pm_qos_add_request(struct device *dev, |
121 | struct dev_pm_qos_request *req, | 125 | struct dev_pm_qos_request *req, |
122 | s32 value) | 126 | s32 value) |
@@ -139,9 +143,13 @@ static inline int dev_pm_qos_remove_global_notifier( | |||
139 | struct notifier_block *notifier) | 143 | struct notifier_block *notifier) |
140 | { return 0; } | 144 | { return 0; } |
141 | static inline void dev_pm_qos_constraints_init(struct device *dev) | 145 | static inline void dev_pm_qos_constraints_init(struct device *dev) |
142 | { return; } | 146 | { |
147 | dev->power.power_state = PMSG_ON; | ||
148 | } | ||
143 | static inline void dev_pm_qos_constraints_destroy(struct device *dev) | 149 | static inline void dev_pm_qos_constraints_destroy(struct device *dev) |
144 | { return; } | 150 | { |
151 | dev->power.power_state = PMSG_INVALID; | ||
152 | } | ||
145 | #endif | 153 | #endif |
146 | 154 | ||
147 | #endif | 155 | #endif |