aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-04-29 16:54:47 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-05-01 15:28:43 -0400
commit23e0fc5ae64925e0ff1b6221b83dff1b217545df (patch)
treed22f7b9891242715238014e00f97646256bea053
parent76e267d822f2913893ad210ba431607aa8e2af94 (diff)
PM / QoS: Create device constraints objects on notifier registration
The current behavior of dev_pm_qos_add_notifier() makes device PM QoS notifiers less than useful. Namely, it silently returns success when called before any PM QoS constraints are added for the device, so the caller will assume that the notifier has been registered, but when someone actually adds some nontrivial constraints for the device eventually, the previous callers of dev_pm_qos_add_notifier() will not know about that and their notifier routines will not be executed (contrary to their expectations). To address this problem make dev_pm_qos_add_notifier() create the constraints object for the device if it is not present when the routine is called. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by : markgross <markgross@thegnar.org>
-rw-r--r--drivers/base/power/qos.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 71855570922d..fd849a2c4fa8 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -352,21 +352,26 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_remove_request);
352 * 352 *
353 * Will register the notifier into a notification chain that gets called 353 * Will register the notifier into a notification chain that gets called
354 * upon changes to the target value for the device. 354 * upon changes to the target value for the device.
355 *
356 * If the device's constraints object doesn't exist when this routine is called,
357 * it will be created (or error code will be returned if that fails).
355 */ 358 */
356int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) 359int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier)
357{ 360{
358 int retval = 0; 361 int ret = 0;
359 362
360 mutex_lock(&dev_pm_qos_mtx); 363 mutex_lock(&dev_pm_qos_mtx);
361 364
362 /* Silently return if the constraints object is not present. */ 365 if (!dev->power.constraints)
363 if (dev->power.constraints) 366 ret = dev->power.power_state.event != PM_EVENT_INVALID ?
364 retval = blocking_notifier_chain_register( 367 dev_pm_qos_constraints_allocate(dev) : -ENODEV;
365 dev->power.constraints->notifiers, 368
366 notifier); 369 if (!ret)
370 ret = blocking_notifier_chain_register(
371 dev->power.constraints->notifiers, notifier);
367 372
368 mutex_unlock(&dev_pm_qos_mtx); 373 mutex_unlock(&dev_pm_qos_mtx);
369 return retval; 374 return ret;
370} 375}
371EXPORT_SYMBOL_GPL(dev_pm_qos_add_notifier); 376EXPORT_SYMBOL_GPL(dev_pm_qos_add_notifier);
372 377