summaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/wmi.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-22 16:20:34 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-22 16:20:34 -0800
commitd02e30c31c57683a66ed68a1bcff900ca78f6d56 (patch)
treec3ce99a00061bcc1199b50fa838147d876c56717 /drivers/platform/x86/wmi.c
parent0fdc7a8022c3eaff6b5ee27ffb9e913e5e58d8e9 (diff)
parentaef55d4922e62a0d887e60d87319f3718aec6ced (diff)
Merge branch 'x86/irq' into x86/apic
Merge reason: Conflicts in arch/x86/kernel/apic/io_apic.c Resolved Conflicts: arch/x86/kernel/apic/io_apic.c Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'drivers/platform/x86/wmi.c')
-rw-r--r--drivers/platform/x86/wmi.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 9f93d6c0f51..b104302fea0 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data)
if (!guid || !handler)
return AE_BAD_PARAMETER;
- find_guid(guid, &block);
- if (!block)
+ if (!find_guid(guid, &block))
return AE_NOT_EXIST;
if (block->handler)
@@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid)
if (!guid)
return AE_BAD_PARAMETER;
- find_guid(guid, &block);
- if (!block)
+ if (!find_guid(guid, &block))
return AE_NOT_EXIST;
if (!block->handler)
@@ -716,6 +714,22 @@ static int wmi_class_init(void)
return ret;
}
+static bool guid_already_parsed(const char *guid_string)
+{
+ struct guid_block *gblock;
+ struct wmi_block *wblock;
+ struct list_head *p;
+
+ list_for_each(p, &wmi_blocks.list) {
+ wblock = list_entry(p, struct wmi_block, list);
+ gblock = &wblock->gblock;
+
+ if (strncmp(gblock->guid, guid_string, 16) == 0)
+ return true;
+ }
+ return false;
+}
+
/*
* Parse the _WDG method for the GUID data blocks
*/
@@ -725,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle)
union acpi_object *obj;
struct guid_block *gblock;
struct wmi_block *wblock;
+ char guid_string[37];
acpi_status status;
u32 i, total;
@@ -747,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle)
memcpy(gblock, obj->buffer.pointer, obj->buffer.length);
for (i = 0; i < total; i++) {
+ /*
+ Some WMI devices, like those for nVidia hooks, have a
+ duplicate GUID. It's not clear what we should do in this
+ case yet, so for now, we'll just ignore the duplicate.
+ Anyone who wants to add support for that device can come
+ up with a better workaround for the mess then.
+ */
+ if (guid_already_parsed(gblock[i].guid) == true) {
+ wmi_gtoa(gblock[i].guid, guid_string);
+ printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n",
+ guid_string);
+ continue;
+ }
wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
if (!wblock)
return AE_NO_MEMORY;