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