* contents of sysfs branch
@ 2006-11-24 5:17 Len Brown
[not found] ` <bd119392c453771fdb994728a2568c2e3f17705d.1164343921.git.len.brown@intel.com>
2006-12-01 8:55 ` updated patches of sysfs branch Zhang Rui
0 siblings, 2 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi
The following patches are on the "sysfs" branch of the ACPI git tree.
To test, apply this e-mail series, or git pull from here:
git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git sysfs
I am hopeful that this series will settle down and make the test branch
shortly, and thus make its way into an upcoming -mm release, and then upstream.
thanks,
-Len
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/13] ACPI: clean up scan.c
[not found] ` <bd119392c453771fdb994728a2568c2e3f17705d.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
[not found] ` <1b3d821f47ae0d8393851c4ff82f6dd667868ead.1164343921.git.len.brown@intel.com>
` (11 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
Adjust the code and make code doing similar things together.
No logic changes.
Signed-off-by : Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 645 +++++++++++++++++++++++++--------------------------
1 files changed, 316 insertions(+), 329 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 698a154..e0255cb 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -111,233 +111,6 @@ static struct kset acpi_namespace_kset =
.uevent_ops = &namespace_uevent_ops,
};
-static void acpi_device_register(struct acpi_device *device,
- struct acpi_device *parent)
-{
- int err;
-
- /*
- * Linkage
- * -------
- * Link this device to its parent and siblings.
- */
- INIT_LIST_HEAD(&device->children);
- INIT_LIST_HEAD(&device->node);
- INIT_LIST_HEAD(&device->g_list);
- INIT_LIST_HEAD(&device->wakeup_list);
-
- spin_lock(&acpi_device_lock);
- if (device->parent) {
- list_add_tail(&device->node, &device->parent->children);
- list_add_tail(&device->g_list, &device->parent->g_list);
- } else
- list_add_tail(&device->g_list, &acpi_device_list);
- if (device->wakeup.flags.valid)
- 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);
-}
-
-static void acpi_device_unregister(struct acpi_device *device, int type)
-{
- spin_lock(&acpi_device_lock);
- if (device->parent) {
- list_del(&device->node);
- list_del(&device->g_list);
- } else
- list_del(&device->g_list);
-
- list_del(&device->wakeup_list);
-
- spin_unlock(&acpi_device_lock);
-
- acpi_detach_data(device->handle, acpi_bus_data_handler);
- remove_sysfs_device_files(device);
- kobject_unregister(&device->kobj);
-}
-
-void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
-{
-
- /* TBD */
-
- return;
-}
-
-static int acpi_bus_get_power_flags(struct acpi_device *device)
-{
- acpi_status status = 0;
- acpi_handle handle = NULL;
- u32 i = 0;
-
-
- /*
- * Power Management Flags
- */
- status = acpi_get_handle(device->handle, "_PSC", &handle);
- if (ACPI_SUCCESS(status))
- device->power.flags.explicit_get = 1;
- status = acpi_get_handle(device->handle, "_IRC", &handle);
- if (ACPI_SUCCESS(status))
- device->power.flags.inrush_current = 1;
-
- /*
- * Enumerate supported power management states
- */
- for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
- struct acpi_device_power_state *ps = &device->power.states[i];
- char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
-
- /* Evaluate "_PRx" to se if power resources are referenced */
- acpi_evaluate_reference(device->handle, object_name, NULL,
- &ps->resources);
- if (ps->resources.count) {
- device->power.flags.power_resources = 1;
- ps->flags.valid = 1;
- }
-
- /* Evaluate "_PSx" to see if we can do explicit sets */
- object_name[2] = 'S';
- status = acpi_get_handle(device->handle, object_name, &handle);
- if (ACPI_SUCCESS(status)) {
- ps->flags.explicit_set = 1;
- ps->flags.valid = 1;
- }
-
- /* State is valid if we have some power control */
- if (ps->resources.count || ps->flags.explicit_set)
- ps->flags.valid = 1;
-
- ps->power = -1; /* Unknown - driver assigned */
- ps->latency = -1; /* Unknown - driver assigned */
- }
-
- /* Set defaults for D0 and D3 states (always valid) */
- device->power.states[ACPI_STATE_D0].flags.valid = 1;
- device->power.states[ACPI_STATE_D0].power = 100;
- device->power.states[ACPI_STATE_D3].flags.valid = 1;
- device->power.states[ACPI_STATE_D3].power = 0;
-
- /* TBD: System wake support and resource requirements. */
-
- device->power.state = ACPI_STATE_UNKNOWN;
-
- return 0;
-}
-
-int acpi_match_ids(struct acpi_device *device, char *ids)
-{
- if (device->flags.hardware_id)
- if (strstr(ids, device->pnp.hardware_id))
- return 0;
-
- if (device->flags.compatible_ids) {
- struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
- int i;
-
- /* compare multiple _CID entries against driver ids */
- for (i = 0; i < cid_list->count; i++) {
- if (strstr(ids, cid_list->id[i].value))
- return 0;
- }
- }
- return -ENOENT;
-}
-
-static acpi_status
-acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
- union acpi_object *package)
-{
- int i = 0;
- union acpi_object *element = NULL;
-
- if (!device || !package || (package->package.count < 2))
- return AE_BAD_PARAMETER;
-
- element = &(package->package.elements[0]);
- if (!element)
- return AE_BAD_PARAMETER;
- if (element->type == ACPI_TYPE_PACKAGE) {
- if ((element->package.count < 2) ||
- (element->package.elements[0].type !=
- ACPI_TYPE_LOCAL_REFERENCE)
- || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
- return AE_BAD_DATA;
- device->wakeup.gpe_device =
- element->package.elements[0].reference.handle;
- device->wakeup.gpe_number =
- (u32) element->package.elements[1].integer.value;
- } else if (element->type == ACPI_TYPE_INTEGER) {
- device->wakeup.gpe_number = element->integer.value;
- } else
- return AE_BAD_DATA;
-
- element = &(package->package.elements[1]);
- if (element->type != ACPI_TYPE_INTEGER) {
- return AE_BAD_DATA;
- }
- device->wakeup.sleep_state = element->integer.value;
-
- if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
- return AE_NO_MEMORY;
- }
- device->wakeup.resources.count = package->package.count - 2;
- for (i = 0; i < device->wakeup.resources.count; i++) {
- element = &(package->package.elements[i + 2]);
- if (element->type != ACPI_TYPE_ANY) {
- return AE_BAD_DATA;
- }
-
- device->wakeup.resources.handles[i] = element->reference.handle;
- }
-
- return AE_OK;
-}
-
-static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
-{
- acpi_status status = 0;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *package = NULL;
-
-
- /* _PRW */
- status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
- goto end;
- }
-
- package = (union acpi_object *)buffer.pointer;
- status = acpi_bus_extract_wakeup_device_power_package(device, package);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
- goto end;
- }
-
- kfree(buffer.pointer);
-
- device->wakeup.flags.valid = 1;
- /* Power button, Lid switch always enable wakeup */
- if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
- device->wakeup.flags.run_wake = 1;
-
- end:
- if (ACPI_FAILURE(status))
- device->flags.wake_capable = 0;
- return 0;
-}
-
/* --------------------------------------------------------------------------
ACPI sysfs device file support
-------------------------------------------------------------------------- */
@@ -447,20 +220,86 @@ acpi_eject_store(struct acpi_device *dev
}
/* --------------------------------------------------------------------------
- Performance Management
+ ACPI Bus operations
-------------------------------------------------------------------------- */
+static inline struct acpi_device * to_acpi_dev(struct device * dev)
+{
+ return container_of(dev, struct acpi_device, dev);
+}
-static int acpi_bus_get_perf_flags(struct acpi_device *device)
+static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
{
- device->performance.state = ACPI_STATE_UNKNOWN;
+ struct acpi_device * dev, * next;
+ int result;
+
+ spin_lock(&acpi_device_lock);
+ list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
+ if (dev->driver && dev->driver->ops.suspend) {
+ spin_unlock(&acpi_device_lock);
+ result = dev->driver->ops.suspend(dev, 0);
+ if (result) {
+ printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
+ acpi_device_name(dev),
+ acpi_device_bid(dev), result);
+ }
+ spin_lock(&acpi_device_lock);
+ }
+ }
+ spin_unlock(&acpi_device_lock);
return 0;
}
-/* --------------------------------------------------------------------------
- Driver Management
- -------------------------------------------------------------------------- */
+static int acpi_device_suspend(struct device * dev, pm_message_t state)
+{
+ struct acpi_device * acpi_dev = to_acpi_dev(dev);
-static LIST_HEAD(acpi_bus_drivers);
+ /*
+ * For now, we should only register 1 generic device -
+ * the ACPI root device - and from there, we walk the
+ * tree of ACPI devices to suspend each one using the
+ * ACPI driver methods.
+ */
+ if (acpi_dev->handle == ACPI_ROOT_OBJECT)
+ root_suspend(acpi_dev, state);
+ return 0;
+}
+
+static int root_resume(struct acpi_device * acpi_dev)
+{
+ struct acpi_device * dev, * next;
+ int result;
+
+ spin_lock(&acpi_device_lock);
+ list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
+ if (dev->driver && dev->driver->ops.resume) {
+ spin_unlock(&acpi_device_lock);
+ result = dev->driver->ops.resume(dev, 0);
+ if (result) {
+ printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
+ acpi_device_name(dev),
+ acpi_device_bid(dev), result);
+ }
+ spin_lock(&acpi_device_lock);
+ }
+ }
+ spin_unlock(&acpi_device_lock);
+ return 0;
+}
+
+static int acpi_device_resume(struct device * dev)
+{
+ struct acpi_device * acpi_dev = to_acpi_dev(dev);
+
+ /*
+ * For now, we should only register 1 generic device -
+ * the ACPI root device - and from there, we walk the
+ * tree of ACPI devices to resume each one using the
+ * ACPI driver methods.
+ */
+ if (acpi_dev->handle == ACPI_ROOT_OBJECT)
+ root_resume(acpi_dev);
+ return 0;
+}
/**
* acpi_bus_match - match device IDs to driver's supported IDs
@@ -478,6 +317,72 @@ acpi_bus_match(struct acpi_device *devic
return acpi_match_ids(device, driver->ids);
}
+static struct bus_type acpi_bus_type = {
+ .name = "acpi",
+ .suspend = acpi_device_suspend,
+ .resume = acpi_device_resume,
+};
+
+static void acpi_device_register(struct acpi_device *device,
+ struct acpi_device *parent)
+{
+ int err;
+
+ /*
+ * Linkage
+ * -------
+ * Link this device to its parent and siblings.
+ */
+ INIT_LIST_HEAD(&device->children);
+ INIT_LIST_HEAD(&device->node);
+ INIT_LIST_HEAD(&device->g_list);
+ INIT_LIST_HEAD(&device->wakeup_list);
+
+ spin_lock(&acpi_device_lock);
+ if (device->parent) {
+ list_add_tail(&device->node, &device->parent->children);
+ list_add_tail(&device->g_list, &device->parent->g_list);
+ } else
+ list_add_tail(&device->g_list, &acpi_device_list);
+ if (device->wakeup.flags.valid)
+ 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);
+}
+
+static void acpi_device_unregister(struct acpi_device *device, int type)
+{
+ spin_lock(&acpi_device_lock);
+ if (device->parent) {
+ list_del(&device->node);
+ list_del(&device->g_list);
+ } else
+ list_del(&device->g_list);
+
+ list_del(&device->wakeup_list);
+
+ spin_unlock(&acpi_device_lock);
+
+ acpi_detach_data(device->handle, acpi_bus_data_handler);
+ remove_sysfs_device_files(device);
+ kobject_unregister(&device->kobj);
+}
+
+/* --------------------------------------------------------------------------
+ Driver Management
+ -------------------------------------------------------------------------- */
+static LIST_HEAD(acpi_bus_drivers);
+
/**
* acpi_bus_driver_init - add a device to a driver
* @device: the device to add and initialize
@@ -668,7 +573,6 @@ static int acpi_bus_find_driver(struct a
/* --------------------------------------------------------------------------
Device Enumeration
-------------------------------------------------------------------------- */
-
acpi_status
acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
{
@@ -691,6 +595,183 @@ acpi_bus_get_ejd(acpi_handle handle, acp
}
EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
+void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
+{
+
+ /* TBD */
+
+ return;
+}
+
+int acpi_match_ids(struct acpi_device *device, char *ids)
+{
+ if (device->flags.hardware_id)
+ if (strstr(ids, device->pnp.hardware_id))
+ return 0;
+
+ if (device->flags.compatible_ids) {
+ struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+ int i;
+
+ /* compare multiple _CID entries against driver ids */
+ for (i = 0; i < cid_list->count; i++) {
+ if (strstr(ids, cid_list->id[i].value))
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+static int acpi_bus_get_perf_flags(struct acpi_device *device)
+{
+ device->performance.state = ACPI_STATE_UNKNOWN;
+ return 0;
+}
+
+static acpi_status
+acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
+ union acpi_object *package)
+{
+ int i = 0;
+ union acpi_object *element = NULL;
+
+ if (!device || !package || (package->package.count < 2))
+ return AE_BAD_PARAMETER;
+
+ element = &(package->package.elements[0]);
+ if (!element)
+ return AE_BAD_PARAMETER;
+ if (element->type == ACPI_TYPE_PACKAGE) {
+ if ((element->package.count < 2) ||
+ (element->package.elements[0].type !=
+ ACPI_TYPE_LOCAL_REFERENCE)
+ || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
+ return AE_BAD_DATA;
+ device->wakeup.gpe_device =
+ element->package.elements[0].reference.handle;
+ device->wakeup.gpe_number =
+ (u32) element->package.elements[1].integer.value;
+ } else if (element->type == ACPI_TYPE_INTEGER) {
+ device->wakeup.gpe_number = element->integer.value;
+ } else
+ return AE_BAD_DATA;
+
+ element = &(package->package.elements[1]);
+ if (element->type != ACPI_TYPE_INTEGER) {
+ return AE_BAD_DATA;
+ }
+ device->wakeup.sleep_state = element->integer.value;
+
+ if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
+ return AE_NO_MEMORY;
+ }
+ device->wakeup.resources.count = package->package.count - 2;
+ for (i = 0; i < device->wakeup.resources.count; i++) {
+ element = &(package->package.elements[i + 2]);
+ if (element->type != ACPI_TYPE_ANY) {
+ return AE_BAD_DATA;
+ }
+
+ device->wakeup.resources.handles[i] = element->reference.handle;
+ }
+
+ return AE_OK;
+}
+
+static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
+{
+ acpi_status status = 0;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *package = NULL;
+
+
+ /* _PRW */
+ status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
+ goto end;
+ }
+
+ package = (union acpi_object *)buffer.pointer;
+ status = acpi_bus_extract_wakeup_device_power_package(device, package);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
+ goto end;
+ }
+
+ kfree(buffer.pointer);
+
+ device->wakeup.flags.valid = 1;
+ /* Power button, Lid switch always enable wakeup */
+ if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
+ device->wakeup.flags.run_wake = 1;
+
+ end:
+ if (ACPI_FAILURE(status))
+ device->flags.wake_capable = 0;
+ return 0;
+}
+
+static int acpi_bus_get_power_flags(struct acpi_device *device)
+{
+ acpi_status status = 0;
+ acpi_handle handle = NULL;
+ u32 i = 0;
+
+
+ /*
+ * Power Management Flags
+ */
+ status = acpi_get_handle(device->handle, "_PSC", &handle);
+ if (ACPI_SUCCESS(status))
+ device->power.flags.explicit_get = 1;
+ status = acpi_get_handle(device->handle, "_IRC", &handle);
+ if (ACPI_SUCCESS(status))
+ device->power.flags.inrush_current = 1;
+
+ /*
+ * Enumerate supported power management states
+ */
+ for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
+ struct acpi_device_power_state *ps = &device->power.states[i];
+ char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
+
+ /* Evaluate "_PRx" to se if power resources are referenced */
+ acpi_evaluate_reference(device->handle, object_name, NULL,
+ &ps->resources);
+ if (ps->resources.count) {
+ device->power.flags.power_resources = 1;
+ ps->flags.valid = 1;
+ }
+
+ /* Evaluate "_PSx" to see if we can do explicit sets */
+ object_name[2] = 'S';
+ status = acpi_get_handle(device->handle, object_name, &handle);
+ if (ACPI_SUCCESS(status)) {
+ ps->flags.explicit_set = 1;
+ ps->flags.valid = 1;
+ }
+
+ /* State is valid if we have some power control */
+ if (ps->resources.count || ps->flags.explicit_set)
+ ps->flags.valid = 1;
+
+ ps->power = -1; /* Unknown - driver assigned */
+ ps->latency = -1; /* Unknown - driver assigned */
+ }
+
+ /* Set defaults for D0 and D3 states (always valid) */
+ device->power.states[ACPI_STATE_D0].flags.valid = 1;
+ device->power.states[ACPI_STATE_D0].power = 100;
+ device->power.states[ACPI_STATE_D3].flags.valid = 1;
+ device->power.states[ACPI_STATE_D3].power = 0;
+
+ /* TBD: System wake support and resource requirements. */
+
+ device->power.state = ACPI_STATE_UNKNOWN;
+
+ return 0;
+}
static int acpi_bus_get_flags(struct acpi_device *device)
{
@@ -1353,100 +1434,6 @@ static int acpi_bus_scan_fixed(struct ac
return result;
}
-
-static inline struct acpi_device * to_acpi_dev(struct device * dev)
-{
- return container_of(dev, struct acpi_device, dev);
-}
-
-
-static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
-{
- struct acpi_device * dev, * next;
- int result;
-
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.suspend) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.suspend(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
- }
- }
- spin_unlock(&acpi_device_lock);
- return 0;
-}
-
-
-static int acpi_device_suspend(struct device * dev, pm_message_t state)
-{
- struct acpi_device * acpi_dev = to_acpi_dev(dev);
-
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to suspend each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_suspend(acpi_dev, state);
- return 0;
-}
-
-
-
-static int root_resume(struct acpi_device * acpi_dev)
-{
- struct acpi_device * dev, * next;
- int result;
-
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.resume) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.resume(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
- }
- }
- spin_unlock(&acpi_device_lock);
- return 0;
-}
-
-
-static int acpi_device_resume(struct device * dev)
-{
- struct acpi_device * acpi_dev = to_acpi_dev(dev);
-
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to resume each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_resume(acpi_dev);
- return 0;
-}
-
-
-static struct bus_type acpi_bus_type = {
- .name = "acpi",
- .suspend = acpi_device_suspend,
- .resume = acpi_device_resume,
-};
-
-
-
static int __init acpi_scan_init(void)
{
int result;
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/13] ACPI: rename some functions
[not found] ` <1b3d821f47ae0d8393851c4ff82f6dd667868ead.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
We want the name 'to_acpi_device'.
And the current macro 'to_acpi_device' will be removed
after device model is setup.
So just simply rename them.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e0255cb..1f75ba6 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -49,13 +49,13 @@ static void setup_sys_fs_device_files(st
#define remove_sysfs_device_files(dev) \
setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
-#define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
+#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_device(kobj);
+ 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;
}
@@ -63,7 +63,7 @@ static ssize_t acpi_device_attr_store(st
struct attribute *attr, const char *buf,
size_t len)
{
- struct acpi_device *device = to_acpi_device(kobj);
+ 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;
}
@@ -82,7 +82,7 @@ static int namespace_uevent(struct kset
char **envp, int num_envp, char *buffer,
int buffer_size)
{
- struct acpi_device *dev = to_acpi_device(kobj);
+ struct acpi_device *dev = to_acpi_dev(kobj);
int i = 0;
int len = 0;
@@ -222,7 +222,7 @@ acpi_eject_store(struct acpi_device *dev
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
-static inline struct acpi_device * to_acpi_dev(struct device * dev)
+static inline struct acpi_device * to_acpi_device(struct device * dev)
{
return container_of(dev, struct acpi_device, dev);
}
@@ -251,7 +251,7 @@ static int root_suspend(struct acpi_devi
static int acpi_device_suspend(struct device * dev, pm_message_t state)
{
- struct acpi_device * acpi_dev = to_acpi_dev(dev);
+ struct acpi_device * acpi_dev = to_acpi_device(dev);
/*
* For now, we should only register 1 generic device -
@@ -288,7 +288,7 @@ static int root_resume(struct acpi_devic
static int acpi_device_resume(struct device * dev)
{
- struct acpi_device * acpi_dev = to_acpi_dev(dev);
+ struct acpi_device * acpi_dev = to_acpi_device(dev);
/*
* For now, we should only register 1 generic device -
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/13] ACPI: add device_driver and helper functions
[not found] ` <5b4e67afe03abecbba9eb45805f4e14214fc65a6.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Patrick Mochel, Zhang Rui, Len Brown
From: Patrick Mochel <mochel@linux.intel.com>
Add device_driver into acpi_driver for driver model.
Add helper functions 'to_acpi_device' and 'to_acpi_driver'
to get structure acpi_device/acpi_driver by device/device_driver.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 5 -----
include/acpi/acpi_bus.h | 3 +++
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1f75ba6..5b42948 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -222,11 +222,6 @@ acpi_eject_store(struct acpi_device *dev
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
-static inline struct acpi_device * to_acpi_device(struct device * dev)
-{
- return container_of(dev, struct acpi_device, dev);
-}
-
static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
{
struct acpi_device * dev, * next;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index f338e40..5282fe7 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -136,6 +136,7 @@ struct acpi_driver {
atomic_t references;
char *ids; /* Supported Hardware IDs */
struct acpi_device_ops ops;
+ struct device_driver drv;
};
/*
@@ -301,6 +302,8 @@ struct acpi_device {
};
#define acpi_driver_data(d) ((d)->driver_data)
+#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
+#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
/*
* Events
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/13] ACPI: add ACPI bus_type for driver model
[not found] ` <1a01fe8f75dc4b96707ebdac366121e772063b96.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Patrick Mochel, Li Shaohua, Zhang Rui, Len Brown
From: Patrick Mochel <mochel@linux.intel.com>
Add ACPI bus_type for Linux driver model.
1. .shutdown method is added into acpi_driver.ops
needed by bus_type operations.
2. remove useless parameter 'int state' in .resume method.
3. change parameter 'int state'
to 'pm_message_t state' in .suspend method.
Note: The new .uevent method mark ACPI drivers by PNPID instead of by name.
Udev script needs to look for "HWID=" or "COMPTID=" to load
ACPI drivers as a result.
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>
---
drivers/acpi/fan.c | 8 +-
drivers/acpi/scan.c | 158 +++++++++++++++++++++++++++--------------------
drivers/acpi/thermal.c | 4 +-
include/acpi/acpi_bus.h | 9 ++-
4 files changed, 103 insertions(+), 76 deletions(-)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 045c894..b249420 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
static int acpi_fan_add(struct acpi_device *device);
static int acpi_fan_remove(struct acpi_device *device, int type);
-static int acpi_fan_suspend(struct acpi_device *device, int state);
-static int acpi_fan_resume(struct acpi_device *device, int state);
+static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
+static int acpi_fan_resume(struct acpi_device *device);
static struct acpi_driver acpi_fan_driver = {
.name = ACPI_FAN_DRIVER_NAME,
@@ -238,7 +238,7 @@ static int acpi_fan_remove(struct acpi_d
return 0;
}
-static int acpi_fan_suspend(struct acpi_device *device, int state)
+static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
{
if (!device)
return -EINVAL;
@@ -248,7 +248,7 @@ static int acpi_fan_suspend(struct acpi_
return AE_OK;
}
-static int acpi_fan_resume(struct acpi_device *device, int state)
+static int acpi_fan_resume(struct acpi_device *device)
{
int result = 0;
int power_state = 0;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5b42948..4647462 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -222,100 +222,124 @@ acpi_eject_store(struct acpi_device *dev
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
-static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
+static int acpi_device_suspend(struct device *dev, pm_message_t state)
{
- struct acpi_device * dev, * next;
- int result;
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.suspend) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.suspend(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
- }
- }
- spin_unlock(&acpi_device_lock);
+ if (acpi_drv && acpi_drv->ops.suspend)
+ return acpi_drv->ops.suspend(acpi_dev, state);
return 0;
}
-static int acpi_device_suspend(struct device * dev, pm_message_t state)
+static int acpi_device_resume(struct device *dev)
{
- struct acpi_device * acpi_dev = to_acpi_device(dev);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to suspend each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_suspend(acpi_dev, state);
+ if (acpi_drv && acpi_drv->ops.resume)
+ return acpi_drv->ops.resume(acpi_dev);
return 0;
}
-static int root_resume(struct acpi_device * acpi_dev)
+static int acpi_bus_match(struct device *dev, struct device_driver *drv)
{
- struct acpi_device * dev, * next;
- int result;
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = to_acpi_driver(drv);
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.resume) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.resume(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
+ if (acpi_drv->ops.match)
+ return !acpi_drv->ops.match(acpi_dev, acpi_drv);
+ return !acpi_match_ids(acpi_dev, acpi_drv->ids);
+}
+
+static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ int i = 0, length = 0, ret = 0;
+
+ if (acpi_dev->flags.hardware_id)
+ ret = add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "HWID=%s", acpi_dev->pnp.hardware_id);
+ if (ret)
+ return -ENOMEM;
+ if (acpi_dev->flags.compatible_ids) {
+ int j;
+ struct acpi_compatible_id_list *cid_list;
+
+ cid_list = acpi_dev->pnp.cid_list;
+
+ for (j = 0; j < cid_list->count; j++) {
+ ret = add_uevent_var(envp, num_envp, &i, buffer,
+ buffer_size, &length, "COMPTID=%s",
+ cid_list->id[j].value);
+ if (ret)
+ return -ENOMEM;
}
}
- spin_unlock(&acpi_device_lock);
+
+ envp[i] = NULL;
return 0;
}
-static int acpi_device_resume(struct device * dev)
+static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
+static int acpi_start_single_object(struct acpi_device *);
+static int acpi_device_probe(struct device * dev)
{
- struct acpi_device * acpi_dev = to_acpi_device(dev);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
+ int ret;
+
+ ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
+ if (!ret) {
+ acpi_start_single_object(acpi_dev);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found driver [%s] for device [%s]\n",
+ acpi_drv->name, acpi_dev->pnp.bus_id));
+ get_device(dev);
+ }
+ return ret;
+}
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to resume each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_resume(acpi_dev);
+static int acpi_device_remove(struct device * dev)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
+
+ if (acpi_drv) {
+ if (acpi_drv->ops.stop)
+ acpi_drv->ops.stop(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ }
+ acpi_dev->driver = NULL;
+ acpi_driver_data(dev) = NULL;
+
+ put_device(dev);
return 0;
}
-/**
- * acpi_bus_match - match device IDs to driver's supported IDs
- * @device: the device that we are trying to match to a driver
- * @driver: driver whose device id table is being checked
- *
- * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
- * matches the specified driver's criteria.
- */
-static int
-acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
+static void acpi_device_shutdown(struct device *dev)
{
- if (driver && driver->ops.match)
- return driver->ops.match(device, driver);
- return acpi_match_ids(device, driver->ids);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
+
+ if (acpi_drv && acpi_drv->ops.shutdown)
+ acpi_drv->ops.shutdown(acpi_dev);
+
+ return ;
}
static struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
+ .shutdown = acpi_device_shutdown,
+ .match = acpi_bus_match,
+ .probe = acpi_device_probe,
+ .remove = acpi_device_remove,
+ .uevent = acpi_device_uevent,
};
static void acpi_device_register(struct acpi_device *device,
@@ -449,7 +473,7 @@ static void acpi_driver_attach(struct ac
continue;
spin_unlock(&acpi_device_lock);
- if (!acpi_bus_match(dev, drv)) {
+ if (!acpi_bus_match(&(dev->dev), &(drv->drv))) {
if (!acpi_bus_driver_init(dev, drv)) {
acpi_start_single_object(dev);
atomic_inc(&drv->references);
@@ -551,7 +575,7 @@ static int acpi_bus_find_driver(struct a
atomic_inc(&driver->references);
spin_unlock(&acpi_device_lock);
- if (!acpi_bus_match(device, driver)) {
+ if (!acpi_bus_match(&(device->dev), &(driver->drv))) {
result = acpi_bus_driver_init(device, driver);
if (!result)
goto Done;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5753d06..3650654 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone poll
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
-static int acpi_thermal_resume(struct acpi_device *device, int state);
+static int acpi_thermal_resume(struct acpi_device *device);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -1356,7 +1356,7 @@ static int acpi_thermal_remove(struct ac
return 0;
}
-static int acpi_thermal_resume(struct acpi_device *device, int state)
+static int acpi_thermal_resume(struct acpi_device *device)
{
struct acpi_thermal *tz = NULL;
int i;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 5282fe7..8fb7158 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -92,13 +92,14 @@ typedef int (*acpi_op_remove) (struct ac
typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
typedef int (*acpi_op_start) (struct acpi_device * device);
typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
-typedef int (*acpi_op_suspend) (struct acpi_device * device, int state);
-typedef int (*acpi_op_resume) (struct acpi_device * device, int state);
+typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state);
+typedef int (*acpi_op_resume) (struct acpi_device * device);
typedef int (*acpi_op_scan) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
typedef int (*acpi_op_match) (struct acpi_device * device,
struct acpi_driver * driver);
+typedef int (*acpi_op_shutdown) (struct acpi_device * device);
struct acpi_bus_ops {
u32 acpi_op_add:1;
@@ -112,7 +113,8 @@ struct acpi_bus_ops {
u32 acpi_op_bind:1;
u32 acpi_op_unbind:1;
u32 acpi_op_match:1;
- u32 reserved:21;
+ u32 acpi_op_shutdown:1;
+ u32 reserved:20;
};
struct acpi_device_ops {
@@ -127,6 +129,7 @@ struct acpi_device_ops {
acpi_op_bind bind;
acpi_op_unbind unbind;
acpi_op_match match;
+ acpi_op_shutdown shutdown;
};
struct acpi_driver {
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/13] ACPI: change registration interface to follow driver model
[not found] ` <eb3ec2290520985fd3a9392342ab586fba1e33c3.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Patrick Mochel, Li Shaohua, Zhang Rui, Len Brown
From: Patrick Mochel <mochel@linux.intel.com>
ACPI device/driver registration Interfaces are modified
to follow Linux driver model.
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>
---
drivers/acpi/scan.c | 175 ++++++++---------------------------------------
include/acpi/acpi_bus.h | 3 +-
2 files changed, 30 insertions(+), 148 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 4647462..b616e17 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -25,7 +25,7 @@ DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
-static void acpi_device_release(struct kobject *kobj)
+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);
@@ -75,7 +75,7 @@ static struct sysfs_ops acpi_device_sysf
static struct kobj_type ktype_acpi_ns = {
.sysfs_ops = &acpi_device_sysfs_ops,
- .release = acpi_device_release,
+ .release = acpi_device_release_legacy,
};
static int namespace_uevent(struct kset *kset, struct kobject *kobj,
@@ -222,6 +222,14 @@ acpi_eject_store(struct acpi_device *dev
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
+static void acpi_device_release(struct device *dev)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ kfree(acpi_dev->pnp.cid_list);
+ kfree(acpi_dev);
+}
+
static int acpi_device_suspend(struct device *dev, pm_message_t state)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -377,6 +385,14 @@ static void acpi_device_register(struct
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;
+ device_initialize(&device->dev);
+ sprintf(device->dev.bus_id, "%s", device->pnp.bus_id);
+ device->dev.release = &acpi_device_release;
+ device_add(&device->dev);
}
static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -395,20 +411,20 @@ static void acpi_device_unregister(struc
acpi_detach_data(device->handle, acpi_bus_data_handler);
remove_sysfs_device_files(device);
kobject_unregister(&device->kobj);
+
+ device_unregister(&device->dev);
}
/* --------------------------------------------------------------------------
Driver Management
-------------------------------------------------------------------------- */
-static LIST_HEAD(acpi_bus_drivers);
-
/**
* acpi_bus_driver_init - add a device to a driver
* @device: the device to add and initialize
* @driver: driver for the device
*
* Used to initialize a device via its device driver. Called whenever a
- * driver is bound to a device. Invokes the driver's add() and start() ops.
+ * driver is bound to a device. Invokes the driver's add() ops.
*/
static int
acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
@@ -459,57 +475,6 @@ static int acpi_start_single_object(stru
return result;
}
-static void acpi_driver_attach(struct acpi_driver *drv)
-{
- struct list_head *node, *next;
-
-
- spin_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, g_list);
-
- if (dev->driver || !dev->status.present)
- continue;
- spin_unlock(&acpi_device_lock);
-
- if (!acpi_bus_match(&(dev->dev), &(drv->drv))) {
- if (!acpi_bus_driver_init(dev, drv)) {
- acpi_start_single_object(dev);
- atomic_inc(&drv->references);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Found driver [%s] for device [%s]\n",
- drv->name, dev->pnp.bus_id));
- }
- }
- spin_lock(&acpi_device_lock);
- }
- spin_unlock(&acpi_device_lock);
-}
-
-static void acpi_driver_detach(struct acpi_driver *drv)
-{
- struct list_head *node, *next;
-
-
- spin_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, g_list);
-
- if (dev->driver == drv) {
- spin_unlock(&acpi_device_lock);
- if (drv->ops.remove)
- drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
- spin_lock(&acpi_device_lock);
- dev->driver = NULL;
- dev->driver_data = NULL;
- atomic_dec(&drv->references);
- }
- }
- spin_unlock(&acpi_device_lock);
-}
-
/**
* acpi_bus_register_driver - register a driver with the ACPI bus
* @driver: driver being registered
@@ -520,16 +485,16 @@ static void acpi_driver_detach(struct ac
*/
int acpi_bus_register_driver(struct acpi_driver *driver)
{
+ int ret;
if (acpi_disabled)
return -ENODEV;
+ driver->drv.name = driver->name;
+ driver->drv.bus = &acpi_bus_type;
+ driver->drv.owner = driver->owner;
- spin_lock(&acpi_device_lock);
- list_add_tail(&driver->node, &acpi_bus_drivers);
- spin_unlock(&acpi_device_lock);
- acpi_driver_attach(driver);
-
- return 0;
+ ret = driver_register(&driver->drv);
+ return ret;
}
EXPORT_SYMBOL(acpi_bus_register_driver);
@@ -543,52 +508,11 @@ EXPORT_SYMBOL(acpi_bus_register_driver);
*/
void acpi_bus_unregister_driver(struct acpi_driver *driver)
{
- acpi_driver_detach(driver);
-
- if (!atomic_read(&driver->references)) {
- spin_lock(&acpi_device_lock);
- list_del_init(&driver->node);
- spin_unlock(&acpi_device_lock);
- }
- return;
+ driver_unregister(&driver->drv);
}
EXPORT_SYMBOL(acpi_bus_unregister_driver);
-/**
- * acpi_bus_find_driver - check if there is a driver installed for the device
- * @device: device that we are trying to find a supporting driver for
- *
- * Parses the list of registered drivers looking for a driver applicable for
- * the specified device.
- */
-static int acpi_bus_find_driver(struct acpi_device *device)
-{
- int result = 0;
- struct list_head *node, *next;
-
-
- spin_lock(&acpi_device_lock);
- list_for_each_safe(node, next, &acpi_bus_drivers) {
- struct acpi_driver *driver =
- container_of(node, struct acpi_driver, node);
-
- atomic_inc(&driver->references);
- spin_unlock(&acpi_device_lock);
- if (!acpi_bus_match(&(device->dev), &(driver->drv))) {
- result = acpi_bus_driver_init(device, driver);
- if (!result)
- goto Done;
- }
- atomic_dec(&driver->references);
- spin_lock(&acpi_device_lock);
- }
- spin_unlock(&acpi_device_lock);
-
- Done:
- return result;
-}
-
/* --------------------------------------------------------------------------
Device Enumeration
-------------------------------------------------------------------------- */
@@ -1033,32 +957,10 @@ static void acpi_device_get_debug_info(s
static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
{
- int result = 0;
- struct acpi_driver *driver;
-
-
if (!dev)
return -EINVAL;
- driver = dev->driver;
-
- if ((driver) && (driver->ops.remove)) {
-
- if (driver->ops.stop) {
- result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
- if (result)
- return result;
- }
-
- result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
- if (result) {
- return result;
- }
-
- atomic_dec(&dev->driver->references);
- dev->driver = NULL;
- acpi_driver_data(dev) = NULL;
- }
+ device_release_driver(&dev->dev);
if (!rmdevice)
return 0;
@@ -1193,17 +1095,6 @@ acpi_add_single_object(struct acpi_devic
device->parent->ops.bind(device);
}
- /*
- * Locate & Attach Driver
- * ----------------------
- * If there's a hardware id (_HID) or compatible ids (_CID) we check
- * to see if there's a driver installed for this kind of device. Note
- * that drivers can install before or after a device is enumerated.
- *
- * TBD: Assumes LDM provides driver hot-plug capability.
- */
- acpi_bus_find_driver(device);
-
end:
if (!result)
*child = device;
@@ -1484,14 +1375,6 @@ static int __init acpi_scan_init(void)
if (result)
goto Done;
- acpi_root->dev.bus = &acpi_bus_type;
- snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
- result = device_register(&acpi_root->dev);
- if (result) {
- /* We don't want to quit even if we failed to add suspend/resume */
- printk(KERN_ERR PREFIX "Could not register device\n");
- }
-
/*
* Enumerate devices in the ACPI namespace.
*/
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 8fb7158..137fdee 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -133,13 +133,12 @@ struct acpi_device_ops {
};
struct acpi_driver {
- struct list_head node;
char name[80];
char class[80];
- atomic_t references;
char *ids; /* Supported Hardware IDs */
struct acpi_device_ops ops;
struct device_driver drv;
+ struct module *owner;
};
/*
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/13] ACPI: adjust init order
[not found] ` <b4ade865912166d7657e5f2a5af4c546c7fe2959.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Li Shaohua, Zhang Rui, Len Brown
From: Li Shaohua <shaohua.li@intel.com>
Adjust link order to add ACPI devices to global list before PCI devices.
In addition, acpi_bus type must be initialized before any driver loads.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bce7ca2..a749510 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -37,6 +37,7 @@ endif
obj-y += sleep/
obj-y += bus.o glue.o
+obj-y += scan.o motherboard.o
obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
@@ -56,7 +57,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
-obj-y += scan.o motherboard.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
obj-y += cm_sbs.o
obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 7/13] ACPI: convert to sysfs framework
[not found] ` <d190142cedf99bb444dfa27164686904773a7051.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Patrick Mochel, Li Shaohua, Zhang Rui, Len Brown
From: Patrick Mochel <mochel@linux.intel.com>
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>
---
drivers/acpi/bus.c | 2 +-
drivers/acpi/container.c | 6 +-
drivers/acpi/processor_core.c | 8 +-
drivers/acpi/scan.c | 187 +++++++++--------------------------------
include/acpi/acpi_bus.h | 1 -
5 files changed, 49 insertions(+), 155 deletions(-)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 279c4ba..da471f6 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -195,7 +195,7 @@ int acpi_bus_set_power(acpi_handle handl
if (!device->flags.power_manageable) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
- device->kobj.name));
+ device->dev.kobj.name));
return -ENODEV;
}
/*
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 871aa52..914f56a 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -168,7 +168,7 @@ static void container_notify_cb(acpi_han
if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle);
if (!result)
- kobject_uevent(&device->kobj,
+ kobject_uevent(&device->dev.kobj,
KOBJ_ONLINE);
else
printk("Failed to add container\n");
@@ -176,13 +176,13 @@ static void container_notify_cb(acpi_han
} else {
if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
}
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
if (!acpi_bus_get_device(handle, &device) && device) {
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
}
break;
default:
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 1908e0d..46e72c3 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -711,7 +711,7 @@ int acpi_processor_device_add(acpi_handl
return -ENODEV;
if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
- kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
+ kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
}
return 0;
}
@@ -749,13 +749,13 @@ acpi_processor_hotplug_notify(acpi_handl
}
if (pr->id >= 0 && (pr->id < NR_CPUS)) {
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
break;
}
result = acpi_processor_start(device);
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
- kobject_uevent(&device->kobj, KOBJ_ONLINE);
+ kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
} else {
printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
acpi_device_bid(device));
@@ -778,7 +778,7 @@ acpi_processor_hotplug_notify(acpi_handl
}
if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b616e17..97f6bbd 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_han
}
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 *dev
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 *dev
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
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
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(struc
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 */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 137fdee..d409d9a 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -299,7 +299,6 @@ struct acpi_device {
struct acpi_device_ops ops;
struct acpi_driver *driver;
void *driver_data;
- struct kobject kobj;
struct device dev;
};
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 8/13] ACPI: add acpi_bus_ops in acpi_device
[not found] ` <b23b4763ca902ef393e87c81177a0b6d6f8388ae.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Li Shaohua, Zhang Rui, Len Brown
From: Li Shaohua <shaohua.li@intel.com>
Add acpi_bus_ops in acpi_device to support acpi hot plug.
NOTE: Two methods .add and .start in acpi_driver.ops are
called separately to probe ACPI devices, while only
.probe method is called in driver model.
As executing .add and .start separately is critical
for ACPI device hot plug, we use acpi_bus_ops to
distinguish different code path.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 55 ++++++++++++++++++++++++-----------------------
include/acpi/acpi_bus.h | 1 +
2 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 97f6bbd..2a82645 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -212,7 +212,8 @@ static int acpi_device_probe(struct devi
ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
if (!ret) {
- acpi_start_single_object(acpi_dev);
+ if (acpi_dev->bus_ops.acpi_op_start)
+ acpi_start_single_object(acpi_dev);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found driver [%s] for device [%s]\n",
acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -305,7 +306,6 @@ static void acpi_device_unregister(struc
list_del(&device->g_list);
list_del(&device->wakeup_list);
-
spin_unlock(&acpi_device_lock);
acpi_detach_data(device->handle, acpi_bus_data_handler);
@@ -876,7 +876,8 @@ static int acpi_bus_remove(struct acpi_d
static int
acpi_add_single_object(struct acpi_device **child,
- struct acpi_device *parent, acpi_handle handle, int type)
+ struct acpi_device *parent, acpi_handle handle, int type,
+ struct acpi_bus_ops *ops)
{
int result = 0;
struct acpi_device *device = NULL;
@@ -894,6 +895,8 @@ acpi_add_single_object(struct acpi_devic
device->handle = handle;
device->parent = parent;
+ device->bus_ops = *ops; /* workround for not call .start */
+
acpi_device_get_busid(device, handle, type);
@@ -1079,14 +1082,14 @@ static int acpi_bus_scan(struct acpi_dev
if (ops->acpi_op_add)
status = acpi_add_single_object(&child, parent,
- chandle, type);
+ chandle, type, ops);
else
status = acpi_bus_get_device(chandle, &child);
if (ACPI_FAILURE(status))
continue;
- if (ops->acpi_op_start) {
+ if (ops->acpi_op_start && !(ops->acpi_op_add)) {
status = acpi_start_single_object(child);
if (ACPI_FAILURE(status))
continue;
@@ -1124,13 +1127,13 @@ acpi_bus_add(struct acpi_device **child,
int result;
struct acpi_bus_ops ops;
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_add = 1;
- result = acpi_add_single_object(child, parent, handle, type);
- if (!result) {
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
+ result = acpi_add_single_object(child, parent, handle, type, &ops);
+ if (!result)
result = acpi_bus_scan(*child, &ops);
- }
+
return result;
}
@@ -1216,28 +1219,30 @@ static int acpi_bus_scan_fixed(struct ac
{
int result = 0;
struct acpi_device *device = NULL;
-
+ struct acpi_bus_ops ops;
if (!root)
return -ENODEV;
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_add = 1;
+ ops.acpi_op_start = 1;
+
/*
* Enumerate all fixed-feature devices.
*/
if (acpi_fadt.pwr_button == 0) {
result = acpi_add_single_object(&device, acpi_root,
NULL,
- ACPI_BUS_TYPE_POWER_BUTTON);
- if (!result)
- result = acpi_start_single_object(device);
+ ACPI_BUS_TYPE_POWER_BUTTON,
+ &ops);
}
if (acpi_fadt.sleep_button == 0) {
result = acpi_add_single_object(&device, acpi_root,
NULL,
- ACPI_BUS_TYPE_SLEEP_BUTTON);
- if (!result)
- result = acpi_start_single_object(device);
+ ACPI_BUS_TYPE_SLEEP_BUTTON,
+ &ops);
}
return result;
@@ -1252,6 +1257,10 @@ static int __init acpi_scan_init(void)
if (acpi_disabled)
return 0;
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_add = 1;
+ ops.acpi_op_start = 1;
+
result = bus_register(&acpi_bus_type);
if (result) {
/* We don't want to quit even if we failed to add suspend/resume */
@@ -1262,11 +1271,7 @@ static int __init acpi_scan_init(void)
* Create the root device in the bus's device tree
*/
result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
- ACPI_BUS_TYPE_SYSTEM);
- if (result)
- goto Done;
-
- result = acpi_start_single_object(acpi_root);
+ ACPI_BUS_TYPE_SYSTEM, &ops);
if (result)
goto Done;
@@ -1274,12 +1279,8 @@ static int __init acpi_scan_init(void)
* Enumerate devices in the ACPI namespace.
*/
result = acpi_bus_scan_fixed(acpi_root);
- if (!result) {
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
- ops.acpi_op_start = 1;
+ if (!result)
result = acpi_bus_scan(acpi_root, &ops);
- }
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index d409d9a..b7baac7 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -300,6 +300,7 @@ struct acpi_device {
struct acpi_driver *driver;
void *driver_data;
struct device dev;
+ struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
};
#define acpi_driver_data(d) ((d)->driver_data)
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 9/13] ACPI: add acpi_bus_removal_type in acpi_device
[not found] ` <68d72528fc25d05d0f6fc17212ea5f695448bee2.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Li Shaohua, Zhang Rui, Len Brown
From: Li Shaohua <shaohua.li@intel.com>
Add removal_type in structure acpi_device for hot removal.
ACPI_BUS_REMOVAL_EJECT is used for ACPI device hot removal.
Only one parameter is allowed in .remove method due to driver model.
So removal_type is added to indicate different removal type.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 6 ++++--
include/acpi/acpi_bus.h | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2a82645..06b86fa 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -229,9 +229,9 @@ static int acpi_device_remove(struct dev
if (acpi_drv) {
if (acpi_drv->ops.stop)
- acpi_drv->ops.stop(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
if (acpi_drv->ops.remove)
- acpi_drv->ops.remove(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
}
acpi_dev->driver = NULL;
acpi_driver_data(dev) = NULL;
@@ -294,6 +294,7 @@ static void acpi_device_register(struct
device_add(&device->dev);
acpi_device_setup_files(device);
+ device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
}
static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -859,6 +860,7 @@ static int acpi_bus_remove(struct acpi_d
if (!dev)
return -EINVAL;
+ dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
device_release_driver(&dev->dev);
if (!rmdevice)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index b7baac7..168ef22 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -301,6 +301,7 @@ struct acpi_device {
void *driver_data;
struct device dev;
struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
+ enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
};
#define acpi_driver_data(d) ((d)->driver_data)
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/13] ACPI: consolidate two motherboard drivers into one
[not found] ` <46d1ee2fc5b8924aa5bb56c34f2205e6fc329b1b.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Li Shaohua, Zhang Rui, Len Brown
From: Li Shaohua <shaohua.li@intel.com>
Consolidate motherboard1 and motherboard2 drivers into one
so that driver core doesn't complain that two drivers have
the same name.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/motherboard.c | 19 ++++---------------
1 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index 2e17ec7..bedb511 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -33,8 +33,7 @@
ACPI_MODULE_NAME("acpi_motherboard")
/* Dell use PNP0C01 instead of PNP0C02 */
-#define ACPI_MB_HID1 "PNP0C01"
-#define ACPI_MB_HID2 "PNP0C02"
+#define ACPI_MB_HID "PNP0C01,PNP0C02"
/**
* Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
* Doesn't care about the failure of 'request_region', since other may reserve
@@ -110,19 +109,10 @@ static int acpi_motherboard_add(struct a
return 0;
}
-static struct acpi_driver acpi_motherboard_driver1 = {
+static struct acpi_driver acpi_motherboard_driver = {
.name = "motherboard",
.class = "",
- .ids = ACPI_MB_HID1,
- .ops = {
- .add = acpi_motherboard_add,
- },
-};
-
-static struct acpi_driver acpi_motherboard_driver2 = {
- .name = "motherboard",
- .class = "",
- .ids = ACPI_MB_HID2,
+ .ids = ACPI_MB_HID,
.ops = {
.add = acpi_motherboard_add,
},
@@ -173,8 +163,7 @@ static void __init acpi_reserve_resource
static int __init acpi_motherboard_init(void)
{
- acpi_bus_register_driver(&acpi_motherboard_driver1);
- acpi_bus_register_driver(&acpi_motherboard_driver2);
+ acpi_bus_register_driver(&acpi_motherboard_driver);
/*
* Guarantee motherboard IO reservation first
* This module must run after scan.c
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 11/13] ACPI: Convert ACPI PCI .bind/.unbind to use PCI bridge driver
[not found] ` <e3eb7f2f2601e00fd34cf1e0b1f0c7cd324e0b6b.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Li Shaohua, Zhang Rui, Len Brown
From: Li Shaohua <shaohua.li@intel.com>
acpi_device had a .bind/.unbind methods, but Linux driver model does not.
Cut ACPI PCI code over to use the Linux driver model methods.
Convert bind/unbind to use a new pci bridge driver.
The driver will add/remove _PRT, so we can eventually
remove .bind/.unbind methods.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/pci_bind.c | 56 +++++++++++++++++++++++++++++++++++++++++++---
drivers/acpi/pci_root.c | 5 ----
drivers/acpi/scan.c | 17 ++-----------
3 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 1e2ae6e..d833274 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -223,8 +223,6 @@ int acpi_pci_bind(struct acpi_device *de
data->id.segment, data->id.bus,
data->id.device, data->id.function));
data->bus = data->dev->subordinate;
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
}
/*
@@ -354,8 +352,6 @@ acpi_pci_bind_root(struct acpi_device *d
data->id = *id;
data->bus = bus;
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
@@ -378,3 +374,55 @@ acpi_pci_bind_root(struct acpi_device *d
return result;
}
+
+#define ACPI_PCI_BRIDGE_DRIVER_NAME "ACPI PCI Bridge Driver"
+
+static int acpi_pci_bridge_add(struct acpi_device *device);
+static int acpi_pci_bridge_remove(struct acpi_device *device, int type);
+static int acpi_pci_bridge_match(struct acpi_device *device,
+ struct acpi_driver *driver);
+static struct acpi_driver acpi_pci_bridge_driver = {
+ .name = ACPI_PCI_BRIDGE_DRIVER_NAME,
+ .ops = {
+ .add = acpi_pci_bridge_add,
+ .remove = acpi_pci_bridge_remove,
+ .match = acpi_pci_bridge_match,
+ },
+};
+
+static int acpi_pci_bridge_match(struct acpi_device *device,
+ struct acpi_driver *driver)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ /* pci bridge has _PRT but isn't PNP0A03 */
+ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+ if (!acpi_match_ids(device, "PNP0A03"))
+ return -ENODEV;
+ return 0;
+}
+
+static int acpi_pci_bridge_add(struct acpi_device *device)
+{
+ return acpi_pci_bind(device);
+}
+
+static int acpi_pci_bridge_remove(struct acpi_device *device, int type)
+{
+ return acpi_pci_unbind(device);
+}
+
+static int __init acpi_pci_bridge_init(void)
+{
+ if (acpi_pci_disabled)
+ return 0;
+ if (acpi_bus_register_driver(&acpi_pci_bridge_driver) < 0)
+ return -ENODEV;
+ return 0;
+}
+
+/* Should be called after ACPI pci root driver */
+subsys_initcall(acpi_pci_bridge_init);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0984a1e..9cfc741 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -175,11 +175,6 @@ static int acpi_pci_root_add(struct acpi
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
acpi_driver_data(device) = root;
- /*
- * TBD: Doesn't the bus driver automatically set this?
- */
- device->ops.bind = acpi_pci_bind;
-
/*
* Segment
* -------
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 06b86fa..b5fab54 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -865,12 +865,13 @@ static int acpi_bus_remove(struct acpi_d
if (!rmdevice)
return 0;
-
+ /* FIXME: device_release_driver will automically call unbind, is this ok */
+#if 0
if (dev->flags.bus_address) {
if ((dev->parent) && (dev->parent->ops.unbind))
dev->parent->ops.unbind(dev);
}
-
+#endif
acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
return 0;
@@ -987,18 +988,6 @@ acpi_add_single_object(struct acpi_devic
acpi_device_register(device, parent);
- /*
- * Bind _ADR-Based Devices
- * -----------------------
- * If there's a a bus address (_ADR) then we utilize the parent's
- * 'bind' function (if exists) to bind the ACPI- and natively-
- * enumerated device representations.
- */
- if (device->flags.bus_address) {
- if (device->parent && device->parent->ops.bind)
- device->parent->ops.bind(device);
- }
-
end:
if (!result)
*child = device;
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 12/13] ACPI: Set fake hid for non-PNPID ACPI devices.
[not found] ` <76e919d87de4de773fc728ecfb02f307b02c5f79.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
0 siblings, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
We do this mainly because:
1. hid is used to match ACPI devices and drivers.
.match method which is incompatible to driver model
can be deleted from acpi_driver.ops then.
2. As the .uevent method mark ACPI drivers by PNPID,
fake hid is set to non-PNPID devices so that udev script
can load the right ACPI driver by looking for
"HWID = " or "COMPTID = ".
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/pci_bind.c | 20 +-------------
drivers/acpi/scan.c | 59 +++++++++++++++++++++++++++++++++++++++++-
drivers/acpi/video.c | 37 +--------------------------
include/acpi/acpi_bus.h | 6 +---
include/acpi/acpi_drivers.h | 2 +
5 files changed, 63 insertions(+), 61 deletions(-)
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index d833274..aa05e92 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -379,32 +379,16 @@ acpi_pci_bind_root(struct acpi_device *d
static int acpi_pci_bridge_add(struct acpi_device *device);
static int acpi_pci_bridge_remove(struct acpi_device *device, int type);
-static int acpi_pci_bridge_match(struct acpi_device *device,
- struct acpi_driver *driver);
+
static struct acpi_driver acpi_pci_bridge_driver = {
.name = ACPI_PCI_BRIDGE_DRIVER_NAME,
+ .ids = ACPI_PCI_BRIDGE_HID,
.ops = {
.add = acpi_pci_bridge_add,
.remove = acpi_pci_bridge_remove,
- .match = acpi_pci_bridge_match,
},
};
-static int acpi_pci_bridge_match(struct acpi_device *device,
- struct acpi_driver *driver)
-{
- acpi_status status;
- acpi_handle handle;
-
- /* pci bridge has _PRT but isn't PNP0A03 */
- status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- if (!acpi_match_ids(device, "PNP0A03"))
- return -ENODEV;
- return 0;
-}
-
static int acpi_pci_bridge_add(struct acpi_device *device)
{
return acpi_pci_bind(device);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b5fab54..4a1484c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -166,8 +166,6 @@ static int acpi_bus_match(struct device
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = to_acpi_driver(drv);
- if (acpi_drv->ops.match)
- return !acpi_drv->ops.match(acpi_dev, acpi_drv);
return !acpi_match_ids(acpi_dev, acpi_drv->ids);
}
@@ -706,6 +704,53 @@ static void acpi_device_get_busid(struct
}
}
+static int
+acpi_video_bus_match(struct acpi_device *device)
+{
+ acpi_handle h_dummy1;
+ acpi_handle h_dummy2;
+ acpi_handle h_dummy3;
+
+
+ if (!device)
+ return -EINVAL;
+
+ /* Since there is no HID, CID for ACPI Video drivers, we have
+ * to check well known required nodes for each feature we support.
+ */
+
+ /* Does this device able to support video switching ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
+ return 0;
+
+ /* Does this device able to retrieve a video ROM ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
+ return 0;
+
+ /* Does this device able to configure which video head to be POSTed ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
+ return 0;
+
+ return -ENODEV;
+}
+
+static int acpi_pci_bridge_match(struct acpi_device *device)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ /* pci bridge has _PRT but isn't PNP0A03 */
+ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+ if (!acpi_match_ids(device, "PNP0A03"))
+ return -ENODEV;
+ return 0;
+}
+
static void acpi_device_set_id(struct acpi_device *device,
struct acpi_device *parent, acpi_handle handle,
int type)
@@ -736,6 +781,16 @@ static void acpi_device_set_id(struct ac
device->pnp.bus_address = info->address;
device->flags.bus_address = 1;
}
+
+ if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
+ status = acpi_video_bus_match(device);
+ if(ACPI_SUCCESS(status))
+ hid = ACPI_VIDEO_HID;
+
+ status = acpi_pci_bridge_match(device);
+ if(ACPI_SUCCESS(status))
+ hid = ACPI_PCI_BRIDGE_HID;
+ }
break;
case ACPI_BUS_TYPE_POWER:
hid = ACPI_POWER_HID;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 56666a9..6e99eea 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -65,16 +65,14 @@ MODULE_LICENSE("GPL");
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
-static int acpi_video_bus_match(struct acpi_device *device,
- struct acpi_driver *driver);
static struct acpi_driver acpi_video_bus = {
.name = ACPI_VIDEO_DRIVER_NAME,
.class = ACPI_VIDEO_CLASS,
+ .ids = ACPI_VIDEO_HID,
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
- .match = acpi_video_bus_match,
},
};
@@ -1774,39 +1772,6 @@ static int acpi_video_bus_remove(struct
return 0;
}
-static int
-acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
-{
- acpi_handle h_dummy1;
- acpi_handle h_dummy2;
- acpi_handle h_dummy3;
-
-
- if (!device || !driver)
- return -EINVAL;
-
- /* Since there is no HID, CID for ACPI Video drivers, we have
- * to check well known required nodes for each feature we support.
- */
-
- /* Does this device able to support video switching ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
- return 0;
-
- /* Does this device able to retrieve a video ROM ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
- return 0;
-
- /* Does this device able to configure which video head to be POSTed ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
- return 0;
-
- return -ENODEV;
-}
-
static int __init acpi_video_init(void)
{
int result = 0;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 168ef22..5aea83b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -97,8 +97,6 @@ typedef int (*acpi_op_resume) (struct ac
typedef int (*acpi_op_scan) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
-typedef int (*acpi_op_match) (struct acpi_device * device,
- struct acpi_driver * driver);
typedef int (*acpi_op_shutdown) (struct acpi_device * device);
struct acpi_bus_ops {
@@ -112,9 +110,8 @@ struct acpi_bus_ops {
u32 acpi_op_scan:1;
u32 acpi_op_bind:1;
u32 acpi_op_unbind:1;
- u32 acpi_op_match:1;
u32 acpi_op_shutdown:1;
- u32 reserved:20;
+ u32 reserved:21;
};
struct acpi_device_ops {
@@ -128,7 +125,6 @@ struct acpi_device_ops {
acpi_op_scan scan;
acpi_op_bind bind;
acpi_op_unbind unbind;
- acpi_op_match match;
acpi_op_shutdown shutdown;
};
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 6a5bdce..be67750 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -43,6 +43,8 @@
#define ACPI_BUTTON_HID_POWERF "ACPI_FPB"
#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB"
+#define ACPI_VIDEO_HID "ACPI_VID"
+#define ACPI_PCI_BRIDGE_HID "ACPI_PCI"
/* --------------------------------------------------------------------------
PCI
-------------------------------------------------------------------------- */
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
[not found] ` <d1f75c71119c62e4a399c5108250248213adfda6.1164343921.git.len.brown@intel.com>
@ 2006-11-24 5:17 ` Len Brown
2006-11-24 6:36 ` Len Brown
0 siblings, 1 reply; 21+ messages in thread
From: Len Brown @ 2006-11-24 5:17 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Li Shaohua, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
Previously we used the device name in the DSDT, but would
crash upon encountering a duplicate. Also, exposing
the DSDT device name to the user in a path isn't a
good idea, becauase it is arbitrary.
So just add two attributes for each device,
the full pathname in ACPI namespace and hardware_id.
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 70 +++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 4a1484c..5e8b8b0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -24,6 +24,8 @@ static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
+static unsigned int device_id = 0;
+
static int acpi_eject_operation(acpi_handle handle, int lockable)
{
struct acpi_object_list arg_list;
@@ -103,18 +105,55 @@ acpi_eject_store(struct device *d, struc
static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
-static void acpi_device_setup_files(struct acpi_device *dev)
+static ssize_t
+acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
+}
+static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
+
+static ssize_t
+acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+ int result;
+
+ result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
+ if(result)
+ goto end;
+
+ result = sprintf(buf, "%s\n", (char*)path.pointer);
+ kfree(path.pointer);
+ end:
+ return result;
+}
+static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
+
+static int acpi_device_setup_files(struct acpi_device *dev)
{
acpi_status status;
acpi_handle temp;
-
+ int result;
/*
* If device has _EJ0, 'eject' file is created that is used to trigger
* hot-removal function from userland.
*/
+ result = device_create_file(&dev->dev, &dev_attr_path);
+ if(result)
+ goto end;
+
+ if(dev->flags.hardware_id) {
+ result = device_create_file(&dev->dev, &dev_attr_hid);
+ if(result)
+ goto end;
+ }
+
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
- device_create_file(&dev->dev, &dev_attr_eject);
+ result = device_create_file(&dev->dev, &dev_attr_eject);
+ end:
+ return result;
}
static void acpi_device_remove_files(struct acpi_device *dev)
@@ -129,6 +168,11 @@ static void acpi_device_remove_files(str
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
device_remove_file(&dev->dev, &dev_attr_eject);
+
+ if(dev->flags.hardware_id)
+ device_remove_file(&dev->dev, &dev_attr_hid);
+
+ device_remove_file(&dev->dev, &dev_attr_path);
}
/* --------------------------------------------------------------------------
ACPI Bus operations
@@ -260,9 +304,10 @@ static struct bus_type acpi_bus_type = {
.uevent = acpi_device_uevent,
};
-static void acpi_device_register(struct acpi_device *device,
+static int acpi_device_register(struct acpi_device *device,
struct acpi_device *parent)
{
+ int result;
/*
* Linkage
* -------
@@ -287,12 +332,21 @@ static void acpi_device_register(struct
device->dev.parent = &parent->dev;
device->dev.bus = &acpi_bus_type;
device_initialize(&device->dev);
- sprintf(device->dev.bus_id, "%s", device->pnp.bus_id);
+ sprintf(device->dev.bus_id, "%d", device_id);
device->dev.release = &acpi_device_release;
- device_add(&device->dev);
+ result = device_add(&device->dev);
+ if(result) {
+ printk("Error adding device %s", device->pnp.bus_id);
+ return result;
+ }
+
+ result = acpi_device_setup_files(device);
+ if(result)
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->pnp.bus_id));
- acpi_device_setup_files(device);
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
+ device_id++;
+ return 0;
}
static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -1041,7 +1095,7 @@ acpi_add_single_object(struct acpi_devic
acpi_device_get_debug_info(device, handle, type);
- acpi_device_register(device, parent);
+ result = acpi_device_register(device, parent);
end:
if (!result)
--
1.4.4.g59427
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-24 5:17 ` [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs Len Brown
@ 2006-11-24 6:36 ` Len Brown
2006-11-24 9:40 ` Zhang Rui
0 siblings, 1 reply; 21+ messages in thread
From: Len Brown @ 2006-11-24 6:36 UTC (permalink / raw)
To: Zhang Rui; +Cc: linux-acpi, Li Shaohua
On Friday 24 November 2006 00:17, Len Brown wrote:
> From: Zhang Rui <rui.zhang@intel.com>
>
> Previously we used the device name in the DSDT, but would
> crash upon encountering a duplicate. Also, exposing
> the DSDT device name to the user in a path isn't a
> good idea, becauase it is arbitrary.
> So just add two attributes for each device,
> the full pathname in ACPI namespace and hardware_id.
While this addresses the potential name conflict of the previous version,
I think this needs some work.
$ ls /sys/devices/0
1 10 2 3 4 5 57 6 7 8 9 bus hid path power subsystem uevent
Assigning the unique numbers in a depth-first search
leaves irritating gaps -- (see 10 and 57 above).
Instance numbers need to be per-directory.
Also, IMHO, the numbers by themselves look a little strange,
maybe dev0, dev1, dev%d etc. wouldn't look so strange?
Also, the ACPI spec has some pre-defined root name-spaces, and I think
it makes sense to look up the device name against a small table of
those reserved names and print something more interesting than
a number.
eg.
_SB system_bus
_PR processors
_TZ thermal_zones
_SI system_indicators
_GPE events
thanks,
-Len
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-24 6:36 ` Len Brown
@ 2006-11-24 9:40 ` Zhang Rui
2006-11-26 5:10 ` Zhang Rui
2006-11-27 6:06 ` Len Brown
0 siblings, 2 replies; 21+ messages in thread
From: Zhang Rui @ 2006-11-24 9:40 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi@vger, Li Shaohua
On Fri, 2006-11-24 at 01:36 -0500, Len Brown wrote:
> On Friday 24 November 2006 00:17, Len Brown wrote:
> > From: Zhang Rui <rui.zhang@intel.com>
> >
> > Previously we used the device name in the DSDT, but would
> > crash upon encountering a duplicate. Also, exposing
> > the DSDT device name to the user in a path isn't a
> > good idea, becauase it is arbitrary.
> > So just add two attributes for each device,
> > the full pathname in ACPI namespace and hardware_id.
>
> While this addresses the potential name conflict of the previous version,
> I think this needs some work.
>
> $ ls /sys/devices/0
> 1 10 2 3 4 5 57 6 7 8 9 bus hid path power subsystem uevent
>
> Assigning the unique numbers in a depth-first search
> leaves irritating gaps -- (see 10 and 57 above).
That's true.
But you know, ACPI namespace is a tree in nature. Depth-first is the
fastest way to traverse the ACPI namespace.
> Instance numbers need to be per-directory.
>
instance numbers should be unique in the whole ACPI bus, as all of them
are linked to /sys/bus/acpi/devices/.
> Also, IMHO, the numbers by themselves look a little strange,
> maybe dev0, dev1, dev%d etc. wouldn't look so strange?
>
Yes, I can do that. :)
> Also, the ACPI spec has some pre-defined root name-spaces, and I think
> it makes sense to look up the device name against a small table of
> those reserved names and print something more interesting than
> a number.
>
> eg.
> _SB system_bus
> _PR processors
> _TZ thermal_zones
> _SI system_indicators
> _GPE events
>
Yeah. I can do that. But few devices can benefit from this. :(.
BTW: Maybe I can generate a patch to get the following result:
Five devices with the fixed name shown above if they are declared in the
BIOS
And add a prefix for every devices, the prefix is one of fixed names,
_SB _PR _TZ _SI _GPE. So devices are shown like _SB:dev001, _TZ:dev001,
_PR:dev033 etc.
But does this make sense? :(
The best way is to define a unique and meaning rule to name all the ACPI
devices. Unfortunately we haven't reached an agreement until now, but I
think we can leave this for further discussion.
> thanks,
> -Len
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-24 9:40 ` Zhang Rui
@ 2006-11-26 5:10 ` Zhang Rui
2006-11-27 6:10 ` Len Brown
2006-11-27 6:06 ` Len Brown
1 sibling, 1 reply; 21+ messages in thread
From: Zhang Rui @ 2006-11-26 5:10 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi@vger, Li Shaohua
> > Also, the ACPI spec has some pre-defined root name-spaces, and I think
> > it makes sense to look up the device name against a small table of
> > those reserved names and print something more interesting than
> > a number.
> >
> > eg.
> > _SB system_bus
> > _PR processors
> > _TZ thermal_zones
> > _SI system_indicators
> > _GPE events
> >
> Yeah. I can do that. But few devices can benefit from this. :(.
>
>
> BTW: Maybe I can generate a patch to get the following result:
> Five devices with the fixed name shown above if they are declared in the
> BIOS
> And add a prefix for every devices, the prefix is one of fixed names,
> _SB _PR _TZ _SI _GPE. So devices are shown like _SB:dev001, _TZ:dev001,
> _PR:dev033 etc.
> But does this make sense? :(
>
> The best way is to define a unique and meaning rule to name all the ACPI
> devices. Unfortunately we haven't reached an agreement until now, but I
> think we can leave this for further discussion.
Another way to fix this naming problem.
Many devices in ACPI namespace is meaningless. Only the devices with a
PNPID are physical devices and should be exported to userspace.
So we can only register these devices and use "PNPID:instance no" as its
name.
Add instance_no in struct acpi_device. Every time we fail to register an
ACPI device and get an error of "-EEXIST", loop acpi_device_list to get
the right instance_no and register again.
Thanks,
Ray
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-24 9:40 ` Zhang Rui
2006-11-26 5:10 ` Zhang Rui
@ 2006-11-27 6:06 ` Len Brown
1 sibling, 0 replies; 21+ messages in thread
From: Len Brown @ 2006-11-27 6:06 UTC (permalink / raw)
To: Zhang Rui; +Cc: Len Brown, linux-acpi@vger, Li Shaohua
> > While this addresses the potential name conflict of the previous version,
> > I think this needs some work.
> >
> > $ ls /sys/devices/0
> > 1 10 2 3 4 5 57 6 7 8 9 bus hid path power subsystem uevent
> >
> > Assigning the unique numbers in a depth-first search
> > leaves irritating gaps -- (see 10 and 57 above).
> That's true.
> But you know, ACPI namespace is a tree in nature. Depth-first is the
> fastest way to traverse the ACPI namespace.
> > Instance numbers need to be per-directory.
> >
> instance numbers should be unique in the whole ACPI bus, as all of them
> are linked to /sys/bus/acpi/devices/.
In sysfs, a directory is a kernel/user API.
A user-program will want to open directory entries by name,
and the names should make some sense.
The names in /sys/bus/acpi/devices/ and the names in /sys/devices
do not have to be the same.
> > Also, IMHO, the numbers by themselves look a little strange,
> > maybe dev0, dev1, dev%d etc. wouldn't look so strange?
> >
> Yes, I can do that. :)
> > Also, the ACPI spec has some pre-defined root name-spaces, and I think
> > it makes sense to look up the device name against a small table of
> > those reserved names and print something more interesting than
> > a number.
> >
> > eg.
> > _SB system_bus
> > _PR processors
> > _TZ thermal_zones
> > _SI system_indicators
> > _GPE events
> >
> Yeah. I can do that. But few devices can benefit from this. :(.
>
>
> BTW: Maybe I can generate a patch to get the following result:
> Five devices with the fixed name shown above if they are declared in the
> BIOS
> And add a prefix for every devices, the prefix is one of fixed names,
> _SB _PR _TZ _SI _GPE. So devices are shown like _SB:dev001, _TZ:dev001,
> _PR:dev033 etc.
> But does this make sense? :(
No. My point is that if it a _TZ then we know that it is a "thermal_zone"
an we can just print "thermal_zone". There is no reason to make
this cryptic by using the ACPI device names -- they have fixed definitions
and in these few cases we can take advantage of that.
> The best way is to define a unique and meaning rule to name all the ACPI
> devices. Unfortunately we haven't reached an agreement until now, but I
> think we can leave this for further discussion.
see next message.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-26 5:10 ` Zhang Rui
@ 2006-11-27 6:10 ` Len Brown
2006-11-27 6:35 ` Zhang Rui
0 siblings, 1 reply; 21+ messages in thread
From: Len Brown @ 2006-11-27 6:10 UTC (permalink / raw)
To: Zhang Rui; +Cc: Len Brown, linux-acpi@vger, Li Shaohua
> Another way to fix this naming problem.
> Many devices in ACPI namespace is meaningless. Only the devices with a
> PNPID are physical devices and should be exported to userspace.
> So we can only register these devices and use "PNPID:instance no" as its
> name.
> Add instance_no in struct acpi_device. Every time we fail to register an
> ACPI device and get an error of "-EEXIST", loop acpi_device_list to get
> the right instance_no and register again.
Yes, PNP-id's have definitions, and when we have the luxury of having
devices with PNP-id's, we should use those, along with an instance number
to handle the case of multiple devices of the PNPid.
Indeed, the question is if we should go so far as to translate the PNPid
into English, or simply use the PNPid string.
eg "PNP0C0C" vs "button".
I vote for the PNPid, since it requires less maintenance:-)
thanks,
-Len
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs
2006-11-27 6:10 ` Len Brown
@ 2006-11-27 6:35 ` Zhang Rui
0 siblings, 0 replies; 21+ messages in thread
From: Zhang Rui @ 2006-11-27 6:35 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi@vger, Li Shaohua
On Mon, 2006-11-27 at 01:10 -0500, Len Brown wrote:
> > Another way to fix this naming problem.
> > Many devices in ACPI namespace is meaningless. Only the devices with a
> > PNPID are physical devices and should be exported to userspace.
> > So we can only register these devices and use "PNPID:instance no" as its
> > name.
> > Add instance_no in struct acpi_device. Every time we fail to register an
> > ACPI device and get an error of "-EEXIST", loop acpi_device_list to get
> > the right instance_no and register again.
>
> Yes, PNP-id's have definitions, and when we have the luxury of having
> devices with PNP-id's, we should use those, along with an instance number
> to handle the case of multiple devices of the PNPid.
>
> Indeed, the question is if we should go so far as to translate the PNPid
> into English, or simply use the PNPid string.
>
> eg "PNP0C0C" vs "button".
>
> I vote for the PNPid, since it requires less maintenance:-)
>
Yes.
For now, we can use "pnpid:instance_no" for devices with pnpid. For
devices without PNPid, we recognise them as "NO_PNPID:instance_no". Is
this OK?
> thanks,
> -Len
^ permalink raw reply [flat|nested] 21+ messages in thread
* updated patches of sysfs branch
2006-11-24 5:17 contents of sysfs branch Len Brown
[not found] ` <bd119392c453771fdb994728a2568c2e3f17705d.1164343921.git.len.brown@intel.com>
@ 2006-12-01 8:55 ` Zhang Rui
1 sibling, 0 replies; 21+ messages in thread
From: Zhang Rui @ 2006-12-01 8:55 UTC (permalink / raw)
To: lenb; +Cc: linux-acpi@vger, len.brown, shaohua.li
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
> The following patches are on the "sysfs" branch of the ACPI git tree.
>
> To test, apply this e-mail series, or git pull from here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git sysfs
>
> I am hopeful that this series will settle down and make the test branch
> shortly, and thus make its way into an upcoming -mm release, and then upstream.
>
These are updated patches against 2.6.19. Len, could you update them in
sysfs branch please?
Four patches are refreshed in all.
[PATCH 4]: ACPI: add ACPI bus_type for driver model
remove parameter "int state" of battery driver .resume method, which is
added recently.
[PATCH 11]: ACPI: Convert ACPI PCI .bind/.unbind to use PCI bridge
driver
remove useless codes and comments which is shown in last patch.
[PATCH 13]: ACPI: use unique number as bus_id of ACPI devices in sysfs
use "PNPID:instance_no" as bus_id of ACPI devices in sysfs instead of
unique numbers.
[PATCH 14]: ACPI: ibm_acpi: don't use '/' in driver names
We add a new patch in this patch series.
ibm_acpi uses '/' in driver names, and this causes a failure when register an ibm_acpi driver.
This patch replace '/' with '_' in driver names.
Thank Henrique de Moraes Holschuh for generating this patch.
Thanks,
Ray
[-- Attachment #2: 04-add-ACPI-bus_type-for-driver-model.patch --]
[-- Type: message/rfc822, Size: 12960 bytes --]
From: Patrick Mochel <mochel@linux.intel.com>
Subject: No Subject
Date: Fri, 01 Dec 2006 16:52:46 +0800
Message-ID: <1164963166.6324.1.camel@localhost.localdomain>
Add ACPI bus_type for Linux driver model.
1. .shutdown method is added into acpi_driver.ops
needed by bus_type operations.
2. remove useless parameter 'int state' in .resume method.
3. change parameter 'int state'
to 'pm_message_t state' in .suspend method.
Note: The new .uevent method mark ACPI drivers by PNPID instead of by name.
Udev script needs to look for "HWID=" or "COMPTID=" to load
ACPI drivers as a result.
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>
---
drivers/acpi/battery.c | 4 -
drivers/acpi/fan.c | 8 +-
drivers/acpi/scan.c | 158 +++++++++++++++++++++++++++---------------------
drivers/acpi/thermal.c | 4 -
include/acpi/acpi_bus.h | 9 +-
5 files changed, 105 insertions(+), 78 deletions(-)
Index: linux-2.6.19/drivers/acpi/fan.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/fan.c 2006-12-01 15:18:30.000000000 +0800
+++ linux-2.6.19/drivers/acpi/fan.c 2006-12-01 15:18:34.000000000 +0800
@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
static int acpi_fan_add(struct acpi_device *device);
static int acpi_fan_remove(struct acpi_device *device, int type);
-static int acpi_fan_suspend(struct acpi_device *device, int state);
-static int acpi_fan_resume(struct acpi_device *device, int state);
+static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
+static int acpi_fan_resume(struct acpi_device *device);
static struct acpi_driver acpi_fan_driver = {
.name = ACPI_FAN_DRIVER_NAME,
@@ -238,7 +238,7 @@ static int acpi_fan_remove(struct acpi_d
return 0;
}
-static int acpi_fan_suspend(struct acpi_device *device, int state)
+static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
{
if (!device)
return -EINVAL;
@@ -248,7 +248,7 @@ static int acpi_fan_suspend(struct acpi_
return AE_OK;
}
-static int acpi_fan_resume(struct acpi_device *device, int state)
+static int acpi_fan_resume(struct acpi_device *device)
{
int result = 0;
int power_state = 0;
Index: linux-2.6.19/drivers/acpi/scan.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/scan.c 2006-12-01 15:18:30.000000000 +0800
+++ linux-2.6.19/drivers/acpi/scan.c 2006-12-01 15:18:34.000000000 +0800
@@ -222,100 +222,124 @@ acpi_eject_store(struct acpi_device *dev
/* --------------------------------------------------------------------------
ACPI Bus operations
-------------------------------------------------------------------------- */
-static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
+static int acpi_device_suspend(struct device *dev, pm_message_t state)
{
- struct acpi_device * dev, * next;
- int result;
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.suspend) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.suspend(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
- }
- }
- spin_unlock(&acpi_device_lock);
+ if (acpi_drv && acpi_drv->ops.suspend)
+ return acpi_drv->ops.suspend(acpi_dev, state);
return 0;
}
-static int acpi_device_suspend(struct device * dev, pm_message_t state)
+static int acpi_device_resume(struct device *dev)
{
- struct acpi_device * acpi_dev = to_acpi_device(dev);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to suspend each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_suspend(acpi_dev, state);
+ if (acpi_drv && acpi_drv->ops.resume)
+ return acpi_drv->ops.resume(acpi_dev);
return 0;
}
-static int root_resume(struct acpi_device * acpi_dev)
+static int acpi_bus_match(struct device *dev, struct device_driver *drv)
{
- struct acpi_device * dev, * next;
- int result;
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = to_acpi_driver(drv);
- spin_lock(&acpi_device_lock);
- list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
- if (dev->driver && dev->driver->ops.resume) {
- spin_unlock(&acpi_device_lock);
- result = dev->driver->ops.resume(dev, 0);
- if (result) {
- printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
- acpi_device_name(dev),
- acpi_device_bid(dev), result);
- }
- spin_lock(&acpi_device_lock);
+ if (acpi_drv->ops.match)
+ return !acpi_drv->ops.match(acpi_dev, acpi_drv);
+ return !acpi_match_ids(acpi_dev, acpi_drv->ids);
+}
+
+static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ int i = 0, length = 0, ret = 0;
+
+ if (acpi_dev->flags.hardware_id)
+ ret = add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "HWID=%s", acpi_dev->pnp.hardware_id);
+ if (ret)
+ return -ENOMEM;
+ if (acpi_dev->flags.compatible_ids) {
+ int j;
+ struct acpi_compatible_id_list *cid_list;
+
+ cid_list = acpi_dev->pnp.cid_list;
+
+ for (j = 0; j < cid_list->count; j++) {
+ ret = add_uevent_var(envp, num_envp, &i, buffer,
+ buffer_size, &length, "COMPTID=%s",
+ cid_list->id[j].value);
+ if (ret)
+ return -ENOMEM;
}
}
- spin_unlock(&acpi_device_lock);
+
+ envp[i] = NULL;
return 0;
}
-static int acpi_device_resume(struct device * dev)
+static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
+static int acpi_start_single_object(struct acpi_device *);
+static int acpi_device_probe(struct device * dev)
{
- struct acpi_device * acpi_dev = to_acpi_device(dev);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
+ int ret;
- /*
- * For now, we should only register 1 generic device -
- * the ACPI root device - and from there, we walk the
- * tree of ACPI devices to resume each one using the
- * ACPI driver methods.
- */
- if (acpi_dev->handle == ACPI_ROOT_OBJECT)
- root_resume(acpi_dev);
+ ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
+ if (!ret) {
+ acpi_start_single_object(acpi_dev);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Found driver [%s] for device [%s]\n",
+ acpi_drv->name, acpi_dev->pnp.bus_id));
+ get_device(dev);
+ }
+ return ret;
+}
+
+static int acpi_device_remove(struct device * dev)
+{
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
+
+ if (acpi_drv) {
+ if (acpi_drv->ops.stop)
+ acpi_drv->ops.stop(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
+ }
+ acpi_dev->driver = NULL;
+ acpi_driver_data(dev) = NULL;
+
+ put_device(dev);
return 0;
}
-/**
- * acpi_bus_match - match device IDs to driver's supported IDs
- * @device: the device that we are trying to match to a driver
- * @driver: driver whose device id table is being checked
- *
- * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
- * matches the specified driver's criteria.
- */
-static int
-acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
+static void acpi_device_shutdown(struct device *dev)
{
- if (driver && driver->ops.match)
- return driver->ops.match(device, driver);
- return acpi_match_ids(device, driver->ids);
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_driver *acpi_drv = acpi_dev->driver;
+
+ if (acpi_drv && acpi_drv->ops.shutdown)
+ acpi_drv->ops.shutdown(acpi_dev);
+
+ return ;
}
static struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
+ .shutdown = acpi_device_shutdown,
+ .match = acpi_bus_match,
+ .probe = acpi_device_probe,
+ .remove = acpi_device_remove,
+ .uevent = acpi_device_uevent,
};
static void acpi_device_register(struct acpi_device *device,
@@ -449,7 +473,7 @@ static void acpi_driver_attach(struct ac
continue;
spin_unlock(&acpi_device_lock);
- if (!acpi_bus_match(dev, drv)) {
+ if (!acpi_bus_match(&(dev->dev), &(drv->drv))) {
if (!acpi_bus_driver_init(dev, drv)) {
acpi_start_single_object(dev);
atomic_inc(&drv->references);
@@ -551,7 +575,7 @@ static int acpi_bus_find_driver(struct a
atomic_inc(&driver->references);
spin_unlock(&acpi_device_lock);
- if (!acpi_bus_match(device, driver)) {
+ if (!acpi_bus_match(&(device->dev), &(driver->drv))) {
result = acpi_bus_driver_init(device, driver);
if (!result)
goto Done;
Index: linux-2.6.19/drivers/acpi/thermal.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/thermal.c 2006-12-01 15:18:30.000000000 +0800
+++ linux-2.6.19/drivers/acpi/thermal.c 2006-12-01 15:18:34.000000000 +0800
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone poll
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
-static int acpi_thermal_resume(struct acpi_device *device, int state);
+static int acpi_thermal_resume(struct acpi_device *device);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -1356,7 +1356,7 @@ static int acpi_thermal_remove(struct ac
return 0;
}
-static int acpi_thermal_resume(struct acpi_device *device, int state)
+static int acpi_thermal_resume(struct acpi_device *device)
{
struct acpi_thermal *tz = NULL;
int i;
Index: linux-2.6.19/include/acpi/acpi_bus.h
===================================================================
--- linux-2.6.19.orig/include/acpi/acpi_bus.h 2006-12-01 15:18:30.000000000 +0800
+++ linux-2.6.19/include/acpi/acpi_bus.h 2006-12-01 15:18:34.000000000 +0800
@@ -92,13 +92,14 @@ typedef int (*acpi_op_remove) (struct ac
typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
typedef int (*acpi_op_start) (struct acpi_device * device);
typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
-typedef int (*acpi_op_suspend) (struct acpi_device * device, int state);
-typedef int (*acpi_op_resume) (struct acpi_device * device, int state);
+typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state);
+typedef int (*acpi_op_resume) (struct acpi_device * device);
typedef int (*acpi_op_scan) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
typedef int (*acpi_op_match) (struct acpi_device * device,
struct acpi_driver * driver);
+typedef int (*acpi_op_shutdown) (struct acpi_device * device);
struct acpi_bus_ops {
u32 acpi_op_add:1;
@@ -112,7 +113,8 @@ struct acpi_bus_ops {
u32 acpi_op_bind:1;
u32 acpi_op_unbind:1;
u32 acpi_op_match:1;
- u32 reserved:21;
+ u32 acpi_op_shutdown:1;
+ u32 reserved:20;
};
struct acpi_device_ops {
@@ -127,6 +129,7 @@ struct acpi_device_ops {
acpi_op_bind bind;
acpi_op_unbind unbind;
acpi_op_match match;
+ acpi_op_shutdown shutdown;
};
struct acpi_driver {
Index: linux-2.6.19/drivers/acpi/battery.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/battery.c 2006-12-01 15:03:38.000000000 +0800
+++ linux-2.6.19/drivers/acpi/battery.c 2006-12-01 15:19:23.000000000 +0800
@@ -64,7 +64,7 @@ extern void *acpi_unlock_battery_dir(str
static int acpi_battery_add(struct acpi_device *device);
static int acpi_battery_remove(struct acpi_device *device, int type);
-static int acpi_battery_resume(struct acpi_device *device, int status);
+static int acpi_battery_resume(struct acpi_device *device);
static struct acpi_driver acpi_battery_driver = {
.name = ACPI_BATTERY_DRIVER_NAME,
@@ -756,7 +756,7 @@ static int acpi_battery_remove(struct ac
}
/* this is needed to learn about changes made in suspended state */
-static int acpi_battery_resume(struct acpi_device *device, int state)
+static int acpi_battery_resume(struct acpi_device *device)
{
struct acpi_battery *battery;
[-- Attachment #3: 11-convert-ACPI-PCI-bind-unbind-to-use-PCI-bridge-driver.patch --]
[-- Type: message/rfc822, Size: 4884 bytes --]
From: Li Shaohua <shaohua.li@intel.com>
Subject: No Subject
Date: Fri, 01 Dec 2006 16:52:46 +0800
Message-ID: <1164963166.6324.2.camel@localhost.localdomain>
acpi_device had a .bind/.unbind methods, but Linux driver model does not.
Cut ACPI PCI code over to use the Linux driver model methods.
Convert bind/unbind to use a new pci bridge driver.
The driver will add/remove _PRT, so we can eventually
remove .bind/.unbind methods.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/pci_bind.c | 56 ++++++++++++++++++++++++++++++++++++++++++++----
drivers/acpi/pci_root.c | 5 ----
drivers/acpi/scan.c | 17 --------------
3 files changed, 52 insertions(+), 26 deletions(-)
Index: linux-2.6.19/drivers/acpi/pci_bind.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/pci_bind.c 2006-12-01 15:20:34.000000000 +0800
+++ linux-2.6.19/drivers/acpi/pci_bind.c 2006-12-01 15:21:30.000000000 +0800
@@ -223,8 +223,6 @@ int acpi_pci_bind(struct acpi_device *de
data->id.segment, data->id.bus,
data->id.device, data->id.function));
data->bus = data->dev->subordinate;
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
}
/*
@@ -354,8 +352,6 @@ acpi_pci_bind_root(struct acpi_device *d
data->id = *id;
data->bus = bus;
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
@@ -378,3 +374,55 @@ acpi_pci_bind_root(struct acpi_device *d
return result;
}
+
+#define ACPI_PCI_BRIDGE_DRIVER_NAME "ACPI PCI Bridge Driver"
+
+static int acpi_pci_bridge_add(struct acpi_device *device);
+static int acpi_pci_bridge_remove(struct acpi_device *device, int type);
+static int acpi_pci_bridge_match(struct acpi_device *device,
+ struct acpi_driver *driver);
+static struct acpi_driver acpi_pci_bridge_driver = {
+ .name = ACPI_PCI_BRIDGE_DRIVER_NAME,
+ .ops = {
+ .add = acpi_pci_bridge_add,
+ .remove = acpi_pci_bridge_remove,
+ .match = acpi_pci_bridge_match,
+ },
+};
+
+static int acpi_pci_bridge_match(struct acpi_device *device,
+ struct acpi_driver *driver)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ /* pci bridge has _PRT but isn't PNP0A03 */
+ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+ if (!acpi_match_ids(device, "PNP0A03"))
+ return -ENODEV;
+ return 0;
+}
+
+static int acpi_pci_bridge_add(struct acpi_device *device)
+{
+ return acpi_pci_bind(device);
+}
+
+static int acpi_pci_bridge_remove(struct acpi_device *device, int type)
+{
+ return acpi_pci_unbind(device);
+}
+
+static int __init acpi_pci_bridge_init(void)
+{
+ if (acpi_pci_disabled)
+ return 0;
+ if (acpi_bus_register_driver(&acpi_pci_bridge_driver) < 0)
+ return -ENODEV;
+ return 0;
+}
+
+/* Should be called after ACPI pci root driver */
+subsys_initcall(acpi_pci_bridge_init);
Index: linux-2.6.19/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/pci_root.c 2006-12-01 15:20:34.000000000 +0800
+++ linux-2.6.19/drivers/acpi/pci_root.c 2006-12-01 15:21:30.000000000 +0800
@@ -175,11 +175,6 @@ static int acpi_pci_root_add(struct acpi
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
acpi_driver_data(device) = root;
- /*
- * TBD: Doesn't the bus driver automatically set this?
- */
- device->ops.bind = acpi_pci_bind;
-
/*
* Segment
* -------
Index: linux-2.6.19/drivers/acpi/scan.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/scan.c 2006-12-01 15:20:34.000000000 +0800
+++ linux-2.6.19/drivers/acpi/scan.c 2006-12-01 15:22:25.000000000 +0800
@@ -866,11 +866,6 @@ static int acpi_bus_remove(struct acpi_d
if (!rmdevice)
return 0;
- if (dev->flags.bus_address) {
- if ((dev->parent) && (dev->parent->ops.unbind))
- dev->parent->ops.unbind(dev);
- }
-
acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
return 0;
@@ -987,18 +982,6 @@ acpi_add_single_object(struct acpi_devic
acpi_device_register(device, parent);
- /*
- * Bind _ADR-Based Devices
- * -----------------------
- * If there's a a bus address (_ADR) then we utilize the parent's
- * 'bind' function (if exists) to bind the ACPI- and natively-
- * enumerated device representations.
- */
- if (device->flags.bus_address) {
- if (device->parent && device->parent->ops.bind)
- device->parent->ops.bind(device);
- }
-
end:
if (!result)
*child = device;
[-- Attachment #4: 13-use-PNPID-and-instance_no-as-bus_id-of-ACPI-devices-in-sysfs.patch --]
[-- Type: text/x-patch, Size: 6850 bytes --]
Previously we used the device name in the DSDT, but would
crash upon encountering a duplicate. Also, exposing the
DSDT device name to the user in a patch isn't a good idea,
because it is arbitrary.
After some discussion, we finally decided to use
"PNPID:instance_no" as the bus_id of ACPI devices.
Two attributes for each device are added at the same time,
the full pathname in ACPI namespace and hardware_id if it has.
NOTE: acpi_bus_id_list is used to keep the information of PNPID
and instance number of the given PNPID. Loop the
acpi_bus_id_list to find the instance_no of the same PNPID
when register a device. If failed, i.e. we don't have a
node with this PNPID, allocate one and link it to this list.
NOTE: Now I don't take the memory free work in charge.
If necessary, I can add a reference count in
struct acpi_device_bus_id, and check the reference and
when unregister a device, i.e. memory is freed when
the reference count of a given PNPID is 0.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
drivers/acpi/scan.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 94 insertions(+), 9 deletions(-)
Index: linux-2.6.19/drivers/acpi/scan.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/scan.c 2006-12-01 16:23:50.000000000 +0800
+++ linux-2.6.19/drivers/acpi/scan.c 2006-12-01 16:29:05.000000000 +0800
@@ -21,9 +21,15 @@ extern struct acpi_device *acpi_root;
#define ACPI_BUS_DEVICE_NAME "System Bus"
static LIST_HEAD(acpi_device_list);
+static LIST_HEAD(acpi_bus_id_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
+struct acpi_device_bus_id{
+ char bus_id[9];
+ unsigned int instance_no;
+ struct list_head node;
+};
static int acpi_eject_operation(acpi_handle handle, int lockable)
{
struct acpi_object_list arg_list;
@@ -103,18 +109,61 @@ acpi_eject_store(struct device *d, struc
static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
-static void acpi_device_setup_files(struct acpi_device *dev)
+static ssize_t
+acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+
+ return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
+}
+static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
+
+static ssize_t
+acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+ int result;
+
+ result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
+ if(result)
+ goto end;
+
+ result = sprintf(buf, "%s\n", (char*)path.pointer);
+ kfree(path.pointer);
+ end:
+ return result;
+}
+static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
+
+static int acpi_device_setup_files(struct acpi_device *dev)
{
acpi_status status;
acpi_handle temp;
+ int result = 0;
/*
- * If device has _EJ0, 'eject' file is created that is used to trigger
- * hot-removal function from userland.
+ * Devices gotten from FADT don't need "path" attribute
*/
+ if(dev->handle) {
+ result = device_create_file(&dev->dev, &dev_attr_path);
+ if(result)
+ goto end;
+ }
+
+ if(dev->flags.hardware_id) {
+ result = device_create_file(&dev->dev, &dev_attr_hid);
+ if(result)
+ goto end;
+ }
+
+ /*
+ * 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);
+ result = device_create_file(&dev->dev, &dev_attr_eject);
+ end:
+ return result;
}
static void acpi_device_remove_files(struct acpi_device *dev)
@@ -129,6 +178,11 @@ static void acpi_device_remove_files(str
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
device_remove_file(&dev->dev, &dev_attr_eject);
+
+ if(dev->flags.hardware_id)
+ device_remove_file(&dev->dev, &dev_attr_hid);
+ if(dev->handle)
+ device_remove_file(&dev->dev, &dev_attr_path);
}
/* --------------------------------------------------------------------------
ACPI Bus operations
@@ -260,9 +314,13 @@ static struct bus_type acpi_bus_type = {
.uevent = acpi_device_uevent,
};
-static void acpi_device_register(struct acpi_device *device,
+static int acpi_device_register(struct acpi_device *device,
struct acpi_device *parent)
{
+ int result;
+ struct list_head *node, *next;
+ struct acpi_device_bus_id *acpi_device_bus_id;
+ int found = 0;
/*
* Linkage
* -------
@@ -281,18 +339,45 @@ static void acpi_device_register(struct
list_add_tail(&device->g_list, &acpi_device_list);
if (device->wakeup.flags.valid)
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
+ /*
+ * Find suitable bus_id and instance number in acpi_bus_id_list
+ * If failed, create one and link it into acpi_bus_id_list
+ */
+ list_for_each_safe(node, next, &acpi_bus_id_list) {
+ acpi_device_bus_id = container_of(node, struct acpi_device_bus_id, node);
+ if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "PNPIDNON")) {
+ acpi_device_bus_id->instance_no ++;
+ found = 1;
+ break;
+ }
+ }
+ if(!found) {
+ acpi_device_bus_id = kmalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
+ memset(acpi_device_bus_id, sizeof(struct acpi_device_bus_id), 0);
+ strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "PNPIDNON");
+ acpi_device_bus_id->instance_no = 0;
+ list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
+ }
+ sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
spin_unlock(&acpi_device_lock);
if (device->parent)
device->dev.parent = &parent->dev;
device->dev.bus = &acpi_bus_type;
device_initialize(&device->dev);
- sprintf(device->dev.bus_id, "%s", device->pnp.bus_id);
device->dev.release = &acpi_device_release;
- device_add(&device->dev);
+ result = device_add(&device->dev);
+ if(result) {
+ printk("Error adding device %s", device->dev.bus_id);
+ return result;
+ }
+
+ result = acpi_device_setup_files(device);
+ if(result)
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
- acpi_device_setup_files(device);
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
+ return 0;
}
static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -1035,7 +1120,7 @@ acpi_add_single_object(struct acpi_devic
acpi_device_get_debug_info(device, handle, type);
- acpi_device_register(device, parent);
+ result = acpi_device_register(device, parent);
end:
if (!result)
[-- Attachment #5: 14-fix-ibm_acpi-sub_driver-name.patch --]
[-- Type: message/rfc822, Size: 1173 bytes --]
From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Subject: No Subject
Date: Fri, 01 Dec 2006 16:54:46 +0800
Message-ID: <1164963286.6324.4.camel@localhost.localdomain>
ibm-acpi uses sub-device names like ibm/hotkey, which get in the way of
a sysfs conversion. Fix it to use ibm_hotkey instead. Thanks to Zhang
Rui for noticing this.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
drivers/acpi/ibm_acpi.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6.19/drivers/acpi/ibm_acpi.c
===================================================================
--- linux-2.6.19.orig/drivers/acpi/ibm_acpi.c 2006-12-01 11:10:37.000000000 +0800
+++ linux-2.6.19/drivers/acpi/ibm_acpi.c 2006-12-01 11:33:30.000000000 +0800
@@ -1825,7 +1825,7 @@ static int __init register_driver(struct
}
memset(ibm->driver, 0, sizeof(struct acpi_driver));
- sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
+ sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
ibm->driver->ids = ibm->hid;
ibm->driver->ops.add = &ibm_device_add;
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2006-12-01 8:51 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-24 5:17 contents of sysfs branch Len Brown
[not found] ` <bd119392c453771fdb994728a2568c2e3f17705d.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 1/13] ACPI: clean up scan.c Len Brown
[not found] ` <1b3d821f47ae0d8393851c4ff82f6dd667868ead.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 2/13] ACPI: rename some functions Len Brown
[not found] ` <5b4e67afe03abecbba9eb45805f4e14214fc65a6.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 3/13] ACPI: add device_driver and helper functions Len Brown
[not found] ` <1a01fe8f75dc4b96707ebdac366121e772063b96.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 4/13] ACPI: add ACPI bus_type for driver model Len Brown
[not found] ` <eb3ec2290520985fd3a9392342ab586fba1e33c3.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 5/13] ACPI: change registration interface to follow " Len Brown
[not found] ` <b4ade865912166d7657e5f2a5af4c546c7fe2959.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 6/13] ACPI: adjust init order Len Brown
[not found] ` <d190142cedf99bb444dfa27164686904773a7051.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 7/13] ACPI: convert to sysfs framework Len Brown
[not found] ` <b23b4763ca902ef393e87c81177a0b6d6f8388ae.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 8/13] ACPI: add acpi_bus_ops in acpi_device Len Brown
[not found] ` <68d72528fc25d05d0f6fc17212ea5f695448bee2.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 9/13] ACPI: add acpi_bus_removal_type " Len Brown
[not found] ` <46d1ee2fc5b8924aa5bb56c34f2205e6fc329b1b.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 10/13] ACPI: consolidate two motherboard drivers into one Len Brown
[not found] ` <e3eb7f2f2601e00fd34cf1e0b1f0c7cd324e0b6b.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 11/13] ACPI: Convert ACPI PCI .bind/.unbind to use PCI bridge driver Len Brown
[not found] ` <76e919d87de4de773fc728ecfb02f307b02c5f79.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 12/13] ACPI: Set fake hid for non-PNPID ACPI devices Len Brown
[not found] ` <d1f75c71119c62e4a399c5108250248213adfda6.1164343921.git.len.brown@intel.com>
2006-11-24 5:17 ` [PATCH 13/13] ACPI: use unique number as bus_id of ACPI device in sysfs Len Brown
2006-11-24 6:36 ` Len Brown
2006-11-24 9:40 ` Zhang Rui
2006-11-26 5:10 ` Zhang Rui
2006-11-27 6:10 ` Len Brown
2006-11-27 6:35 ` Zhang Rui
2006-11-27 6:06 ` Len Brown
2006-12-01 8:55 ` updated patches of sysfs branch Zhang Rui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).