Commit ea261051 authored by Len Brown's avatar Len Brown

Merge branch 'bjorn-HID' into release

parents 6d7f18f6 57f3674f
...@@ -94,36 +94,33 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) ...@@ -94,36 +94,33 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
EXPORT_SYMBOL(acpi_bus_get_device); EXPORT_SYMBOL(acpi_bus_get_device);
int acpi_bus_get_status(struct acpi_device *device) acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta)
{ {
acpi_status status = AE_OK; acpi_status status;
unsigned long long sta = 0;
status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
if (ACPI_SUCCESS(status))
return AE_OK;
if (!device) if (status == AE_NOT_FOUND) {
return -EINVAL; *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
return AE_OK;
}
return status;
}
/* int acpi_bus_get_status(struct acpi_device *device)
* Evaluate _STA if present. {
*/ acpi_status status;
if (device->flags.dynamic_status) { unsigned long long sta;
status =
acpi_evaluate_integer(device->handle, "_STA", NULL, &sta); status = acpi_bus_get_status_handle(device->handle, &sta);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
STRUCT_TO_INT(device->status) = (int)sta;
}
/* STRUCT_TO_INT(device->status) = (int) sta;
* According to ACPI spec some device can be present and functional
* even if the parent is not present but functional.
* In such conditions the child device should not inherit the status
* from the parent.
*/
else
STRUCT_TO_INT(device->status) =
ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
if (device->status.functional && !device->status.present) { if (device->status.functional && !device->status.present) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
...@@ -135,10 +132,8 @@ int acpi_bus_get_status(struct acpi_device *device) ...@@ -135,10 +132,8 @@ int acpi_bus_get_status(struct acpi_device *device)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
device->pnp.bus_id, device->pnp.bus_id,
(u32) STRUCT_TO_INT(device->status))); (u32) STRUCT_TO_INT(device->status)));
return 0; return 0;
} }
EXPORT_SYMBOL(acpi_bus_get_status); EXPORT_SYMBOL(acpi_bus_get_status);
void acpi_bus_private_data_handler(acpi_handle handle, void acpi_bus_private_data_handler(acpi_handle handle,
......
...@@ -22,6 +22,8 @@ extern struct acpi_device *acpi_root; ...@@ -22,6 +22,8 @@ extern struct acpi_device *acpi_root;
#define ACPI_BUS_HID "LNXSYBUS" #define ACPI_BUS_HID "LNXSYBUS"
#define ACPI_BUS_DEVICE_NAME "System Bus" #define ACPI_BUS_DEVICE_NAME "System Bus"
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
static LIST_HEAD(acpi_device_list); static LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list); static LIST_HEAD(acpi_bus_id_list);
DEFINE_MUTEX(acpi_device_lock); DEFINE_MUTEX(acpi_device_lock);
...@@ -43,40 +45,19 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, ...@@ -43,40 +45,19 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
{ {
int len; int len;
int count; int count;
struct acpi_hardware_id *id;
if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids)
return -ENODEV;
len = snprintf(modalias, size, "acpi:"); len = snprintf(modalias, size, "acpi:");
size -= len; size -= len;
if (acpi_dev->flags.hardware_id) { list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
count = snprintf(&modalias[len], size, "%s:", count = snprintf(&modalias[len], size, "%s:", id->id);
acpi_dev->pnp.hardware_id);
if (count < 0 || count >= size) if (count < 0 || count >= size)
return -EINVAL; return -EINVAL;
len += count; len += count;
size -= count; size -= count;
} }
if (acpi_dev->flags.compatible_ids) {
struct acpica_device_id_list *cid_list;
int i;
cid_list = acpi_dev->pnp.cid_list;
for (i = 0; i < cid_list->count; i++) {
count = snprintf(&modalias[len], size, "%s:",
cid_list->ids[i].string);
if (count < 0 || count >= size) {
printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size",
acpi_dev->pnp.device_name, i);
break;
}
len += count;
size -= count;
}
}
modalias[len] = '\0'; modalias[len] = '\0';
return len; return len;
} }
...@@ -183,7 +164,7 @@ static ssize_t ...@@ -183,7 +164,7 @@ static ssize_t
acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_device *acpi_dev = to_acpi_device(dev);
return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id); return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev));
} }
static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
...@@ -219,17 +200,13 @@ static int acpi_device_setup_files(struct acpi_device *dev) ...@@ -219,17 +200,13 @@ static int acpi_device_setup_files(struct acpi_device *dev)
goto end; goto end;
} }
if (dev->flags.hardware_id) {
result = device_create_file(&dev->dev, &dev_attr_hid); result = device_create_file(&dev->dev, &dev_attr_hid);
if (result) if (result)
goto end; goto end;
}
if (dev->flags.hardware_id || dev->flags.compatible_ids) {
result = device_create_file(&dev->dev, &dev_attr_modalias); result = device_create_file(&dev->dev, &dev_attr_modalias);
if (result) if (result)
goto end; goto end;
}
/* /*
* If device has _EJ0, 'eject' file is created that is used to trigger * If device has _EJ0, 'eject' file is created that is used to trigger
...@@ -255,10 +232,7 @@ static void acpi_device_remove_files(struct acpi_device *dev) ...@@ -255,10 +232,7 @@ static void acpi_device_remove_files(struct acpi_device *dev)
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
device_remove_file(&dev->dev, &dev_attr_eject); device_remove_file(&dev->dev, &dev_attr_eject);
if (dev->flags.hardware_id || dev->flags.compatible_ids)
device_remove_file(&dev->dev, &dev_attr_modalias); device_remove_file(&dev->dev, &dev_attr_modalias);
if (dev->flags.hardware_id)
device_remove_file(&dev->dev, &dev_attr_hid); device_remove_file(&dev->dev, &dev_attr_hid);
if (dev->handle) if (dev->handle)
device_remove_file(&dev->dev, &dev_attr_path); device_remove_file(&dev->dev, &dev_attr_path);
...@@ -271,6 +245,7 @@ int acpi_match_device_ids(struct acpi_device *device, ...@@ -271,6 +245,7 @@ int acpi_match_device_ids(struct acpi_device *device,
const struct acpi_device_id *ids) const struct acpi_device_id *ids)
{ {
const struct acpi_device_id *id; const struct acpi_device_id *id;
struct acpi_hardware_id *hwid;
/* /*
* If the device is not present, it is unnecessary to load device * If the device is not present, it is unnecessary to load device
...@@ -279,40 +254,30 @@ int acpi_match_device_ids(struct acpi_device *device, ...@@ -279,40 +254,30 @@ int acpi_match_device_ids(struct acpi_device *device,
if (!device->status.present) if (!device->status.present)
return -ENODEV; return -ENODEV;
if (device->flags.hardware_id) { for (id = ids; id->id[0]; id++)
for (id = ids; id->id[0]; id++) { list_for_each_entry(hwid, &device->pnp.ids, list)
if (!strcmp((char*)id->id, device->pnp.hardware_id)) if (!strcmp((char *) id->id, hwid->id))
return 0; return 0;
}
}
if (device->flags.compatible_ids) {
struct acpica_device_id_list *cid_list = device->pnp.cid_list;
int i;
for (id = ids; id->id[0]; id++) {
/* compare multiple _CID entries against driver ids */
for (i = 0; i < cid_list->count; i++) {
if (!strcmp((char*)id->id,
cid_list->ids[i].string))
return 0;
}
}
}
return -ENOENT; return -ENOENT;
} }
EXPORT_SYMBOL(acpi_match_device_ids); EXPORT_SYMBOL(acpi_match_device_ids);
static void acpi_free_ids(struct acpi_device *device)
{
struct acpi_hardware_id *id, *tmp;
list_for_each_entry_safe(id, tmp, &device->pnp.ids, list) {
kfree(id->id);
kfree(id);
}
}
static void acpi_device_release(struct device *dev) static void acpi_device_release(struct device *dev)
{ {
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_device *acpi_dev = to_acpi_device(dev);
kfree(acpi_dev->pnp.cid_list); acpi_free_ids(acpi_dev);
if (acpi_dev->flags.hardware_id)
kfree(acpi_dev->pnp.hardware_id);
if (acpi_dev->flags.unique_id)
kfree(acpi_dev->pnp.unique_id);
kfree(acpi_dev); kfree(acpi_dev);
} }
...@@ -378,15 +343,13 @@ static acpi_status acpi_device_notify_fixed(void *data) ...@@ -378,15 +343,13 @@ static acpi_status acpi_device_notify_fixed(void *data)
static int acpi_device_install_notify_handler(struct acpi_device *device) static int acpi_device_install_notify_handler(struct acpi_device *device)
{ {
acpi_status status; acpi_status status;
char *hid;
hid = acpi_device_hid(device); if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
status = status =
acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
acpi_device_notify_fixed, acpi_device_notify_fixed,
device); device);
else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
status = status =
acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
acpi_device_notify_fixed, acpi_device_notify_fixed,
...@@ -404,10 +367,10 @@ static int acpi_device_install_notify_handler(struct acpi_device *device) ...@@ -404,10 +367,10 @@ static int acpi_device_install_notify_handler(struct acpi_device *device)
static void acpi_device_remove_notify_handler(struct acpi_device *device) static void acpi_device_remove_notify_handler(struct acpi_device *device)
{ {
if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
acpi_device_notify_fixed); acpi_device_notify_fixed);
else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
acpi_device_notify_fixed); acpi_device_notify_fixed);
else else
...@@ -474,12 +437,12 @@ struct bus_type acpi_bus_type = { ...@@ -474,12 +437,12 @@ struct bus_type acpi_bus_type = {
.uevent = acpi_device_uevent, .uevent = acpi_device_uevent,
}; };
static int acpi_device_register(struct acpi_device *device, static int acpi_device_register(struct acpi_device *device)
struct acpi_device *parent)
{ {
int result; int result;
struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
int found = 0; int found = 0;
/* /*
* Linkage * Linkage
* ------- * -------
...@@ -501,8 +464,9 @@ static int acpi_device_register(struct acpi_device *device, ...@@ -501,8 +464,9 @@ static int acpi_device_register(struct acpi_device *device,
* If failed, create one and link it into acpi_bus_id_list * If failed, create one and link it into acpi_bus_id_list
*/ */
list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) { if (!strcmp(acpi_device_bus_id->bus_id,
acpi_device_bus_id->instance_no ++; acpi_device_hid(device))) {
acpi_device_bus_id->instance_no++;
found = 1; found = 1;
kfree(new_bus_id); kfree(new_bus_id);
break; break;
...@@ -510,7 +474,7 @@ static int acpi_device_register(struct acpi_device *device, ...@@ -510,7 +474,7 @@ static int acpi_device_register(struct acpi_device *device,
} }
if (!found) { if (!found) {
acpi_device_bus_id = new_bus_id; acpi_device_bus_id = new_bus_id;
strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device));
acpi_device_bus_id->instance_no = 0; acpi_device_bus_id->instance_no = 0;
list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
} }
...@@ -524,7 +488,7 @@ static int acpi_device_register(struct acpi_device *device, ...@@ -524,7 +488,7 @@ static int acpi_device_register(struct acpi_device *device,
mutex_unlock(&acpi_device_lock); mutex_unlock(&acpi_device_lock);
if (device->parent) if (device->parent)
device->dev.parent = &parent->dev; device->dev.parent = &device->parent->dev;
device->dev.bus = &acpi_bus_type; device->dev.bus = &acpi_bus_type;
device->dev.release = &acpi_device_release; device->dev.release = &acpi_device_release;
result = device_register(&device->dev); result = device_register(&device->dev);
...@@ -664,6 +628,33 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver); ...@@ -664,6 +628,33 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Device Enumeration Device Enumeration
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
{
acpi_status status;
int ret;
struct acpi_device *device;
/*
* Fixed hardware devices do not appear in the namespace and do not
* have handles, but we fabricate acpi_devices for them, so we have
* to deal with them specially.
*/
if (handle == NULL)
return acpi_root;
do {
status = acpi_get_parent(handle, &handle);
if (status == AE_NULL_ENTRY)
return NULL;
if (ACPI_FAILURE(status))
return acpi_root;
ret = acpi_bus_get_device(handle, &device);
if (ret == 0)
return device;
} while (1);
}
acpi_status acpi_status
acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
{ {
...@@ -876,11 +867,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) ...@@ -876,11 +867,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
device->flags.dynamic_status = 1; device->flags.dynamic_status = 1;
/* Presence of _CID indicates 'compatible_ids' */
status = acpi_get_handle(device->handle, "_CID", &temp);
if (ACPI_SUCCESS(status))
device->flags.compatible_ids = 1;
/* Presence of _RMV indicates 'removable' */ /* Presence of _RMV indicates 'removable' */
status = acpi_get_handle(device->handle, "_RMV", &temp); status = acpi_get_handle(device->handle, "_RMV", &temp);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
...@@ -918,8 +904,7 @@ static int acpi_bus_get_flags(struct acpi_device *device) ...@@ -918,8 +904,7 @@ static int acpi_bus_get_flags(struct acpi_device *device)
return 0; return 0;
} }
static void acpi_device_get_busid(struct acpi_device *device, static void acpi_device_get_busid(struct acpi_device *device)
acpi_handle handle, int type)
{ {
char bus_id[5] = { '?', 0 }; char bus_id[5] = { '?', 0 };
struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
...@@ -931,10 +916,12 @@ static void acpi_device_get_busid(struct acpi_device *device, ...@@ -931,10 +916,12 @@ static void acpi_device_get_busid(struct acpi_device *device,
* The device's Bus ID is simply the object name. * The device's Bus ID is simply the object name.
* TBD: Shouldn't this value be unique (within the ACPI namespace)? * TBD: Shouldn't this value be unique (within the ACPI namespace)?
*/ */
switch (type) { if (ACPI_IS_ROOT_DEVICE(device)) {
case ACPI_BUS_TYPE_SYSTEM:
strcpy(device->pnp.bus_id, "ACPI"); strcpy(device->pnp.bus_id, "ACPI");
break; return;
}
switch (device->device_type) {
case ACPI_BUS_TYPE_POWER_BUTTON: case ACPI_BUS_TYPE_POWER_BUTTON:
strcpy(device->pnp.bus_id, "PWRF"); strcpy(device->pnp.bus_id, "PWRF");
break; break;
...@@ -942,7 +929,7 @@ static void acpi_device_get_busid(struct acpi_device *device, ...@@ -942,7 +929,7 @@ static void acpi_device_get_busid(struct acpi_device *device,
strcpy(device->pnp.bus_id, "SLPF"); strcpy(device->pnp.bus_id, "SLPF");
break; break;
default: default:
acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer);
/* Clean up trailing underscores (if any) */ /* Clean up trailing underscores (if any) */
for (i = 3; i > 1; i--) { for (i = 3; i > 1; i--) {
if (bus_id[i] == '_') if (bus_id[i] == '_')
...@@ -1000,204 +987,132 @@ static int acpi_dock_match(struct acpi_device *device) ...@@ -1000,204 +987,132 @@ static int acpi_dock_match(struct acpi_device *device)
return acpi_get_handle(device->handle, "_DCK", &tmp); return acpi_get_handle(device->handle, "_DCK", &tmp);
} }
static struct acpica_device_id_list* char *acpi_device_hid(struct acpi_device *device)
acpi_add_cid(
struct acpi_device_info *info,
struct acpica_device_id *new_cid)
{ {
struct acpica_device_id_list *cid; struct acpi_hardware_id *hid;
char *next_id_string;
acpi_size cid_length;
acpi_size new_cid_length;
u32 i;
/* Allocate new CID list with room for the new CID */
if (!new_cid) hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
new_cid_length = info->compatible_id_list.list_size; return hid->id;
else if (info->compatible_id_list.list_size) }
new_cid_length = info->compatible_id_list.list_size + EXPORT_SYMBOL(acpi_device_hid);
new_cid->length + sizeof(struct acpica_device_id);
else
new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length;
cid = ACPI_ALLOCATE_ZEROED(new_cid_length);
if (!cid) {
return NULL;
}
cid->list_size = new_cid_length;
cid->count = info->compatible_id_list.count;
if (new_cid)
cid->count++;
next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id));
/* Copy all existing CIDs */
for (i = 0; i < info->compatible_id_list.count; i++) {
cid_length = info->compatible_id_list.ids[i].length;
cid->ids[i].string = next_id_string;
cid->ids[i].length = cid_length;
ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string,
cid_length);
next_id_string += cid_length;
}
/* Append the new CID */ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
{
struct acpi_hardware_id *id;
if (new_cid) { id = kmalloc(sizeof(*id), GFP_KERNEL);
cid->ids[i].string = next_id_string; if (!id)
cid->ids[i].length = new_cid->length; return;
ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
if (!id->id) {
kfree(id);
return;
} }
return cid; strcpy(id->id, dev_id);
list_add_tail(&id->list, &device->pnp.ids);
} }
static void acpi_device_set_id(struct acpi_device *device, static void acpi_device_set_id(struct acpi_device *device)
struct acpi_device *parent, acpi_handle handle,
int type)
{ {
struct acpi_device_info *info = NULL;
char *hid = NULL;
char *uid = NULL;
struct acpica_device_id_list *cid_list = NULL;
char *cid_add = NULL;
acpi_status status; acpi_status status;
struct acpi_device_info *info;
struct acpica_device_id_list *cid_list;
int i;
switch (type) { switch (device->device_type) {
case ACPI_BUS_TYPE_DEVICE: case ACPI_BUS_TYPE_DEVICE:
status = acpi_get_object_info(handle, &info); if (ACPI_IS_ROOT_DEVICE(device)) {
acpi_add_id(device, ACPI_SYSTEM_HID);
break;
} else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
/* \_SB_, the only root-level namespace device */
acpi_add_id(device, ACPI_BUS_HID);
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
break;
}
status = acpi_get_object_info(device->handle, &info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
return; return;
} }
if (info->valid & ACPI_VALID_HID) if (info->valid & ACPI_VALID_HID)
hid = info->hardware_id.string; acpi_add_id(device, info->hardware_id.string);
if (info->valid & ACPI_VALID_UID) if (info->valid & ACPI_VALID_CID) {
uid = info->unique_id.string;
if (info->valid & ACPI_VALID_CID)
cid_list = &info->compatible_id_list; cid_list = &info->compatible_id_list;
for (i = 0; i < cid_list->count; i++)
acpi_add_id(device, cid_list->ids[i].string);
}
if (info->valid & ACPI_VALID_ADR) { if (info->valid & ACPI_VALID_ADR) {
device->pnp.bus_address = info->address; device->pnp.bus_address = info->address;
device->flags.bus_address = 1; device->flags.bus_address = 1;
} }
/* If we have a video/bay/dock device, add our selfdefined /*
HID to the CID list. Like that the video/bay/dock drivers * Some devices don't reliably have _HIDs & _CIDs, so add
will get autoloaded and the device might still match * synthetic HIDs to make sure drivers can find them.
against another driver.
*/ */
if (acpi_is_video_device(device)) if (acpi_is_video_device(device))
cid_add = ACPI_VIDEO_HID; acpi_add_id(device, ACPI_VIDEO_HID);
else if (ACPI_SUCCESS(acpi_bay_match(device))) else if (ACPI_SUCCESS(acpi_bay_match(device)))
cid_add = ACPI_BAY_HID; acpi_add_id(device, ACPI_BAY_HID);
else if (ACPI_SUCCESS(acpi_dock_match(device))) else if (ACPI_SUCCESS(acpi_dock_match(device)))
cid_add = ACPI_DOCK_HID; acpi_add_id(device, ACPI_DOCK_HID);
break; break;
case ACPI_BUS_TYPE_POWER: case ACPI_BUS_TYPE_POWER:
hid = ACPI_POWER_HID; acpi_add_id(device, ACPI_POWER_HID);
break; break;
case ACPI_BUS_TYPE_PROCESSOR: case ACPI_BUS_TYPE_PROCESSOR:
hid = ACPI_PROCESSOR_OBJECT_HID; acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID);
break;
case ACPI_BUS_TYPE_SYSTEM:
hid = ACPI_SYSTEM_HID;
break; break;
case ACPI_BUS_TYPE_THERMAL: case ACPI_BUS_TYPE_THERMAL:
hid = ACPI_THERMAL_HID; acpi_add_id(device, ACPI_THERMAL_HID);
break; break;
case ACPI_BUS_TYPE_POWER_BUTTON: case ACPI_BUS_TYPE_POWER_BUTTON:
hid = ACPI_BUTTON_HID_POWERF; acpi_add_id(device, ACPI_BUTTON_HID_POWERF);
break; break;
case ACPI_BUS_TYPE_SLEEP_BUTTON: case ACPI_BUS_TYPE_SLEEP_BUTTON:
hid = ACPI_BUTTON_HID_SLEEPF; acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
break; break;
} }
/* /*
* \_SB * We build acpi_devices for some objects that don't have _HID or _CID,
* ---- * e.g., PCI bridges and slots. Drivers can't bind to these objects,
* Fix for the system root bus device -- the only root-level device. * but we do use them indirectly by traversing the acpi_device tree.
* This generic ID isn't useful for driver binding, but it provides
* the useful property that "every acpi_device has an ID."
*/ */
if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { if (list_empty(&device->pnp.ids))
hid = ACPI_BUS_HID; acpi_add_id(device, "device");
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
}
if (hid) {
device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1);
if (device->pnp.hardware_id) {
strcpy(device->pnp.hardware_id, hid);
device->flags.hardware_id = 1;
}
}
if (!device->flags.hardware_id)
device->pnp.hardware_id = "";
if (uid) {
device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1);
if (device->pnp.unique_id) {
strcpy(device->pnp.unique_id, uid);
device->flags.unique_id = 1;
}
}
if (!device->flags.unique_id)
device->pnp.unique_id = "";
if (cid_list || cid_add) {
struct acpica_device_id_list *list;
if (cid_add) {
struct acpica_device_id cid;
cid.length = strlen (cid_add) + 1;
cid.string = cid_add;
list = acpi_add_cid(info, &cid);
} else {
list = acpi_add_cid(info, NULL);
}
if (list) {
device->pnp.cid_list = list;
if (cid_add)
device->flags.compatible_ids = 1;
}
}
kfree(info);
} }
static int acpi_device_set_context(struct acpi_device *device, int type) static int acpi_device_set_context(struct acpi_device *device)
{ {
acpi_status status = AE_OK; acpi_status status;
int result = 0;
/* /*
* Context * Context
* ------- * -------
* Attach this 'struct acpi_device' to the ACPI object. This makes * Attach this 'struct acpi_device' to the ACPI object. This makes
* resolutions from handle->device very efficient. Note that we need * resolutions from handle->device very efficient. Fixed hardware
* to be careful with fixed-feature devices as they all attach to the * devices have no handles, so we skip them.
* root object.
*/ */
if (type != ACPI_BUS_TYPE_POWER_BUTTON && if (!device->handle)
type != ACPI_BUS_TYPE_SLEEP_BUTTON) { return 0;
status = acpi_attach_data(device->handle, status = acpi_attach_data(device->handle,
acpi_bus_data_handler, device); acpi_bus_data_handler, device);
if (ACPI_SUCCESS(status))
return 0;
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Error attaching device data\n"); printk(KERN_ERR PREFIX "Error attaching device data\n");
result = -ENODEV; return -ENODEV;
}
}
return result;
} }
static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
...@@ -1223,17 +1138,14 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) ...@@ -1223,17 +1138,14 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
return 0; return 0;
} }
static int static int acpi_add_single_object(struct acpi_device **child,
acpi_add_single_object(struct acpi_device **child, acpi_handle handle, int type,
struct acpi_device *parent, acpi_handle handle, int type, unsigned long long sta,
struct acpi_bus_ops *ops) struct acpi_bus_ops *ops)
{ {
int result = 0; int result;
struct acpi_device *device = NULL; struct acpi_device *device;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
if (!child)
return -EINVAL;
device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
if (!device) { if (!device) {
...@@ -1241,75 +1153,31 @@ acpi_add_single_object(struct acpi_device **child, ...@@ -1241,75 +1153,31 @@ acpi_add_single_object(struct acpi_device **child,
return -ENOMEM; return -ENOMEM;
} }
INIT_LIST_HEAD(&device->pnp.ids);
device->device_type = type;
device->handle = handle; device->handle = handle;
device->parent = parent; device->parent = acpi_bus_get_parent(handle);
device->bus_ops = *ops; /* workround for not call .start */ device->bus_ops = *ops; /* workround for not call .start */
STRUCT_TO_INT(device->status) = sta;
acpi_device_get_busid(device);
acpi_device_get_busid(device, handle, type);
/* /*
* Flags * Flags
* ----- * -----
* Get prior to calling acpi_bus_get_status() so we know whether * Note that we only look for object handles -- cannot evaluate objects
* or not _STA is present. Note that we only look for object * until we know the device is present and properly initialized.
* handles -- cannot evaluate objects until we know the device is
* present and properly initialized.
*/ */
result = acpi_bus_get_flags(device); result = acpi_bus_get_flags(device);
if (result) if (result)
goto end; goto end;
/*
* Status
* ------
* See if the device is present. We always assume that non-Device
* and non-Processor objects (e.g. thermal zones, power resources,
* etc.) are present, functioning, etc. (at least when parent object
* is present). Note that _STA has a different meaning for some
* objects (e.g. power resources) so we need to be careful how we use
* it.
*/
switch (type) {
case ACPI_BUS_TYPE_PROCESSOR:
case ACPI_BUS_TYPE_DEVICE:
result = acpi_bus_get_status(device);
if (ACPI_FAILURE(result)) {
result = -ENODEV;
goto end;
}
/*
* When the device is neither present nor functional, the
* device should not be added to Linux ACPI device tree.
* When the status of the device is not present but functinal,
* it should be added to Linux ACPI tree. For example : bay
* device , dock device.
* In such conditions it is unncessary to check whether it is
* bay device or dock device.
*/
if (!device->status.present && !device->status.functional) {
result = -ENODEV;
goto end;
}
break;
default:
STRUCT_TO_INT(device->status) =
ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
break;
}
/* /*
* Initialize Device * Initialize Device
* ----------------- * -----------------
* TBD: Synch with Core's enumeration/initialization process. * TBD: Synch with Core's enumeration/initialization process.
*/ */
acpi_device_set_id(device);
/*
* Hardware ID, Unique ID, & Bus Address
* -------------------------------------
*/
acpi_device_set_id(device, parent, handle, type);
/* /*
* Power Management * Power Management
...@@ -1341,10 +1209,10 @@ acpi_add_single_object(struct acpi_device **child, ...@@ -1341,10 +1209,10 @@ acpi_add_single_object(struct acpi_device **child,
goto end; goto end;
} }
if ((result = acpi_device_set_context(device, type))) if ((result = acpi_device_set_context(device)))
goto end; goto end;
result = acpi_device_register(device, parent); result = acpi_device_register(device);
/* /*
* Bind _ADR-Based Devices when hot add * Bind _ADR-Based Devices when hot add
...@@ -1355,128 +1223,122 @@ acpi_add_single_object(struct acpi_device **child, ...@@ -1355,128 +1223,122 @@ acpi_add_single_object(struct acpi_device **child,
} }
end: end:
if (!result) if (!result) {
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Adding %s [%s] parent %s\n", dev_name(&device->dev),
(char *) buffer.pointer,
device->parent ? dev_name(&device->parent->dev) :
"(null)"));
kfree(buffer.pointer);
*child = device; *child = device;
else } else
acpi_device_release(&device->dev); acpi_device_release(&device->dev);
return result; return result;
} }
static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
{ ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
acpi_status status = AE_OK;
struct acpi_device *parent = NULL;
struct acpi_device *child = NULL;
acpi_handle phandle = NULL;
acpi_handle chandle = NULL;
acpi_object_type type = 0;
u32 level = 1;
if (!start)
return -EINVAL;
parent = start;
phandle = start->handle;
/*
* Parse through the ACPI namespace, identify all 'devices', and
* create a new 'struct acpi_device' for each.
*/
while ((level > 0) && parent) {
status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
chandle, &chandle);
/* static int acpi_bus_type_and_status(acpi_handle handle, int *type,
* If this scope is exhausted then move our way back up. unsigned long long *sta)
*/ {
if (ACPI_FAILURE(status)) { acpi_status status;
level--; acpi_object_type acpi_type;
chandle = phandle;
acpi_get_parent(phandle, &phandle);
if (parent->parent)
parent = parent->parent;
continue;
}
status = acpi_get_type(chandle, &type); status = acpi_get_type(handle, &acpi_type);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
continue; return -ENODEV;
/*
* If this is a scope object then parse it (depth-first).
*/
if (type == ACPI_TYPE_LOCAL_SCOPE) {
level++;
phandle = chandle;
chandle = NULL;
continue;
}
/* switch (acpi_type) {
* We're only interested in objects that we consider 'devices'. case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
*/
switch (type) {
case ACPI_TYPE_DEVICE: case ACPI_TYPE_DEVICE:
type = ACPI_BUS_TYPE_DEVICE; *type = ACPI_BUS_TYPE_DEVICE;
status = acpi_bus_get_status_handle(handle, sta);
if (ACPI_FAILURE(status))
return -ENODEV;
break; break;
case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_PROCESSOR:
type = ACPI_BUS_TYPE_PROCESSOR; *type = ACPI_BUS_TYPE_PROCESSOR;
status = acpi_bus_get_status_handle(handle, sta);
if (ACPI_FAILURE(status))
return -ENODEV;
break; break;
case ACPI_TYPE_THERMAL: case ACPI_TYPE_THERMAL:
type = ACPI_BUS_TYPE_THERMAL; *type = ACPI_BUS_TYPE_THERMAL;
*sta = ACPI_STA_DEFAULT;
break; break;
case ACPI_TYPE_POWER: case ACPI_TYPE_POWER:
type = ACPI_BUS_TYPE_POWER; *type = ACPI_BUS_TYPE_POWER;
*sta = ACPI_STA_DEFAULT;
break; break;
default: default:
continue; return -ENODEV;
} }
if (ops->acpi_op_add) return 0;
status = acpi_add_single_object(&child, parent, }
chandle, type, ops);
else
status = acpi_bus_get_device(chandle, &child);
if (ACPI_FAILURE(status)) static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
continue; void *context, void **return_value)
{
struct acpi_bus_ops *ops = context;
int type;
unsigned long long sta;
struct acpi_device *device;
acpi_status status;
int result;
if (ops->acpi_op_start && !(ops->acpi_op_add)) { result = acpi_bus_type_and_status(handle, &type, &sta);
status = acpi_start_single_object(child); if (result)
if (ACPI_FAILURE(status)) return AE_OK;
continue;
} if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
!(sta & ACPI_STA_DEVICE_FUNCTIONING))
return AE_CTRL_DEPTH;
/* /*
* If the device is present, enabled, and functioning then * We may already have an acpi_device from a previous enumeration. If
* parse its scope (depth-first). Note that we need to * so, we needn't add it again, but we may still have to start it.
* represent absent devices to facilitate PnP notifications
* -- but only the subtree head (not all of its children,
* which will be enumerated when the parent is inserted).
*
* TBD: Need notifications and other detection mechanisms
* in place before we can fully implement this.
*/
/*
* When the device is not present but functional, it is also
* necessary to scan the children of this device.
*/ */
if (child->status.present || (!child->status.present && device = NULL;
child->status.functional)) { acpi_bus_get_device(handle, &device);
status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, if (ops->acpi_op_add && !device)
NULL, NULL); acpi_add_single_object(&device, handle, type, sta, ops);
if (ACPI_SUCCESS(status)) {
level++; if (!device)
phandle = chandle; return AE_CTRL_DEPTH;
chandle = NULL;
parent = child; if (ops->acpi_op_start && !(ops->acpi_op_add)) {
} status = acpi_start_single_object(device);
} if (ACPI_FAILURE(status))
return AE_CTRL_DEPTH;
} }
if (!*return_value)
*return_value = device;
return AE_OK;
}
static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
struct acpi_device **child)
{
acpi_status status;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
void *device = NULL;
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n",
(char *) buffer.pointer);
status = acpi_bus_check_add(handle, 0, ops, &device);
if (ACPI_SUCCESS(status))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
acpi_bus_check_add, ops, &device);
if (child)
*child = device;
return 0; return 0;
} }
...@@ -1484,36 +1346,25 @@ int ...@@ -1484,36 +1346,25 @@ int
acpi_bus_add(struct acpi_device **child, acpi_bus_add(struct acpi_device **child,
struct acpi_device *parent, acpi_handle handle, int type) struct acpi_device *parent, acpi_handle handle, int type)
{ {
int result;
struct acpi_bus_ops ops; struct acpi_bus_ops ops;
memset(&ops, 0, sizeof(ops)); memset(&ops, 0, sizeof(ops));
ops.acpi_op_add = 1; ops.acpi_op_add = 1;
result = acpi_add_single_object(child, parent, handle, type, &ops); acpi_bus_scan(handle, &ops, child);
if (!result) return 0;
result = acpi_bus_scan(*child, &ops);
return result;
} }
EXPORT_SYMBOL(acpi_bus_add); EXPORT_SYMBOL(acpi_bus_add);
int acpi_bus_start(struct acpi_device *device) int acpi_bus_start(struct acpi_device *device)
{ {
int result;
struct acpi_bus_ops ops; struct acpi_bus_ops ops;
if (!device)
return -EINVAL;
result = acpi_start_single_object(device);
if (!result) {
memset(&ops, 0, sizeof(ops)); memset(&ops, 0, sizeof(ops));
ops.acpi_op_start = 1; ops.acpi_op_start = 1;
result = acpi_bus_scan(device, &ops);
} acpi_bus_scan(device->handle, &ops, NULL);
return result; return 0;
} }
EXPORT_SYMBOL(acpi_bus_start); EXPORT_SYMBOL(acpi_bus_start);
...@@ -1572,15 +1423,12 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice) ...@@ -1572,15 +1423,12 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice)
} }
EXPORT_SYMBOL_GPL(acpi_bus_trim); EXPORT_SYMBOL_GPL(acpi_bus_trim);
static int acpi_bus_scan_fixed(struct acpi_device *root) static int acpi_bus_scan_fixed(void)
{ {
int result = 0; int result = 0;
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
struct acpi_bus_ops ops; struct acpi_bus_ops ops;
if (!root)
return -ENODEV;
memset(&ops, 0, sizeof(ops)); memset(&ops, 0, sizeof(ops));
ops.acpi_op_add = 1; ops.acpi_op_add = 1;
ops.acpi_op_start = 1; ops.acpi_op_start = 1;
...@@ -1589,16 +1437,16 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) ...@@ -1589,16 +1437,16 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
* Enumerate all fixed-feature devices. * Enumerate all fixed-feature devices.
*/ */
if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
result = acpi_add_single_object(&device, acpi_root, result = acpi_add_single_object(&device, NULL,
NULL,
ACPI_BUS_TYPE_POWER_BUTTON, ACPI_BUS_TYPE_POWER_BUTTON,
ACPI_STA_DEFAULT,
&ops); &ops);
} }
if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
result = acpi_add_single_object(&device, acpi_root, result = acpi_add_single_object(&device, NULL,
NULL,
ACPI_BUS_TYPE_SLEEP_BUTTON, ACPI_BUS_TYPE_SLEEP_BUTTON,
ACPI_STA_DEFAULT,
&ops); &ops);
} }
...@@ -1620,25 +1468,16 @@ int __init acpi_scan_init(void) ...@@ -1620,25 +1468,16 @@ int __init acpi_scan_init(void)
printk(KERN_ERR PREFIX "Could not register bus type\n"); printk(KERN_ERR PREFIX "Could not register bus type\n");
} }
/*
* 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, &ops);
if (result)
goto Done;
/* /*
* Enumerate devices in the ACPI namespace. * Enumerate devices in the ACPI namespace.
*/ */
result = acpi_bus_scan_fixed(acpi_root); result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
if (!result) if (!result)
result = acpi_bus_scan(acpi_root, &ops); result = acpi_bus_scan_fixed();
if (result) if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
Done:
return result; return result;
} }
...@@ -406,7 +406,6 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, ...@@ -406,7 +406,6 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
__func__, status); __func__, status);
return retval; return retval;
} }
info->hardware_id.string[sizeof(info->hardware_id.length) - 1] = '\0';
if (info->current_status && (info->valid & ACPI_VALID_HID) && if (info->current_status && (info->valid & ACPI_VALID_HID) &&
(!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) || (!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) ||
......
...@@ -153,6 +153,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) ...@@ -153,6 +153,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
acpi_handle temp = NULL; acpi_handle temp = NULL;
acpi_status status; acpi_status status;
struct pnp_dev *dev; struct pnp_dev *dev;
struct acpi_hardware_id *id;
/* /*
* If a PnPacpi device is not present , the device * If a PnPacpi device is not present , the device
...@@ -193,15 +194,12 @@ static int __init pnpacpi_add_device(struct acpi_device *device) ...@@ -193,15 +194,12 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
if (dev->capabilities & PNP_CONFIGURABLE) if (dev->capabilities & PNP_CONFIGURABLE)
pnpacpi_parse_resource_option_data(dev); pnpacpi_parse_resource_option_data(dev);
if (device->flags.compatible_ids) { list_for_each_entry(id, &device->pnp.ids, list) {
struct acpica_device_id_list *cid_list = device->pnp.cid_list; if (!strcmp(id->id, acpi_device_hid(device)))
int i;
for (i = 0; i < cid_list->count; i++) {
if (!ispnpidacpi(cid_list->ids[i].string))
continue; continue;
pnp_add_id(dev, cid_list->ids[i].string); if (!ispnpidacpi(id->id))
} continue;
pnp_add_id(dev, id->id);
} }
/* clear out the damaged flags */ /* clear out the damaged flags */
...@@ -232,9 +230,8 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) ...@@ -232,9 +230,8 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
struct pnp_dev *pnp = _pnp; struct pnp_dev *pnp = _pnp;
/* true means it matched */ /* true means it matched */
return acpi->flags.hardware_id return !acpi_get_physical_device(acpi->handle)
&& !acpi_get_physical_device(acpi->handle) && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
&& compare_pnp_id(pnp->id, acpi->pnp.hardware_id);
} }
static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle) static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle)
......
...@@ -70,7 +70,6 @@ enum acpi_bus_device_type { ...@@ -70,7 +70,6 @@ enum acpi_bus_device_type {
ACPI_BUS_TYPE_POWER, ACPI_BUS_TYPE_POWER,
ACPI_BUS_TYPE_PROCESSOR, ACPI_BUS_TYPE_PROCESSOR,
ACPI_BUS_TYPE_THERMAL, ACPI_BUS_TYPE_THERMAL,
ACPI_BUS_TYPE_SYSTEM,
ACPI_BUS_TYPE_POWER_BUTTON, ACPI_BUS_TYPE_POWER_BUTTON,
ACPI_BUS_TYPE_SLEEP_BUTTON, ACPI_BUS_TYPE_SLEEP_BUTTON,
ACPI_BUS_DEVICE_TYPE_COUNT ACPI_BUS_DEVICE_TYPE_COUNT
...@@ -142,10 +141,7 @@ struct acpi_device_status { ...@@ -142,10 +141,7 @@ struct acpi_device_status {
struct acpi_device_flags { struct acpi_device_flags {
u32 dynamic_status:1; u32 dynamic_status:1;
u32 hardware_id:1;
u32 compatible_ids:1;
u32 bus_address:1; u32 bus_address:1;
u32 unique_id:1;
u32 removable:1; u32 removable:1;
u32 ejectable:1; u32 ejectable:1;
u32 lockable:1; u32 lockable:1;
...@@ -154,7 +150,7 @@ struct acpi_device_flags { ...@@ -154,7 +150,7 @@ struct acpi_device_flags {
u32 performance_manageable:1; u32 performance_manageable:1;
u32 wake_capable:1; /* Wakeup(_PRW) supported? */ u32 wake_capable:1; /* Wakeup(_PRW) supported? */
u32 force_power_state:1; u32 force_power_state:1;
u32 reserved:19; u32 reserved:22;
}; };
/* File System */ /* File System */
...@@ -172,20 +168,23 @@ typedef unsigned long acpi_bus_address; ...@@ -172,20 +168,23 @@ typedef unsigned long acpi_bus_address;
typedef char acpi_device_name[40]; typedef char acpi_device_name[40];
typedef char acpi_device_class[20]; typedef char acpi_device_class[20];
struct acpi_hardware_id {
struct list_head list;
char *id;
};
struct acpi_device_pnp { struct acpi_device_pnp {
acpi_bus_id bus_id; /* Object name */ acpi_bus_id bus_id; /* Object name */
acpi_bus_address bus_address; /* _ADR */ acpi_bus_address bus_address; /* _ADR */
char *hardware_id; /* _HID */
struct acpica_device_id_list *cid_list; /* _CIDs */
char *unique_id; /* _UID */ char *unique_id; /* _UID */
struct list_head ids; /* _HID and _CIDs */
acpi_device_name device_name; /* Driver-determined */ acpi_device_name device_name; /* Driver-determined */
acpi_device_class device_class; /* " */ acpi_device_class device_class; /* " */
}; };
#define acpi_device_bid(d) ((d)->pnp.bus_id) #define acpi_device_bid(d) ((d)->pnp.bus_id)
#define acpi_device_adr(d) ((d)->pnp.bus_address) #define acpi_device_adr(d) ((d)->pnp.bus_address)
#define acpi_device_hid(d) ((d)->pnp.hardware_id) char *acpi_device_hid(struct acpi_device *device);
#define acpi_device_uid(d) ((d)->pnp.unique_id)
#define acpi_device_name(d) ((d)->pnp.device_name) #define acpi_device_name(d) ((d)->pnp.device_name)
#define acpi_device_class(d) ((d)->pnp.device_class) #define acpi_device_class(d) ((d)->pnp.device_class)
...@@ -262,7 +261,8 @@ struct acpi_device_wakeup { ...@@ -262,7 +261,8 @@ struct acpi_device_wakeup {
/* Device */ /* Device */
struct acpi_device { struct acpi_device {
acpi_handle handle; int device_type;
acpi_handle handle; /* no handle for fixed hardware */
struct acpi_device *parent; struct acpi_device *parent;
struct list_head children; struct list_head children;
struct list_head node; struct list_head node;
...@@ -322,6 +322,8 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); ...@@ -322,6 +322,8 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
void acpi_bus_data_handler(acpi_handle handle, void *context); void acpi_bus_data_handler(acpi_handle handle, void *context);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_get_power(acpi_handle handle, int *state);
int acpi_bus_set_power(acpi_handle handle, int state); int acpi_bus_set_power(acpi_handle handle, int state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment