Skip to content

Commit

Permalink
ACPI: add acpi_bus_ops in acpi_device
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Li Shaohua authored and Len Brown committed Dec 16, 2006
1 parent f883d9d commit c4168bf
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 27 deletions.
55 changes: 28 additions & 27 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ static int acpi_device_probe(struct device * dev)

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));
Expand Down Expand Up @@ -305,7 +306,6 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
list_del(&device->g_list);

list_del(&device->wakeup_list);

spin_unlock(&acpi_device_lock);

acpi_detach_data(device->handle, acpi_bus_data_handler);
Expand Down Expand Up @@ -876,7 +876,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)

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;
Expand All @@ -894,6 +895,8 @@ acpi_add_single_object(struct acpi_device **child,

device->handle = handle;
device->parent = parent;
device->bus_ops = *ops; /* workround for not call .start */


acpi_device_get_busid(device, handle, type);

Expand Down Expand Up @@ -1079,14 +1082,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)

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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -1216,28 +1219,30 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
{
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;
Expand All @@ -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 */
Expand All @@ -1262,24 +1271,16 @@ 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;

/*
* 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);
Expand Down
1 change: 1 addition & 0 deletions include/acpi/acpi_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit c4168bf

Please sign in to comment.