aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r--drivers/acpi/power.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 34f5ef11d427..0e3f57674fd1 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -459,57 +459,79 @@ static struct attribute_group attr_groups[] = {
459 }, 459 },
460}; 460};
461 461
462static void acpi_power_hide_list(struct acpi_device *adev, int state) 462static struct attribute_group wakeup_attr_group = {
463 .name = "power_resources_wakeup",
464 .attrs = attrs,
465};
466
467static void acpi_power_hide_list(struct acpi_device *adev,
468 struct list_head *resources,
469 struct attribute_group *attr_group)
463{ 470{
464 struct acpi_device_power_state *ps = &adev->power.states[state];
465 struct acpi_power_resource_entry *entry; 471 struct acpi_power_resource_entry *entry;
466 472
467 if (list_empty(&ps->resources)) 473 if (list_empty(resources))
468 return; 474 return;
469 475
470 list_for_each_entry_reverse(entry, &ps->resources, node) { 476 list_for_each_entry_reverse(entry, resources, node) {
471 struct acpi_device *res_dev = &entry->resource->device; 477 struct acpi_device *res_dev = &entry->resource->device;
472 478
473 sysfs_remove_link_from_group(&adev->dev.kobj, 479 sysfs_remove_link_from_group(&adev->dev.kobj,
474 attr_groups[state].name, 480 attr_group->name,
475 dev_name(&res_dev->dev)); 481 dev_name(&res_dev->dev));
476 } 482 }
477 sysfs_remove_group(&adev->dev.kobj, &attr_groups[state]); 483 sysfs_remove_group(&adev->dev.kobj, attr_group);
478} 484}
479 485
480static void acpi_power_expose_list(struct acpi_device *adev, int state) 486static void acpi_power_expose_list(struct acpi_device *adev,
487 struct list_head *resources,
488 struct attribute_group *attr_group)
481{ 489{
482 struct acpi_device_power_state *ps = &adev->power.states[state];
483 struct acpi_power_resource_entry *entry; 490 struct acpi_power_resource_entry *entry;
484 int ret; 491 int ret;
485 492
486 if (list_empty(&ps->resources)) 493 if (list_empty(resources))
487 return; 494 return;
488 495
489 ret = sysfs_create_group(&adev->dev.kobj, &attr_groups[state]); 496 ret = sysfs_create_group(&adev->dev.kobj, attr_group);
490 if (ret) 497 if (ret)
491 return; 498 return;
492 499
493 list_for_each_entry(entry, &ps->resources, node) { 500 list_for_each_entry(entry, resources, node) {
494 struct acpi_device *res_dev = &entry->resource->device; 501 struct acpi_device *res_dev = &entry->resource->device;
495 502
496 ret = sysfs_add_link_to_group(&adev->dev.kobj, 503 ret = sysfs_add_link_to_group(&adev->dev.kobj,
497 attr_groups[state].name, 504 attr_group->name,
498 &res_dev->dev.kobj, 505 &res_dev->dev.kobj,
499 dev_name(&res_dev->dev)); 506 dev_name(&res_dev->dev));
500 if (ret) { 507 if (ret) {
501 acpi_power_hide_list(adev, state); 508 acpi_power_hide_list(adev, resources, attr_group);
502 break; 509 break;
503 } 510 }
504 } 511 }
505} 512}
506 513
514static void acpi_power_expose_hide(struct acpi_device *adev,
515 struct list_head *resources,
516 struct attribute_group *attr_group,
517 bool expose)
518{
519 if (expose)
520 acpi_power_expose_list(adev, resources, attr_group);
521 else
522 acpi_power_hide_list(adev, resources, attr_group);
523}
524
507void acpi_power_add_remove_device(struct acpi_device *adev, bool add) 525void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
508{ 526{
509 struct acpi_device_power_state *ps; 527 struct acpi_device_power_state *ps;
510 struct acpi_power_resource_entry *entry; 528 struct acpi_power_resource_entry *entry;
511 int state; 529 int state;
512 530
531 if (adev->wakeup.flags.valid)
532 acpi_power_expose_hide(adev, &adev->wakeup.resources,
533 &wakeup_attr_group, add);
534
513 if (!adev->power.flags.power_resources) 535 if (!adev->power.flags.power_resources)
514 return; 536 return;
515 537
@@ -523,12 +545,10 @@ void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
523 acpi_power_remove_dependent(resource, adev); 545 acpi_power_remove_dependent(resource, adev);
524 } 546 }
525 547
526 for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++) { 548 for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++)
527 if (add) 549 acpi_power_expose_hide(adev,
528 acpi_power_expose_list(adev, state); 550 &adev->power.states[state].resources,
529 else 551 &attr_groups[state], add);
530 acpi_power_hide_list(adev, state);
531 }
532} 552}
533 553
534int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p) 554int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)