#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
-#include <linux/wmi.h>
 
 #include "nct6775.h"
 
        void (*sio_exit)(struct nct6775_sio_data *sio_data);
 };
 
-#define ASUSWMI_MONITORING_GUID                "466747A0-70EC-11DE-8A39-0800200C9A66"
+#define ASUSWMI_METHOD                 "WMBD"
 #define ASUSWMI_METHODID_RSIO          0x5253494F
 #define ASUSWMI_METHODID_WSIO          0x5753494F
 #define ASUSWMI_METHODID_RHWM          0x5248574D
 #define ASUSWMI_METHODID_WHWM          0x5748574D
 #define ASUSWMI_UNSUPPORTED_METHOD     0xFFFFFFFE
+#define ASUSWMI_DEVICE_HID             "PNP0C14"
+#define ASUSWMI_DEVICE_UID             "ASUSWMI"
+
+#if IS_ENABLED(CONFIG_ACPI)
+/*
+ * ASUS boards have only one device with WMI "WMBD" method and have provided
+ * access to only one SuperIO chip at 0x0290.
+ */
+static struct acpi_device *asus_acpi_dev;
+#endif
 
 static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
 {
-#if IS_ENABLED(CONFIG_ACPI_WMI)
+#if IS_ENABLED(CONFIG_ACPI)
+       acpi_handle handle = acpi_device_handle(asus_acpi_dev);
        u32 args = bank | (reg << 8) | (val << 16);
-       struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
-       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_object_list input;
+       union acpi_object params[3];
+       unsigned long long result;
        acpi_status status;
-       union acpi_object *obj;
-       u32 tmp = ASUSWMI_UNSUPPORTED_METHOD;
-
-       status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0,
-                                    method_id, &input, &output);
 
+       params[0].type = ACPI_TYPE_INTEGER;
+       params[0].integer.value = 0;
+       params[1].type = ACPI_TYPE_INTEGER;
+       params[1].integer.value = method_id;
+       params[2].type = ACPI_TYPE_BUFFER;
+       params[2].buffer.length = sizeof(args);
+       params[2].buffer.pointer = (void *)&args;
+       input.count = 3;
+       input.pointer = params;
+
+       status = acpi_evaluate_integer(handle, ASUSWMI_METHOD, &input, &result);
        if (ACPI_FAILURE(status))
                return -EIO;
 
-       obj = output.pointer;
-       if (obj && obj->type == ACPI_TYPE_INTEGER)
-               tmp = obj->integer.value;
-
        if (retval)
-               *retval = tmp;
+               *retval = (u32)result & 0xFFFFFFFF;
 
-       kfree(obj);
-
-       if (tmp == ASUSWMI_UNSUPPORTED_METHOD)
-               return -ENODEV;
        return 0;
 #else
        return -EOPNOTSUPP;
        "TUF GAMING Z490-PLUS (WI-FI)",
 };
 
+#if IS_ENABLED(CONFIG_ACPI)
+/*
+ * Callback for acpi_bus_for_each_dev() to find the right device
+ * by _UID and _HID and return 1 to stop iteration.
+ */
+static int nct6775_asuswmi_device_match(struct device *dev, void *data)
+{
+       struct acpi_device *adev = to_acpi_device(dev);
+       const char *uid = acpi_device_uid(adev);
+       const char *hid = acpi_device_hid(adev);
+
+       if (hid && !strcmp(hid, ASUSWMI_DEVICE_HID) && uid && !strcmp(uid, data)) {
+               asus_acpi_dev = adev;
+               return 1;
+       }
+
+       return 0;
+}
+#endif
+
+static enum sensor_access nct6775_determine_access(const char *device_uid)
+{
+#if IS_ENABLED(CONFIG_ACPI)
+       u8 tmp;
+
+       acpi_bus_for_each_dev(nct6775_asuswmi_device_match, (void *)device_uid);
+       if (!asus_acpi_dev)
+               return access_direct;
+
+       /* if reading chip id via ACPI succeeds, use WMI "WMBD" method for access */
+       if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
+               pr_debug("Using Asus WMBD method of %s to access %#x chip.\n", device_uid, tmp);
+               return access_asuswmi;
+       }
+#endif
+
+       return access_direct;
+}
+
 static int __init sensors_nct6775_platform_init(void)
 {
        int i, err;
        int sioaddr[2] = { 0x2e, 0x4e };
        enum sensor_access access = access_direct;
        const char *board_vendor, *board_name;
-       u8 tmp;
 
        err = platform_driver_register(&nct6775_driver);
        if (err)
            !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
                err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards),
                                   board_name);
-               if (err >= 0) {
-                       /* if reading chip id via WMI succeeds, use WMI */
-                       if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
-                               pr_info("Using Asus WMI to access %#x chip.\n", tmp);
-                               access = access_asuswmi;
-                       } else {
-                               pr_err("Can't read ChipID by Asus WMI.\n");
-                       }
-               }
+               if (err >= 0)
+                       access = nct6775_determine_access(ASUSWMI_DEVICE_UID);
        }
 
        /*