diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index fc1f339b7431..dcb34a5f5669 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -63,7 +63,7 @@ struct guid_block {
 struct wmi_block {
 	struct list_head list;
 	struct guid_block gblock;
-	acpi_handle handle;
+	struct acpi_device *acpi_device;
 	wmi_notify_handler handler;
 	void *handler_data;
 	struct device dev;
@@ -225,7 +225,7 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
 	acpi_handle handle;
 
 	block = &wblock->gblock;
-	handle = wblock->handle;
+	handle = wblock->acpi_device->handle;
 
 	snprintf(method, 5, "WE%02X", block->notify_id);
 	status = acpi_execute_simple_method(handle, method, enable);
@@ -264,7 +264,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
 		return AE_ERROR;
 
 	block = &wblock->gblock;
-	handle = wblock->handle;
+	handle = wblock->acpi_device->handle;
 
 	if (!(block->flags & ACPI_WMI_METHOD))
 		return AE_BAD_DATA;
@@ -326,7 +326,7 @@ struct acpi_buffer *out)
 		return AE_ERROR;
 
 	block = &wblock->gblock;
-	handle = wblock->handle;
+	handle = wblock->acpi_device->handle;
 
 	if (block->instance_count < instance)
 		return AE_BAD_PARAMETER;
@@ -399,7 +399,7 @@ const struct acpi_buffer *in)
 		return AE_ERROR;
 
 	block = &wblock->gblock;
-	handle = wblock->handle;
+	handle = wblock->acpi_device->handle;
 
 	if (block->instance_count < instance)
 		return AE_BAD_PARAMETER;
@@ -603,8 +603,8 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
 
 		if ((gblock->flags & ACPI_WMI_EVENT) &&
 			(gblock->notify_id == event))
-			return acpi_evaluate_object(wblock->handle, "_WED",
-				&input, out);
+			return acpi_evaluate_object(wblock->acpi_device->handle,
+				"_WED", &input, out);
 	}
 
 	return AE_NOT_FOUND;
@@ -696,27 +696,40 @@ static int wmi_create_device(const struct guid_block *gblock,
 	return device_register(&wblock->dev);
 }
 
-static void wmi_free_devices(void)
+static void wmi_free_devices(struct acpi_device *device)
 {
 	struct wmi_block *wblock, *next;
 
 	/* Delete devices for all the GUIDs */
 	list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
-		list_del(&wblock->list);
-		if (wblock->dev.class)
-			device_unregister(&wblock->dev);
-		else
-			kfree(wblock);
+		if (wblock->acpi_device == device) {
+			list_del(&wblock->list);
+			if (wblock->dev.class)
+				device_unregister(&wblock->dev);
+			else
+				kfree(wblock);
+		}
 	}
 }
 
-static bool guid_already_parsed(const char *guid_string)
+static bool guid_already_parsed(struct acpi_device *device,
+				const u8 *guid)
 {
 	struct wmi_block *wblock;
 
-	list_for_each_entry(wblock, &wmi_block_list, list)
-		if (memcmp(wblock->gblock.guid, guid_string, 16) == 0)
+	list_for_each_entry(wblock, &wmi_block_list, list) {
+		if (memcmp(wblock->gblock.guid, guid, 16) == 0) {
+			/*
+			 * Because we historically didn't track the relationship
+			 * between GUIDs and ACPI nodes, we don't know whether
+			 * we need to suppress GUIDs that are unique on a
+			 * given node but duplicated across nodes.
+			 */
+			dev_warn(&device->dev, "duplicate WMI GUID %pUL (first instance was on %s)\n",
+				 guid, dev_name(&wblock->acpi_device->dev));
 			return true;
+		}
+	}
 
 	return false;
 }
@@ -758,7 +771,7 @@ static int parse_wdg(struct acpi_device *device)
 		if (!wblock)
 			return -ENOMEM;
 
-		wblock->handle = device->handle;
+		wblock->acpi_device = device;
 		wblock->gblock = gblock[i];
 
 		/*
@@ -767,10 +780,10 @@ static int parse_wdg(struct acpi_device *device)
 		  case yet, so for now, we'll just ignore the duplicate
 		  for device creation.
 		*/
-		if (!guid_already_parsed(gblock[i].guid)) {
+		if (!guid_already_parsed(device, gblock[i].guid)) {
 			retval = wmi_create_device(&gblock[i], wblock, device);
 			if (retval) {
-				wmi_free_devices();
+				wmi_free_devices(device);
 				goto out_free_pointer;
 			}
 		}
@@ -845,8 +858,9 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
 		wblock = list_entry(p, struct wmi_block, list);
 		block = &wblock->gblock;
 
-		if ((block->flags & ACPI_WMI_EVENT) &&
-			(block->notify_id == event)) {
+		if (wblock->acpi_device == device &&
+		    (block->flags & ACPI_WMI_EVENT) &&
+		    (block->notify_id == event)) {
 			if (wblock->handler)
 				wblock->handler(event, wblock->handler_data);
 			if (debug_event) {
@@ -866,7 +880,7 @@ static int acpi_wmi_remove(struct acpi_device *device)
 {
 	acpi_remove_address_space_handler(device->handle,
 				ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
-	wmi_free_devices();
+	wmi_free_devices(device);
 
 	return 0;
 }
