summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@linux.intel.com>2006-12-07 20:56:38 +0800
committerLen Brown <len.brown@intel.com>2006-12-15 23:38:34 -0500
commitf883d9db008deb20d4969c26475100cec2b7f6f8 (patch)
tree4d66f2bf9f0a6142685870177e26837fc510f9e1 /drivers/acpi/scan.c
parenta7178df5e7e5730e5daa6cf6d8b8bf73adbe75c0 (diff)
downloadlinux-f883d9db008deb20d4969c26475100cec2b7f6f8.tar.gz
linux-f883d9db008deb20d4969c26475100cec2b7f6f8.tar.bz2
linux-f883d9db008deb20d4969c26475100cec2b7f6f8.zip
ACPI: convert to sysfs framework
Setup new sysfs framework 1. Remove /sys/firmware/acpi 2. Add ACPI device in device tree. File "eject" for every device that has _EJ0 method is moved from /sys/firmware to /sys/devices. Operation on this file is exactly the same as before. i.e. echo 1 to "eject" will cause hot removal of this device. Corresponding changes should be made in userspace for hot removal. Signed-off-by: Li Shaohua <shaohua.li@intel.com> Signed-off-by: Zhang Rui<rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c187
1 files changed, 41 insertions, 146 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b616e17de522..97f6bbd6ef3c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -24,126 +24,6 @@ static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
-
-static void acpi_device_release_legacy(struct kobject *kobj)
-{
- struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
- kfree(dev->pnp.cid_list);
- kfree(dev);
-}
-
-struct acpi_device_attribute {
- struct attribute attr;
- ssize_t(*show) (struct acpi_device *, char *);
- ssize_t(*store) (struct acpi_device *, const char *, size_t);
-};
-
-typedef void acpi_device_sysfs_files(struct kobject *,
- const struct attribute *);
-
-static void setup_sys_fs_device_files(struct acpi_device *dev,
- acpi_device_sysfs_files * func);
-
-#define create_sysfs_device_files(dev) \
- setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
-#define remove_sysfs_device_files(dev) \
- setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
-
-#define to_acpi_dev(n) container_of(n, struct acpi_device, kobj)
-#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
-
-static ssize_t acpi_device_attr_show(struct kobject *kobj,
- struct attribute *attr, char *buf)
-{
- struct acpi_device *device = to_acpi_dev(kobj);
- struct acpi_device_attribute *attribute = to_handle_attr(attr);
- return attribute->show ? attribute->show(device, buf) : -EIO;
-}
-static ssize_t acpi_device_attr_store(struct kobject *kobj,
- struct attribute *attr, const char *buf,
- size_t len)
-{
- struct acpi_device *device = to_acpi_dev(kobj);
- struct acpi_device_attribute *attribute = to_handle_attr(attr);
- return attribute->store ? attribute->store(device, buf, len) : -EIO;
-}
-
-static struct sysfs_ops acpi_device_sysfs_ops = {
- .show = acpi_device_attr_show,
- .store = acpi_device_attr_store,
-};
-
-static struct kobj_type ktype_acpi_ns = {
- .sysfs_ops = &acpi_device_sysfs_ops,
- .release = acpi_device_release_legacy,
-};
-
-static int namespace_uevent(struct kset *kset, struct kobject *kobj,
- char **envp, int num_envp, char *buffer,
- int buffer_size)
-{
- struct acpi_device *dev = to_acpi_dev(kobj);
- int i = 0;
- int len = 0;
-
- if (!dev->driver)
- return 0;
-
- if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
- "PHYSDEVDRIVER=%s", dev->driver->name))
- return -ENOMEM;
-
- envp[i] = NULL;
-
- return 0;
-}
-
-static struct kset_uevent_ops namespace_uevent_ops = {
- .uevent = &namespace_uevent,
-};
-
-static struct kset acpi_namespace_kset = {
- .kobj = {
- .name = "namespace",
- },
- .subsys = &acpi_subsys,
- .ktype = &ktype_acpi_ns,
- .uevent_ops = &namespace_uevent_ops,
-};
-
-/* --------------------------------------------------------------------------
- ACPI sysfs device file support
- -------------------------------------------------------------------------- */
-static ssize_t acpi_eject_store(struct acpi_device *device,
- const char *buf, size_t count);
-
-#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
-static struct acpi_device_attribute acpi_device_attr_##_name = \
- __ATTR(_name, _mode, _show, _store)
-
-ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
-
-/**
- * setup_sys_fs_device_files - sets up the device files under device namespace
- * @dev: acpi_device object
- * @func: function pointer to create or destroy the device file
- */
-static void
-setup_sys_fs_device_files(struct acpi_device *dev,
- acpi_device_sysfs_files * func)
-{
- acpi_status status;
- acpi_handle temp = NULL;
-
- /*
- * If device has _EJ0, 'eject' file is created that is used to trigger
- * hot-removal function from userland.
- */
- status = acpi_get_handle(dev->handle, "_EJ0", &temp);
- if (ACPI_SUCCESS(status))
- (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
-}
-
static int acpi_eject_operation(acpi_handle handle, int lockable)
{
struct acpi_object_list arg_list;
@@ -180,7 +60,8 @@ static int acpi_eject_operation(acpi_handle handle, int lockable)
}
static ssize_t
-acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
+acpi_eject_store(struct device *d, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int result;
int ret = count;
@@ -188,26 +69,27 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
acpi_status status;
acpi_handle handle;
acpi_object_type type = 0;
+ struct acpi_device *acpi_device = to_acpi_device(d);
if ((!count) || (buf[0] != '1')) {
return -EINVAL;
}
#ifndef FORCE_EJECT
- if (device->driver == NULL) {
+ if (acpi_device->driver == NULL) {
ret = -ENODEV;
goto err;
}
#endif
- status = acpi_get_type(device->handle, &type);
- if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
+ status = acpi_get_type(acpi_device->handle, &type);
+ if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
ret = -ENODEV;
goto err;
}
- islockable = device->flags.lockable;
- handle = device->handle;
+ islockable = acpi_device->flags.lockable;
+ handle = acpi_device->handle;
- result = acpi_bus_trim(device, 1);
+ result = acpi_bus_trim(acpi_device, 1);
if (!result)
result = acpi_eject_operation(handle, islockable);
@@ -219,6 +101,35 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
return ret;
}
+static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
+
+static void acpi_device_setup_files(struct acpi_device *dev)
+{
+ acpi_status status;
+ acpi_handle temp;
+
+ /*
+ * If device has _EJ0, 'eject' file is created that is used to trigger
+ * hot-removal function from userland.
+ */
+ status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+ if (ACPI_SUCCESS(status))
+ device_create_file(&dev->dev, &dev_attr_eject);
+}
+
+static void acpi_device_remove_files(struct acpi_device *dev)
+{
+ acpi_status status;
+ acpi_handle temp;
+
+ /*
+ * If device has _EJ0, 'eject' file is created that is used to trigger
+ * hot-removal function from userland.
+ */
+ status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+ if (ACPI_SUCCESS(status))
+ device_remove_file(&dev->dev, &dev_attr_eject);
+}
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
@@ -353,8 +264,6 @@ static struct bus_type acpi_bus_type = {
static void acpi_device_register(struct acpi_device *device,
struct acpi_device *parent)
{
- int err;
-
/*
* Linkage
* -------
@@ -375,17 +284,6 @@ static void acpi_device_register(struct acpi_device *device,
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
spin_unlock(&acpi_device_lock);
- strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN);
- if (parent)
- device->kobj.parent = &parent->kobj;
- device->kobj.ktype = &ktype_acpi_ns;
- device->kobj.kset = &acpi_namespace_kset;
- err = kobject_register(&device->kobj);
- if (err < 0)
- printk(KERN_WARNING "%s: kobject_register error: %d\n",
- __FUNCTION__, err);
- create_sysfs_device_files(device);
-
if (device->parent)
device->dev.parent = &parent->dev;
device->dev.bus = &acpi_bus_type;
@@ -393,6 +291,8 @@ static void acpi_device_register(struct acpi_device *device,
sprintf(device->dev.bus_id, "%s", device->pnp.bus_id);
device->dev.release = &acpi_device_release;
device_add(&device->dev);
+
+ acpi_device_setup_files(device);
}
static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -409,9 +309,8 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
spin_unlock(&acpi_device_lock);
acpi_detach_data(device->handle, acpi_bus_data_handler);
- remove_sysfs_device_files(device);
- kobject_unregister(&device->kobj);
+ acpi_device_remove_files(device);
device_unregister(&device->dev);
}
@@ -1353,10 +1252,6 @@ static int __init acpi_scan_init(void)
if (acpi_disabled)
return 0;
- result = kset_register(&acpi_namespace_kset);
- if (result < 0)
- printk(KERN_ERR PREFIX "kset_register error: %d\n", result);
-
result = bus_register(&acpi_bus_type);
if (result) {
/* We don't want to quit even if we failed to add suspend/resume */