--- /dev/null
+From 202a861205905629c5f10ce0a8358623485e1ae9 Mon Sep 17 00:00:00 2001
+From: Kurt Borja <kuurtb@gmail.com>
+Date: Fri, 11 Apr 2025 11:14:36 -0300
+Subject: platform/x86: alienware-wmi-wmax: Extend support to more laptops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kurt Borja <kuurtb@gmail.com>
+
+commit 202a861205905629c5f10ce0a8358623485e1ae9 upstream.
+
+Extend thermal control support to:
+
+ - Alienware Area-51m R2
+ - Alienware m16 R1
+ - Alienware m16 R2
+ - Dell G16 7630
+ - Dell G5 5505 SE
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Kurt Borja <kuurtb@gmail.com>
+Link: https://lore.kernel.org/r/20250411-awcc-support-v1-2-09a130ec4560@gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/dell/alienware-wmi.c | 54 ++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/drivers/platform/x86/dell/alienware-wmi.c
++++ b/drivers/platform/x86/dell/alienware-wmi.c
+@@ -216,6 +216,15 @@ static int __init dmi_matched(const stru
+ static const struct dmi_system_id alienware_quirks[] __initconst = {
+ {
+ .callback = dmi_matched,
++ .ident = "Alienware Area-51m R2",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"),
++ },
++ .driver_data = &quirk_x_series,
++ },
++ {
++ .callback = dmi_matched,
+ .ident = "Alienware ASM100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+@@ -243,6 +252,15 @@ static const struct dmi_system_id alienw
+ },
+ {
+ .callback = dmi_matched,
++ .ident = "Alienware m16 R1",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1"),
++ },
++ .driver_data = &quirk_g_series,
++ },
++ {
++ .callback = dmi_matched,
+ .ident = "Alienware m16 R1 AMD",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+@@ -261,6 +279,15 @@ static const struct dmi_system_id alienw
+ },
+ {
+ .callback = dmi_matched,
++ .ident = "Alienware m16 R2",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R2"),
++ },
++ .driver_data = &quirk_x_series,
++ },
++ {
++ .callback = dmi_matched,
+ .ident = "Alienware m18 R2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+@@ -279,6 +306,15 @@ static const struct dmi_system_id alienw
+ },
+ {
+ .callback = dmi_matched,
++ .ident = "Alienware x15 R2",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"),
++ },
++ .driver_data = &quirk_x_series,
++ },
++ {
++ .callback = dmi_matched,
+ .ident = "Alienware x17 R2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+@@ -342,6 +378,15 @@ static const struct dmi_system_id alienw
+ },
+ {
+ .callback = dmi_matched,
++ .ident = "Dell Inc. G16 7630",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"),
++ },
++ .driver_data = &quirk_g_series,
++ },
++ {
++ .callback = dmi_matched,
+ .ident = "Dell Inc. G3 3500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+@@ -367,6 +412,15 @@ static const struct dmi_system_id alienw
+ },
+ .driver_data = &quirk_g_series,
+ },
++ {
++ .callback = dmi_matched,
++ .ident = "Dell Inc. G5 5505",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"),
++ },
++ .driver_data = &quirk_g_series,
++ },
+ {
+ .callback = dmi_matched,
+ .ident = "Dell Inc. Inspiron 5675",
--- /dev/null
+From baf2f2c2b4c8e1d398173acd4d2fa9131a86b84e Mon Sep 17 00:00:00 2001
+From: Armin Wolf <W_Armin@gmx.de>
+Date: Mon, 14 Apr 2025 16:04:53 +0200
+Subject: platform/x86: msi-wmi-platform: Workaround a ACPI firmware bug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+commit baf2f2c2b4c8e1d398173acd4d2fa9131a86b84e upstream.
+
+The ACPI byte code inside the ACPI control method responsible for
+handling the WMI method calls uses a global buffer for constructing
+the return value, yet the ACPI control method itself is not marked
+as "Serialized".
+This means that calling WMI methods on this WMI device is not
+thread-safe, as concurrent WMI method calls will corrupt the global
+buffer.
+
+Fix this by serializing the WMI method calls using a mutex.
+
+Cc: stable@vger.kernel.org # 6.x.x: 912d614ac99e: platform/x86: msi-wmi-platform: Rename "data" variable
+Fixes: 9c0beb6b29e7 ("platform/x86: wmi: Add MSI WMI Platform driver")
+Tested-by: Antheas Kapenekakis <lkml@antheas.dev>
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20250414140453.7691-2-W_Armin@gmx.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/wmi/devices/msi-wmi-platform.rst | 4 +
+ drivers/platform/x86/msi-wmi-platform.c | 91 ++++++++++++++++---------
+ 2 files changed, 63 insertions(+), 32 deletions(-)
+
+--- a/Documentation/wmi/devices/msi-wmi-platform.rst
++++ b/Documentation/wmi/devices/msi-wmi-platform.rst
+@@ -138,6 +138,10 @@ input data, the meaning of which depends
+ The output buffer contains a single byte which signals success or failure (``0x00`` on failure)
+ and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.
+
++.. note::
++ The ACPI control method responsible for handling the WMI method calls is not thread-safe.
++ This is a firmware bug that needs to be handled inside the driver itself.
++
+ WMI method Get_EC()
+ -------------------
+
+--- a/drivers/platform/x86/msi-wmi-platform.c
++++ b/drivers/platform/x86/msi-wmi-platform.c
+@@ -10,6 +10,7 @@
+ #include <linux/acpi.h>
+ #include <linux/bits.h>
+ #include <linux/bitfield.h>
++#include <linux/cleanup.h>
+ #include <linux/debugfs.h>
+ #include <linux/device.h>
+ #include <linux/device/driver.h>
+@@ -17,6 +18,7 @@
+ #include <linux/hwmon.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/mutex.h>
+ #include <linux/printk.h>
+ #include <linux/rwsem.h>
+ #include <linux/types.h>
+@@ -76,8 +78,13 @@ enum msi_wmi_platform_method {
+ MSI_PLATFORM_GET_WMI = 0x1d,
+ };
+
+-struct msi_wmi_platform_debugfs_data {
++struct msi_wmi_platform_data {
+ struct wmi_device *wdev;
++ struct mutex wmi_lock; /* Necessary when calling WMI methods */
++};
++
++struct msi_wmi_platform_debugfs_data {
++ struct msi_wmi_platform_data *data;
+ enum msi_wmi_platform_method method;
+ struct rw_semaphore buffer_lock; /* Protects debugfs buffer */
+ size_t length;
+@@ -132,8 +139,9 @@ static int msi_wmi_platform_parse_buffer
+ return 0;
+ }
+
+-static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform_method method,
+- u8 *input, size_t input_length, u8 *output, size_t output_length)
++static int msi_wmi_platform_query(struct msi_wmi_platform_data *data,
++ enum msi_wmi_platform_method method, u8 *input,
++ size_t input_length, u8 *output, size_t output_length)
+ {
+ struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer in = {
+@@ -147,9 +155,15 @@ static int msi_wmi_platform_query(struct
+ if (!input_length || !output_length)
+ return -EINVAL;
+
+- status = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
+- if (ACPI_FAILURE(status))
+- return -EIO;
++ /*
++ * The ACPI control method responsible for handling the WMI method calls
++ * is not thread-safe. Because of this we have to do the locking ourself.
++ */
++ scoped_guard(mutex, &data->wmi_lock) {
++ status = wmidev_evaluate_method(data->wdev, 0x0, method, &in, &out);
++ if (ACPI_FAILURE(status))
++ return -EIO;
++ }
+
+ obj = out.pointer;
+ if (!obj)
+@@ -170,13 +184,13 @@ static umode_t msi_wmi_platform_is_visib
+ static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+ int channel, long *val)
+ {
+- struct wmi_device *wdev = dev_get_drvdata(dev);
++ struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+ u8 input[32] = { 0 };
+ u8 output[32];
+ u16 value;
+ int ret;
+
+- ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,
++ ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,
+ sizeof(output));
+ if (ret < 0)
+ return ret;
+@@ -231,7 +245,7 @@ static ssize_t msi_wmi_platform_write(st
+ return ret;
+
+ down_write(&data->buffer_lock);
+- ret = msi_wmi_platform_query(data->wdev, data->method, payload, data->length, data->buffer,
++ ret = msi_wmi_platform_query(data->data, data->method, payload, data->length, data->buffer,
+ data->length);
+ up_write(&data->buffer_lock);
+
+@@ -277,17 +291,17 @@ static void msi_wmi_platform_debugfs_rem
+ debugfs_remove_recursive(dir);
+ }
+
+-static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry *dir,
++static void msi_wmi_platform_debugfs_add(struct msi_wmi_platform_data *drvdata, struct dentry *dir,
+ const char *name, enum msi_wmi_platform_method method)
+ {
+ struct msi_wmi_platform_debugfs_data *data;
+ struct dentry *entry;
+
+- data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
++ data = devm_kzalloc(&drvdata->wdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return;
+
+- data->wdev = wdev;
++ data->data = drvdata;
+ data->method = method;
+ init_rwsem(&data->buffer_lock);
+
+@@ -298,82 +312,82 @@ static void msi_wmi_platform_debugfs_add
+
+ entry = debugfs_create_file(name, 0600, dir, data, &msi_wmi_platform_debugfs_fops);
+ if (IS_ERR(entry))
+- devm_kfree(&wdev->dev, data);
++ devm_kfree(&drvdata->wdev->dev, data);
+ }
+
+-static void msi_wmi_platform_debugfs_init(struct wmi_device *wdev)
++static void msi_wmi_platform_debugfs_init(struct msi_wmi_platform_data *data)
+ {
+ struct dentry *dir;
+ char dir_name[64];
+ int ret, method;
+
+- scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
++ scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&data->wdev->dev));
+
+ dir = debugfs_create_dir(dir_name, NULL);
+ if (IS_ERR(dir))
+ return;
+
+- ret = devm_add_action_or_reset(&wdev->dev, msi_wmi_platform_debugfs_remove, dir);
++ ret = devm_add_action_or_reset(&data->wdev->dev, msi_wmi_platform_debugfs_remove, dir);
+ if (ret < 0)
+ return;
+
+ for (method = MSI_PLATFORM_GET_PACKAGE; method <= MSI_PLATFORM_GET_WMI; method++)
+- msi_wmi_platform_debugfs_add(wdev, dir, msi_wmi_platform_debugfs_names[method - 1],
++ msi_wmi_platform_debugfs_add(data, dir, msi_wmi_platform_debugfs_names[method - 1],
+ method);
+ }
+
+-static int msi_wmi_platform_hwmon_init(struct wmi_device *wdev)
++static int msi_wmi_platform_hwmon_init(struct msi_wmi_platform_data *data)
+ {
+ struct device *hdev;
+
+- hdev = devm_hwmon_device_register_with_info(&wdev->dev, "msi_wmi_platform", wdev,
++ hdev = devm_hwmon_device_register_with_info(&data->wdev->dev, "msi_wmi_platform", data,
+ &msi_wmi_platform_chip_info, NULL);
+
+ return PTR_ERR_OR_ZERO(hdev);
+ }
+
+-static int msi_wmi_platform_ec_init(struct wmi_device *wdev)
++static int msi_wmi_platform_ec_init(struct msi_wmi_platform_data *data)
+ {
+ u8 input[32] = { 0 };
+ u8 output[32];
+ u8 flags;
+ int ret;
+
+- ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_EC, input, sizeof(input), output,
++ ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_EC, input, sizeof(input), output,
+ sizeof(output));
+ if (ret < 0)
+ return ret;
+
+ flags = output[MSI_PLATFORM_EC_FLAGS_OFFSET];
+
+- dev_dbg(&wdev->dev, "EC RAM version %lu.%lu\n",
++ dev_dbg(&data->wdev->dev, "EC RAM version %lu.%lu\n",
+ FIELD_GET(MSI_PLATFORM_EC_MAJOR_MASK, flags),
+ FIELD_GET(MSI_PLATFORM_EC_MINOR_MASK, flags));
+- dev_dbg(&wdev->dev, "EC firmware version %.28s\n",
++ dev_dbg(&data->wdev->dev, "EC firmware version %.28s\n",
+ &output[MSI_PLATFORM_EC_VERSION_OFFSET]);
+
+ if (!(flags & MSI_PLATFORM_EC_IS_TIGERLAKE)) {
+ if (!force)
+ return -ENODEV;
+
+- dev_warn(&wdev->dev, "Loading on a non-Tigerlake platform\n");
++ dev_warn(&data->wdev->dev, "Loading on a non-Tigerlake platform\n");
+ }
+
+ return 0;
+ }
+
+-static int msi_wmi_platform_init(struct wmi_device *wdev)
++static int msi_wmi_platform_init(struct msi_wmi_platform_data *data)
+ {
+ u8 input[32] = { 0 };
+ u8 output[32];
+ int ret;
+
+- ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,
++ ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,
+ sizeof(output));
+ if (ret < 0)
+ return ret;
+
+- dev_dbg(&wdev->dev, "WMI interface version %u.%u\n",
++ dev_dbg(&data->wdev->dev, "WMI interface version %u.%u\n",
+ output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
+ output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
+
+@@ -381,7 +395,8 @@ static int msi_wmi_platform_init(struct
+ if (!force)
+ return -ENODEV;
+
+- dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u.%u)\n",
++ dev_warn(&data->wdev->dev,
++ "Loading despite unsupported WMI interface version (%u.%u)\n",
+ output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
+ output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
+ }
+@@ -391,19 +406,31 @@ static int msi_wmi_platform_init(struct
+
+ static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context)
+ {
++ struct msi_wmi_platform_data *data;
+ int ret;
+
+- ret = msi_wmi_platform_init(wdev);
++ data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->wdev = wdev;
++ dev_set_drvdata(&wdev->dev, data);
++
++ ret = devm_mutex_init(&wdev->dev, &data->wmi_lock);
++ if (ret < 0)
++ return ret;
++
++ ret = msi_wmi_platform_init(data);
+ if (ret < 0)
+ return ret;
+
+- ret = msi_wmi_platform_ec_init(wdev);
++ ret = msi_wmi_platform_ec_init(data);
+ if (ret < 0)
+ return ret;
+
+- msi_wmi_platform_debugfs_init(wdev);
++ msi_wmi_platform_debugfs_init(data);
+
+- return msi_wmi_platform_hwmon_init(wdev);
++ return msi_wmi_platform_hwmon_init(data);
+ }
+
+ static const struct wmi_device_id msi_wmi_platform_id_table[] = {