aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sysfs.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-03-03 17:08:16 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-03-04 08:25:32 -0500
commit3f8055c3583640ed3e4c81864dd76e06a7faa505 (patch)
treec77ae4121942fc43be57cd603435f1a9dcb78b3d /drivers/acpi/sysfs.c
parent4b59cc1fd6fd1dac1d4468b4f327ae9f59d1c0aa (diff)
ACPI / hotplug: Introduce user space interface for hotplug profiles
Introduce user space interface for manipulating hotplug profiles associated with ACPI scan handlers. The interface consists of sysfs directories under /sys/firmware/acpi/hotplug/, one for each hotplug profile, containing an attribute allowing user space to manipulate the enabled field of the corresponding profile. Namely, switching the enabled attribute from '0' to '1' will cause the common hotplug notify handler to be installed for all ACPI namespace objects representing devices matching the scan handler associated with the given hotplug profile (and analogously for the converse switch). Drivers willing to use the new user space interface should add their ACPI scan handlers with the help of new funtion acpi_scan_add_handler_with_hotplug(). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Tested-by: Toshi Kani <toshi.kani@hp.com>
Diffstat (limited to 'drivers/acpi/sysfs.c')
-rw-r--r--drivers/acpi/sysfs.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 41c0504470db..83db3a68a7ee 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -7,6 +7,8 @@
7#include <linux/moduleparam.h> 7#include <linux/moduleparam.h>
8#include <acpi/acpi_drivers.h> 8#include <acpi/acpi_drivers.h>
9 9
10#include "internal.h"
11
10#define _COMPONENT ACPI_SYSTEM_COMPONENT 12#define _COMPONENT ACPI_SYSTEM_COMPONENT
11ACPI_MODULE_NAME("sysfs"); 13ACPI_MODULE_NAME("sysfs");
12 14
@@ -249,6 +251,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
249static LIST_HEAD(acpi_table_attr_list); 251static LIST_HEAD(acpi_table_attr_list);
250static struct kobject *tables_kobj; 252static struct kobject *tables_kobj;
251static struct kobject *dynamic_tables_kobj; 253static struct kobject *dynamic_tables_kobj;
254static struct kobject *hotplug_kobj;
252 255
253struct acpi_table_attr { 256struct acpi_table_attr {
254 struct bin_attribute attr; 257 struct bin_attribute attr;
@@ -716,6 +719,67 @@ acpi_show_profile(struct device *dev, struct device_attribute *attr,
716static const struct device_attribute pm_profile_attr = 719static const struct device_attribute pm_profile_attr =
717 __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL); 720 __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL);
718 721
722static ssize_t hotplug_enabled_show(struct kobject *kobj,
723 struct kobj_attribute *attr, char *buf)
724{
725 struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
726
727 return sprintf(buf, "%d\n", hotplug->enabled);
728}
729
730static ssize_t hotplug_enabled_store(struct kobject *kobj,
731 struct kobj_attribute *attr,
732 const char *buf, size_t size)
733{
734 struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
735 unsigned int val;
736
737 if (kstrtouint(buf, 10, &val) || val > 1)
738 return -EINVAL;
739
740 acpi_scan_hotplug_enabled(hotplug, val);
741 return size;
742}
743
744static struct kobj_attribute hotplug_enabled_attr =
745 __ATTR(enabled, S_IRUGO | S_IWUSR, hotplug_enabled_show,
746 hotplug_enabled_store);
747
748static struct attribute *hotplug_profile_attrs[] = {
749 &hotplug_enabled_attr.attr,
750 NULL
751};
752
753struct kobj_type acpi_hotplug_profile_ktype = {
754 .sysfs_ops = &kobj_sysfs_ops,
755 .default_attrs = hotplug_profile_attrs,
756};
757
758void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
759 const char *name)
760{
761 int error;
762
763 if (!hotplug_kobj)
764 goto err_out;
765
766 kobject_init(&hotplug->kobj, &acpi_hotplug_profile_ktype);
767 error = kobject_set_name(&hotplug->kobj, "%s", name);
768 if (error)
769 goto err_out;
770
771 hotplug->kobj.parent = hotplug_kobj;
772 error = kobject_add(&hotplug->kobj, hotplug_kobj, NULL);
773 if (error)
774 goto err_out;
775
776 kobject_uevent(&hotplug->kobj, KOBJ_ADD);
777 return;
778
779 err_out:
780 pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name);
781}
782
719int __init acpi_sysfs_init(void) 783int __init acpi_sysfs_init(void)
720{ 784{
721 int result; 785 int result;
@@ -723,6 +787,8 @@ int __init acpi_sysfs_init(void)
723 result = acpi_tables_sysfs_init(); 787 result = acpi_tables_sysfs_init();
724 if (result) 788 if (result)
725 return result; 789 return result;
790
791 hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
726 result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr); 792 result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
727 return result; 793 return result;
728} 794}