aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-09-18 13:11:09 -0400
committerLen Brown <len.brown@intel.com>2010-10-01 02:08:59 -0400
commit420a0f66378c84b00b0e603e4d38210102dbe367 (patch)
tree2452b35b42dc10f21533d2c3d01ea12b9f95d21a
parent899611ee7d373e5eeda08e9a8632684e1ebbbf00 (diff)
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>
-rw-r--r--drivers/pnp/pnpacpi/core.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index dc4e32e031e9..0d943eea1c2d 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -28,7 +28,7 @@
28#include "../base.h" 28#include "../base.h"
29#include "pnpacpi.h" 29#include "pnpacpi.h"
30 30
31static int num = 0; 31static int num;
32 32
33/* We need only to blacklist devices that have already an acpi driver that 33/* We need only to blacklist devices that have already an acpi driver that
34 * can't use pnp layer. We don't need to blacklist device that are directly 34 * can't use pnp layer. We don't need to blacklist device that are directly
@@ -180,11 +180,24 @@ struct pnp_protocol pnpacpi_protocol = {
180}; 180};
181EXPORT_SYMBOL(pnpacpi_protocol); 181EXPORT_SYMBOL(pnpacpi_protocol);
182 182
183static char *pnpacpi_get_id(struct acpi_device *device)
184{
185 struct acpi_hardware_id *id;
186
187 list_for_each_entry(id, &device->pnp.ids, list) {
188 if (ispnpidacpi(id->id))
189 return id->id;
190 }
191
192 return NULL;
193}
194
183static int __init pnpacpi_add_device(struct acpi_device *device) 195static int __init pnpacpi_add_device(struct acpi_device *device)
184{ 196{
185 acpi_handle temp = NULL; 197 acpi_handle temp = NULL;
186 acpi_status status; 198 acpi_status status;
187 struct pnp_dev *dev; 199 struct pnp_dev *dev;
200 char *pnpid;
188 struct acpi_hardware_id *id; 201 struct acpi_hardware_id *id;
189 202
190 /* 203 /*
@@ -192,11 +205,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
192 * driver should not be loaded. 205 * driver should not be loaded.
193 */ 206 */
194 status = acpi_get_handle(device->handle, "_CRS", &temp); 207 status = acpi_get_handle(device->handle, "_CRS", &temp);
195 if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || 208 if (ACPI_FAILURE(status))
196 is_exclusive_device(device) || (!device->status.present)) 209 return 0;
210
211 pnpid = pnpacpi_get_id(device);
212 if (!pnpid)
213 return 0;
214
215 if (is_exclusive_device(device) || !device->status.present)
197 return 0; 216 return 0;
198 217
199 dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); 218 dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid);
200 if (!dev) 219 if (!dev)
201 return -ENOMEM; 220 return -ENOMEM;
202 221
@@ -227,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
227 pnpacpi_parse_resource_option_data(dev); 246 pnpacpi_parse_resource_option_data(dev);
228 247
229 list_for_each_entry(id, &device->pnp.ids, list) { 248 list_for_each_entry(id, &device->pnp.ids, list) {
230 if (!strcmp(id->id, acpi_device_hid(device))) 249 if (!strcmp(id->id, pnpid))
231 continue; 250 continue;
232 if (!ispnpidacpi(id->id)) 251 if (!ispnpidacpi(id->id))
233 continue; 252 continue;