Commit 8f859016 authored by Len Brown's avatar Len Brown

Merge branches 'release' and 'autoload' into release

parents dd07a8db 17196d6e
...@@ -46,6 +46,12 @@ MODULE_LICENSE("GPL"); ...@@ -46,6 +46,12 @@ MODULE_LICENSE("GPL");
printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
static void bay_notify(acpi_handle handle, u32 event, void *data); static void bay_notify(acpi_handle handle, u32 event, void *data);
static const struct acpi_device_id bay_device_ids[] = {
{"LNXIOBAY", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, bay_device_ids);
struct bay { struct bay {
acpi_handle handle; acpi_handle handle;
char *name; char *name;
......
...@@ -51,6 +51,12 @@ static struct atomic_notifier_head dock_notifier_list; ...@@ -51,6 +51,12 @@ static struct atomic_notifier_head dock_notifier_list;
static struct platform_device *dock_device; static struct platform_device *dock_device;
static char dock_device_name[] = "dock"; static char dock_device_name[] = "dock";
static const struct acpi_device_id dock_device_ids[] = {
{"LNXDOCK", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, dock_device_ids);
struct dock_station { struct dock_station {
acpi_handle handle; acpi_handle handle;
unsigned long last_dock_time; unsigned long last_dock_time;
......
...@@ -941,6 +941,15 @@ static int acpi_bay_match(struct acpi_device *device){ ...@@ -941,6 +941,15 @@ static int acpi_bay_match(struct acpi_device *device){
return -ENODEV; return -ENODEV;
} }
/*
* acpi_dock_match - see if a device has a _DCK method
*/
static int acpi_dock_match(struct acpi_device *device)
{
acpi_handle tmp;
return acpi_get_handle(device->handle, "_DCK", &tmp);
}
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, struct acpi_device *parent, acpi_handle handle,
int type) int type)
...@@ -950,6 +959,7 @@ static void acpi_device_set_id(struct acpi_device *device, ...@@ -950,6 +959,7 @@ static void acpi_device_set_id(struct acpi_device *device,
char *hid = NULL; char *hid = NULL;
char *uid = NULL; char *uid = NULL;
struct acpi_compatible_id_list *cid_list = NULL; struct acpi_compatible_id_list *cid_list = NULL;
const char *cid_add = NULL;
acpi_status status; acpi_status status;
switch (type) { switch (type) {
...@@ -972,15 +982,18 @@ static void acpi_device_set_id(struct acpi_device *device, ...@@ -972,15 +982,18 @@ static void acpi_device_set_id(struct acpi_device *device,
device->flags.bus_address = 1; device->flags.bus_address = 1;
} }
if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){ /* If we have a video/bay/dock device, add our selfdefined
status = acpi_video_bus_match(device); HID to the CID list. Like that the video/bay/dock drivers
if(ACPI_SUCCESS(status)) will get autoloaded and the device might still match
hid = ACPI_VIDEO_HID; against another driver.
*/
if (ACPI_SUCCESS(acpi_video_bus_match(device)))
cid_add = ACPI_VIDEO_HID;
else if (ACPI_SUCCESS(acpi_bay_match(device)))
cid_add = ACPI_BAY_HID;
else if (ACPI_SUCCESS(acpi_dock_match(device)))
cid_add = ACPI_DOCK_HID;
status = acpi_bay_match(device);
if (ACPI_SUCCESS(status))
hid = ACPI_BAY_HID;
}
break; break;
case ACPI_BUS_TYPE_POWER: case ACPI_BUS_TYPE_POWER:
hid = ACPI_POWER_HID; hid = ACPI_POWER_HID;
...@@ -1021,11 +1034,44 @@ static void acpi_device_set_id(struct acpi_device *device, ...@@ -1021,11 +1034,44 @@ static void acpi_device_set_id(struct acpi_device *device,
strcpy(device->pnp.unique_id, uid); strcpy(device->pnp.unique_id, uid);
device->flags.unique_id = 1; device->flags.unique_id = 1;
} }
if (cid_list) { if (cid_list || cid_add) {
device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); struct acpi_compatible_id_list *list;
if (device->pnp.cid_list) int size = 0;
memcpy(device->pnp.cid_list, cid_list, cid_list->size); int count = 0;
else
if (cid_list) {
size = cid_list->size;
} else if (cid_add) {
size = sizeof(struct acpi_compatible_id_list);
cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
if (!cid_list) {
printk(KERN_ERR "Memory allocation error\n");
kfree(buffer.pointer);
return;
} else {
cid_list->count = 0;
cid_list->size = size;
}
}
if (cid_add)
size += sizeof(struct acpi_compatible_id);
list = kmalloc(size, GFP_KERNEL);
if (list) {
if (cid_list) {
memcpy(list, cid_list, cid_list->size);
count = cid_list->count;
}
if (cid_add) {
strncpy(list->id[count].value, cid_add,
ACPI_MAX_CID_LENGTH);
count++;
device->flags.compatible_ids = 1;
}
list->size = size;
list->count = count;
device->pnp.cid_list = list;
} else
printk(KERN_ERR "Memory allocation error\n"); printk(KERN_ERR "Memory allocation error\n");
} }
...@@ -1080,6 +1126,20 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) ...@@ -1080,6 +1126,20 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
return 0; return 0;
} }
static int
acpi_is_child_device(struct acpi_device *device,
int (*matcher)(struct acpi_device *))
{
int result = -ENODEV;
do {
if (ACPI_SUCCESS(matcher(device)))
return AE_OK;
} while ((device = device->parent));
return result;
}
static int static int
acpi_add_single_object(struct acpi_device **child, 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,
...@@ -1131,10 +1191,20 @@ acpi_add_single_object(struct acpi_device **child, ...@@ -1131,10 +1191,20 @@ acpi_add_single_object(struct acpi_device **child,
case ACPI_BUS_TYPE_PROCESSOR: case ACPI_BUS_TYPE_PROCESSOR:
case ACPI_BUS_TYPE_DEVICE: case ACPI_BUS_TYPE_DEVICE:
result = acpi_bus_get_status(device); result = acpi_bus_get_status(device);
if (ACPI_FAILURE(result) || !device->status.present) { if (ACPI_FAILURE(result)) {
result = -ENOENT; result = -ENODEV;
goto end; goto end;
} }
if (!device->status.present) {
/* Bay and dock should be handled even if absent */
if (!ACPI_SUCCESS(
acpi_is_child_device(device, acpi_bay_match)) &&
!ACPI_SUCCESS(
acpi_is_child_device(device, acpi_dock_match))) {
result = -ENODEV;
goto end;
}
}
break; break;
default: default:
STRUCT_TO_INT(device->status) = STRUCT_TO_INT(device->status) =
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#define ACPI_BUTTON_HID_SLEEPF "LNXSLPBN" #define ACPI_BUTTON_HID_SLEEPF "LNXSLPBN"
#define ACPI_VIDEO_HID "LNXVIDEO" #define ACPI_VIDEO_HID "LNXVIDEO"
#define ACPI_BAY_HID "LNXIOBAY" #define ACPI_BAY_HID "LNXIOBAY"
#define ACPI_DOCK_HID "LNXDOCK"
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
PCI PCI
......
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