aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/sysfs.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-09-25 17:35:15 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2010-10-16 19:57:47 -0400
commit7490e44239e60293bca0c2663229050c36c660c2 (patch)
tree938cd1cafba133f2d47c648ac01242de841d6d1b /drivers/base/power/sysfs.c
parent140a6c945211ee911dec776fafa52e03a7d7bb9a (diff)
PM / Runtime: Add no_callbacks flag
Some devices, such as USB interfaces, cannot be power-managed independently of their parents, i.e., they cannot be put in low power while the parent remains at full power. This patch (as1425) creates a new "no_callbacks" flag, which tells the PM core not to invoke the runtime-PM callback routines for the such devices but instead to assume that the callbacks always succeed. In addition, the non-debugging runtime-PM sysfs attributes for the devices are removed, since they are pretty much meaningless. The advantage of this scheme comes not so much from avoiding the callbacks themselves, but rather from the fact that without the need for a process context in which to run the callbacks, more work can be done in interrupt context. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power/sysfs.c')
-rw-r--r--drivers/base/power/sysfs.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 8859780817e1..b5708c47ce2d 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -81,6 +81,9 @@
81static const char enabled[] = "enabled"; 81static const char enabled[] = "enabled";
82static const char disabled[] = "disabled"; 82static const char disabled[] = "disabled";
83 83
84const char power_group_name[] = "power";
85EXPORT_SYMBOL_GPL(power_group_name);
86
84#ifdef CONFIG_PM_RUNTIME 87#ifdef CONFIG_PM_RUNTIME
85static const char ctrl_auto[] = "auto"; 88static const char ctrl_auto[] = "auto";
86static const char ctrl_on[] = "on"; 89static const char ctrl_on[] = "on";
@@ -390,12 +393,6 @@ static DEVICE_ATTR(async, 0644, async_show, async_store);
390#endif /* CONFIG_PM_ADVANCED_DEBUG */ 393#endif /* CONFIG_PM_ADVANCED_DEBUG */
391 394
392static struct attribute * power_attrs[] = { 395static struct attribute * power_attrs[] = {
393#ifdef CONFIG_PM_RUNTIME
394 &dev_attr_control.attr,
395 &dev_attr_runtime_status.attr,
396 &dev_attr_runtime_suspended_time.attr,
397 &dev_attr_runtime_active_time.attr,
398#endif
399 &dev_attr_wakeup.attr, 396 &dev_attr_wakeup.attr,
400#ifdef CONFIG_PM_SLEEP 397#ifdef CONFIG_PM_SLEEP
401 &dev_attr_wakeup_count.attr, 398 &dev_attr_wakeup_count.attr,
@@ -409,6 +406,7 @@ static struct attribute * power_attrs[] = {
409#ifdef CONFIG_PM_ADVANCED_DEBUG 406#ifdef CONFIG_PM_ADVANCED_DEBUG
410 &dev_attr_async.attr, 407 &dev_attr_async.attr,
411#ifdef CONFIG_PM_RUNTIME 408#ifdef CONFIG_PM_RUNTIME
409 &dev_attr_runtime_status.attr,
412 &dev_attr_runtime_usage.attr, 410 &dev_attr_runtime_usage.attr,
413 &dev_attr_runtime_active_kids.attr, 411 &dev_attr_runtime_active_kids.attr,
414 &dev_attr_runtime_enabled.attr, 412 &dev_attr_runtime_enabled.attr,
@@ -417,10 +415,52 @@ static struct attribute * power_attrs[] = {
417 NULL, 415 NULL,
418}; 416};
419static struct attribute_group pm_attr_group = { 417static struct attribute_group pm_attr_group = {
420 .name = "power", 418 .name = power_group_name,
421 .attrs = power_attrs, 419 .attrs = power_attrs,
422}; 420};
423 421
422#ifdef CONFIG_PM_RUNTIME
423
424static struct attribute *runtime_attrs[] = {
425#ifndef CONFIG_PM_ADVANCED_DEBUG
426 &dev_attr_runtime_status.attr,
427#endif
428 &dev_attr_control.attr,
429 &dev_attr_runtime_suspended_time.attr,
430 &dev_attr_runtime_active_time.attr,
431 NULL,
432};
433static struct attribute_group pm_runtime_attr_group = {
434 .name = power_group_name,
435 .attrs = runtime_attrs,
436};
437
438int dpm_sysfs_add(struct device *dev)
439{
440 int rc;
441
442 rc = sysfs_create_group(&dev->kobj, &pm_attr_group);
443 if (rc == 0 && !dev->power.no_callbacks) {
444 rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group);
445 if (rc)
446 sysfs_remove_group(&dev->kobj, &pm_attr_group);
447 }
448 return rc;
449}
450
451void rpm_sysfs_remove(struct device *dev)
452{
453 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
454}
455
456void dpm_sysfs_remove(struct device *dev)
457{
458 rpm_sysfs_remove(dev);
459 sysfs_remove_group(&dev->kobj, &pm_attr_group);
460}
461
462#else /* CONFIG_PM_RUNTIME */
463
424int dpm_sysfs_add(struct device * dev) 464int dpm_sysfs_add(struct device * dev)
425{ 465{
426 return sysfs_create_group(&dev->kobj, &pm_attr_group); 466 return sysfs_create_group(&dev->kobj, &pm_attr_group);
@@ -430,3 +470,5 @@ void dpm_sysfs_remove(struct device * dev)
430{ 470{
431 sysfs_remove_group(&dev->kobj, &pm_attr_group); 471 sysfs_remove_group(&dev->kobj, &pm_attr_group);
432} 472}
473
474#endif