diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-05-02 18:26:16 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-05-12 08:14:24 -0400 |
commit | 683058e315f00a216fd6c79df4f63bc9945ca434 (patch) | |
tree | e4b143220938ebb24a7bf72f286f275090b2afef /drivers/acpi/sysfs.c | |
parent | 0902a9044fa5b7a0456ea4daacec2c2b3189ba8c (diff) |
ACPI / hotplug: Use device offline/online for graceful hot-removal
Modify the generic ACPI hotplug code to be able to check if devices
scheduled for hot-removal may be gracefully removed from the system
using the device offline/online mechanism introduced previously.
Namely, make acpi_scan_hot_remove() handling device hot-removal call
device_offline() for all physical companions of the ACPI device nodes
involved in the operation and check the results. If any of the
device_offline() calls fails, the function will not progress to the
removal phase (which cannot be aborted), unless its (new) force
argument is set (in case of a failing offline it will put the devices
offlined by it back online).
In support of 'forced' device hot-removal, add a new sysfs attribute
'force_remove' that will reside under /sys/firmware/acpi/hotplug/.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Toshi Kani <toshi.kani@hp.com>
Diffstat (limited to 'drivers/acpi/sysfs.c')
-rw-r--r-- | drivers/acpi/sysfs.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index fcae5fa2e1b3..5c5d1624fa2c 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -780,6 +780,33 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, | |||
780 | pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name); | 780 | pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name); |
781 | } | 781 | } |
782 | 782 | ||
783 | static ssize_t force_remove_show(struct kobject *kobj, | ||
784 | struct kobj_attribute *attr, char *buf) | ||
785 | { | ||
786 | return sprintf(buf, "%d\n", !!acpi_force_hot_remove); | ||
787 | } | ||
788 | |||
789 | static ssize_t force_remove_store(struct kobject *kobj, | ||
790 | struct kobj_attribute *attr, | ||
791 | const char *buf, size_t size) | ||
792 | { | ||
793 | bool val; | ||
794 | int ret; | ||
795 | |||
796 | ret = strtobool(buf, &val); | ||
797 | if (ret < 0) | ||
798 | return ret; | ||
799 | |||
800 | lock_device_hotplug(); | ||
801 | acpi_force_hot_remove = val; | ||
802 | unlock_device_hotplug(); | ||
803 | return size; | ||
804 | } | ||
805 | |||
806 | static const struct kobj_attribute force_remove_attr = | ||
807 | __ATTR(force_remove, S_IRUGO | S_IWUSR, force_remove_show, | ||
808 | force_remove_store); | ||
809 | |||
783 | int __init acpi_sysfs_init(void) | 810 | int __init acpi_sysfs_init(void) |
784 | { | 811 | { |
785 | int result; | 812 | int result; |
@@ -789,6 +816,10 @@ int __init acpi_sysfs_init(void) | |||
789 | return result; | 816 | return result; |
790 | 817 | ||
791 | hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj); | 818 | hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj); |
819 | result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr); | ||
820 | if (result) | ||
821 | return result; | ||
822 | |||
792 | result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr); | 823 | result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr); |
793 | return result; | 824 | return result; |
794 | } | 825 | } |