| commit 420a0f66378c84b00b0e603e4d38210102dbe367 |
| Author: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Date: Sat Sep 18 10:11:09 2010 -0700 |
| |
| PNPACPI: cope with invalid device IDs |
| |
| If primary ID (HID) is invalid try locating first valid ID on compatible |
| ID list before giving up. |
| |
| This helps, for example, to recognize i8042 AUX port on Sony Vaio VPCZ1 |
| which uses SNYSYN0003 as HID. Without the patch users are forced to |
| boot with i8042.nopnp to make use of their touchpads. |
| |
| Tested-by: Jan-Hendrik Zab <jan@jhz.name> |
| Signed-off-by: Dmitry Torokhov <dtor@mail.ru> |
| Signed-off-by: Len Brown <len.brown@intel.com> |
| |
| diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c |
| index dc4e32e..0d943ee 100644 |
| |
| |
| @@ -28,7 +28,7 @@ |
| #include "../base.h" |
| #include "pnpacpi.h" |
| |
| -static int num = 0; |
| +static int num; |
| |
| /* We need only to blacklist devices that have already an acpi driver that |
| * can't use pnp layer. We don't need to blacklist device that are directly |
| @@ -180,11 +180,24 @@ struct pnp_protocol pnpacpi_protocol = { |
| }; |
| EXPORT_SYMBOL(pnpacpi_protocol); |
| |
| +static char *pnpacpi_get_id(struct acpi_device *device) |
| +{ |
| + struct acpi_hardware_id *id; |
| + |
| + list_for_each_entry(id, &device->pnp.ids, list) { |
| + if (ispnpidacpi(id->id)) |
| + return id->id; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| static int __init pnpacpi_add_device(struct acpi_device *device) |
| { |
| acpi_handle temp = NULL; |
| acpi_status status; |
| struct pnp_dev *dev; |
| + char *pnpid; |
| struct acpi_hardware_id *id; |
| |
| /* |
| @@ -192,11 +205,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device) |
| * driver should not be loaded. |
| */ |
| status = acpi_get_handle(device->handle, "_CRS", &temp); |
| - if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || |
| - is_exclusive_device(device) || (!device->status.present)) |
| + if (ACPI_FAILURE(status)) |
| + return 0; |
| + |
| + pnpid = pnpacpi_get_id(device); |
| + if (!pnpid) |
| + return 0; |
| + |
| + if (is_exclusive_device(device) || !device->status.present) |
| return 0; |
| |
| - dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); |
| + dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid); |
| if (!dev) |
| return -ENOMEM; |
| |
| @@ -227,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) |
| pnpacpi_parse_resource_option_data(dev); |
| |
| list_for_each_entry(id, &device->pnp.ids, list) { |
| - if (!strcmp(id->id, acpi_device_hid(device))) |
| + if (!strcmp(id->id, pnpid)) |
| continue; |
| if (!ispnpidacpi(id->id)) |
| continue; |