aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/sysfs.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-08 17:26:02 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-03-14 19:43:14 -0400
commitcb8f51bdadb7969139c2e39c2defd4cde98c1ea8 (patch)
treea6d6e20878460d50b8f61d5fe3237818c54065eb /drivers/base/power/sysfs.c
parent4681b17154b3fd81f898802262985f662344e6ed (diff)
PM: Do not create wakeup sysfs files for devices that cannot wake up
Currently, wakeup sysfs attributes are created for all devices, regardless of whether or not they are wakeup-capable. This is excessive and complicates wakeup device identification from user space (i.e. to identify wakeup-capable devices user space has to read /sys/devices/.../power/wakeup for all devices and see if they are not empty). Fix this issue by avoiding to create wakeup sysfs files for devices that cannot wake up the system from sleep states (i.e. whose power.can_wakeup flags are unset during registration) and modify device_set_wakeup_capable() so that it adds (or removes) the relevant sysfs attributes if a device's wakeup capability status is changed. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power/sysfs.c')
-rw-r--r--drivers/base/power/sysfs.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 0b1e46bf3e56..fff49bee781d 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -431,26 +431,18 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr,
431static DEVICE_ATTR(async, 0644, async_show, async_store); 431static DEVICE_ATTR(async, 0644, async_show, async_store);
432#endif /* CONFIG_PM_ADVANCED_DEBUG */ 432#endif /* CONFIG_PM_ADVANCED_DEBUG */
433 433
434static struct attribute * power_attrs[] = { 434static struct attribute *power_attrs[] = {
435 &dev_attr_wakeup.attr,
436#ifdef CONFIG_PM_SLEEP
437 &dev_attr_wakeup_count.attr,
438 &dev_attr_wakeup_active_count.attr,
439 &dev_attr_wakeup_hit_count.attr,
440 &dev_attr_wakeup_active.attr,
441 &dev_attr_wakeup_total_time_ms.attr,
442 &dev_attr_wakeup_max_time_ms.attr,
443 &dev_attr_wakeup_last_time_ms.attr,
444#endif
445#ifdef CONFIG_PM_ADVANCED_DEBUG 435#ifdef CONFIG_PM_ADVANCED_DEBUG
436#ifdef CONFIG_PM_SLEEP
446 &dev_attr_async.attr, 437 &dev_attr_async.attr,
438#endif
447#ifdef CONFIG_PM_RUNTIME 439#ifdef CONFIG_PM_RUNTIME
448 &dev_attr_runtime_status.attr, 440 &dev_attr_runtime_status.attr,
449 &dev_attr_runtime_usage.attr, 441 &dev_attr_runtime_usage.attr,
450 &dev_attr_runtime_active_kids.attr, 442 &dev_attr_runtime_active_kids.attr,
451 &dev_attr_runtime_enabled.attr, 443 &dev_attr_runtime_enabled.attr,
452#endif 444#endif
453#endif 445#endif /* CONFIG_PM_ADVANCED_DEBUG */
454 NULL, 446 NULL,
455}; 447};
456static struct attribute_group pm_attr_group = { 448static struct attribute_group pm_attr_group = {
@@ -458,9 +450,26 @@ static struct attribute_group pm_attr_group = {
458 .attrs = power_attrs, 450 .attrs = power_attrs,
459}; 451};
460 452
461#ifdef CONFIG_PM_RUNTIME 453static struct attribute *wakeup_attrs[] = {
454#ifdef CONFIG_PM_SLEEP
455 &dev_attr_wakeup.attr,
456 &dev_attr_wakeup_count.attr,
457 &dev_attr_wakeup_active_count.attr,
458 &dev_attr_wakeup_hit_count.attr,
459 &dev_attr_wakeup_active.attr,
460 &dev_attr_wakeup_total_time_ms.attr,
461 &dev_attr_wakeup_max_time_ms.attr,
462 &dev_attr_wakeup_last_time_ms.attr,
463#endif
464 NULL,
465};
466static struct attribute_group pm_wakeup_attr_group = {
467 .name = power_group_name,
468 .attrs = wakeup_attrs,
469};
462 470
463static struct attribute *runtime_attrs[] = { 471static struct attribute *runtime_attrs[] = {
472#ifdef CONFIG_PM_RUNTIME
464#ifndef CONFIG_PM_ADVANCED_DEBUG 473#ifndef CONFIG_PM_ADVANCED_DEBUG
465 &dev_attr_runtime_status.attr, 474 &dev_attr_runtime_status.attr,
466#endif 475#endif
@@ -468,6 +477,7 @@ static struct attribute *runtime_attrs[] = {
468 &dev_attr_runtime_suspended_time.attr, 477 &dev_attr_runtime_suspended_time.attr,
469 &dev_attr_runtime_active_time.attr, 478 &dev_attr_runtime_active_time.attr,
470 &dev_attr_autosuspend_delay_ms.attr, 479 &dev_attr_autosuspend_delay_ms.attr,
480#endif /* CONFIG_PM_RUNTIME */
471 NULL, 481 NULL,
472}; 482};
473static struct attribute_group pm_runtime_attr_group = { 483static struct attribute_group pm_runtime_attr_group = {
@@ -480,35 +490,49 @@ int dpm_sysfs_add(struct device *dev)
480 int rc; 490 int rc;
481 491
482 rc = sysfs_create_group(&dev->kobj, &pm_attr_group); 492 rc = sysfs_create_group(&dev->kobj, &pm_attr_group);
483 if (rc == 0 && !dev->power.no_callbacks) { 493 if (rc)
494 return rc;
495
496 if (pm_runtime_callbacks_present(dev)) {
484 rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group); 497 rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group);
485 if (rc) 498 if (rc)
486 sysfs_remove_group(&dev->kobj, &pm_attr_group); 499 goto err_out;
500 }
501
502 if (device_can_wakeup(dev)) {
503 rc = sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group);
504 if (rc) {
505 if (pm_runtime_callbacks_present(dev))
506 sysfs_unmerge_group(&dev->kobj,
507 &pm_runtime_attr_group);
508 goto err_out;
509 }
487 } 510 }
511 return 0;
512
513 err_out:
514 sysfs_remove_group(&dev->kobj, &pm_attr_group);
488 return rc; 515 return rc;
489} 516}
490 517
491void rpm_sysfs_remove(struct device *dev) 518int wakeup_sysfs_add(struct device *dev)
492{ 519{
493 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); 520 return sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group);
494} 521}
495 522
496void dpm_sysfs_remove(struct device *dev) 523void wakeup_sysfs_remove(struct device *dev)
497{ 524{
498 rpm_sysfs_remove(dev); 525 sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
499 sysfs_remove_group(&dev->kobj, &pm_attr_group);
500} 526}
501 527
502#else /* CONFIG_PM_RUNTIME */ 528void rpm_sysfs_remove(struct device *dev)
503
504int dpm_sysfs_add(struct device * dev)
505{ 529{
506 return sysfs_create_group(&dev->kobj, &pm_attr_group); 530 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
507} 531}
508 532
509void dpm_sysfs_remove(struct device * dev) 533void dpm_sysfs_remove(struct device *dev)
510{ 534{
535 rpm_sysfs_remove(dev);
536 sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
511 sysfs_remove_group(&dev->kobj, &pm_attr_group); 537 sysfs_remove_group(&dev->kobj, &pm_attr_group);
512} 538}
513
514#endif