lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250511204427.327558-5-lkml@antheas.dev>
Date: Sun, 11 May 2025 22:44:21 +0200
From: Antheas Kapenekakis <lkml@...heas.dev>
To: platform-driver-x86@...r.kernel.org
Cc: Armin Wolf <W_Armin@....de>,
	Jonathan Corbet <corbet@....net>,
	Hans de Goede <hdegoede@...hat.com>,
	Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>,
	Jean Delvare <jdelvare@...e.com>,
	Guenter Roeck <linux@...ck-us.net>,
	Kurt Borja <kuurtb@...il.com>,
	linux-doc@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-hwmon@...r.kernel.org,
	Antheas Kapenekakis <lkml@...heas.dev>
Subject: [PATCH v1 04/10] platform/x86: msi-wmi-platform: Add support for fan
 control

From: Armin Wolf <W_Armin@....de>

Adds fan curve support for the MSI platform. These devices contain
support for two fans, where they are named CPU and GPU but in the
case of the Claw series just map to left and right fan.

Co-developed-by: Antheas Kapenekakis <lkml@...heas.dev>
Signed-off-by: Antheas Kapenekakis <lkml@...heas.dev>
Signed-off-by: Armin Wolf <W_Armin@....de>
---
 .../wmi/devices/msi-wmi-platform.rst          |  26 ++
 drivers/platform/x86/msi-wmi-platform.c       | 328 +++++++++++++++++-
 2 files changed, 337 insertions(+), 17 deletions(-)

diff --git a/Documentation/wmi/devices/msi-wmi-platform.rst b/Documentation/wmi/devices/msi-wmi-platform.rst
index 73197b31926a5..704bfdac5203e 100644
--- a/Documentation/wmi/devices/msi-wmi-platform.rst
+++ b/Documentation/wmi/devices/msi-wmi-platform.rst
@@ -169,6 +169,32 @@ The fan RPM readings can be calculated with the following formula:
 
 If the fan speed reading is zero, then the fan RPM is zero too.
 
+The subfeature ``0x01`` is used to retrieve the fan speed table for the CPU fan. The output
+data contains the fan speed table and two bytes with unknown data. The fan speed table
+consists of six 8-bit entries, each containing a fan speed value in percent.
+
+The subfeature ``0x02`` is used tho retrieve the same data for the GPU fan.
+
+WMI method Set_Fan()
+--------------------
+
+The fan speed tables can be accessed using subfeature ``0x01`` (CPU fan) and subfeature ``0x02``
+(GPU fan). The input data has the same format as the output data of the ``Get_Fan`` WMI method.
+
+WMI method Get_AP()
+-------------------
+
+The current fan mode can be accessed using subfeature ``0x01``. The output data contains a flag
+byte and two bytes of unknown data. If the 7th bit inside the flag byte is cleared then all fans
+are operating in automatic mode, otherwise the fans operate based on the fan speed tables
+accessible thru the ``Get_Fan``/``Set_Fan`` WMI methods.
+
+WMI method Set_AP()
+-------------------
+
+The current fan mode can be changed using subfeature ``0x01``. The input data has the same format
+as the output data of the ``Get_AP`` WMI method.
+
 WMI method Get_WMI()
 --------------------
 
diff --git a/drivers/platform/x86/msi-wmi-platform.c b/drivers/platform/x86/msi-wmi-platform.c
index 408d42ab19e20..9ac3c6f1b3f1d 100644
--- a/drivers/platform/x86/msi-wmi-platform.c
+++ b/drivers/platform/x86/msi-wmi-platform.c
@@ -16,13 +16,18 @@
 #include <linux/device/driver.h>
 #include <linux/dmi.h>
 #include <linux/errno.h>
+#include <linux/fixp-arith.h>
 #include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
 #include <linux/kernel.h>
+#include <linux/kstrtox.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/printk.h>
 #include <linux/rwsem.h>
 #include <linux/string.h>
+#include <linux/sysfs.h>
 #include <linux/types.h>
 #include <linux/wmi.h>
 
@@ -34,9 +39,11 @@
 
 #define MSI_WMI_PLATFORM_INTERFACE_VERSION	2
 
+/* Get_WMI() WMI method */
 #define MSI_PLATFORM_WMI_MAJOR_OFFSET	1
 #define MSI_PLATFORM_WMI_MINOR_OFFSET	2
 
+/* Get_EC() and Set_EC() WMI methods */
 #define MSI_PLATFORM_EC_FLAGS_OFFSET	1
 #define MSI_PLATFORM_EC_MINOR_MASK	GENMASK(3, 0)
 #define MSI_PLATFORM_EC_MAJOR_MASK	GENMASK(5, 4)
@@ -44,6 +51,18 @@
 #define MSI_PLATFORM_EC_IS_TIGERLAKE	BIT(7)
 #define MSI_PLATFORM_EC_VERSION_OFFSET	2
 
+/* Get_Fan() and Set_Fan() WMI methods */
+#define MSI_PLATFORM_FAN_SUBFEATURE_FAN_SPEED		0x0
+#define MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE	0x1
+#define MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE	0x2
+#define MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE	0x1
+#define MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE	0x2
+
+/* Get_AP() and Set_AP() WMI methods */
+#define MSI_PLATFORM_AP_SUBFEATURE_FAN_MODE	0x1
+#define MSI_PLATFORM_AP_FAN_FLAGS_OFFSET	1
+#define MSI_PLATFORM_AP_ENABLE_FAN_TABLES	BIT(7)
+
 static bool force;
 module_param_unsafe(force, bool, 0);
 MODULE_PARM_DESC(force, "Force loading without checking for supported WMI interface versions");
@@ -221,9 +240,201 @@ static int msi_wmi_platform_query(struct msi_wmi_platform_data *data,
 	}
 }
 
+static ssize_t msi_wmi_platform_fan_table_show(struct device *dev, struct device_attribute *attr,
+					       char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+	u8 buffer[32] = { sattr->nr };
+	u8 fan_percent;
+	int ret;
+
+	ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	fan_percent = buffer[sattr->index + 1];
+	if (fan_percent > 100)
+		return -EIO;
+
+	return sysfs_emit(buf, "%d\n", fixp_linear_interpolate(0, 0, 100, 255, fan_percent));
+}
+
+static ssize_t msi_wmi_platform_fan_table_store(struct device *dev, struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+	u8 buffer[32] = { sattr->nr };
+	long speed;
+	int ret;
+
+	ret = kstrtol(buf, 10, &speed);
+	if (ret < 0)
+		return ret;
+
+	speed = clamp_val(speed, 0, 255);
+
+	guard(mutex)(&data->wmi_lock);
+
+	ret = msi_wmi_platform_query_unlocked(data, MSI_PLATFORM_GET_FAN,
+					      buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	buffer[0] = sattr->nr;
+	buffer[sattr->index + 1] = fixp_linear_interpolate(0, 0, 255, 100, speed);
+
+	ret = msi_wmi_platform_query_unlocked(data, MSI_PLATFORM_SET_FAN,
+					      buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static ssize_t msi_wmi_platform_temp_table_show(struct device *dev, struct device_attribute *attr,
+						char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+	u8 buffer[32] = { sattr->nr };
+	u8 temp_c;
+	int ret;
+
+	ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_TEMPERATURE,
+				     buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	temp_c = buffer[sattr->index + 1];
+
+	return sysfs_emit(buf, "%d\n", temp_c);
+}
+
+static ssize_t msi_wmi_platform_temp_table_store(struct device *dev, struct device_attribute *attr,
+						 const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+	u8 buffer[32] = { sattr->nr };
+	long temp_c;
+	int ret;
+
+	ret = kstrtol(buf, 10, &temp_c);
+	if (ret < 0)
+		return ret;
+
+	temp_c = clamp_val(temp_c, 0, 255);
+
+	guard(mutex)(&data->wmi_lock);
+
+	ret = msi_wmi_platform_query_unlocked(data, MSI_PLATFORM_GET_TEMPERATURE,
+					      buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	buffer[0] = sattr->nr;
+	buffer[sattr->index + 1] = temp_c;
+
+	ret = msi_wmi_platform_query_unlocked(data, MSI_PLATFORM_SET_TEMPERATURE,
+					      buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x0);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x3);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x4);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x5);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x6);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_TEMP_TABLE, 0x7);
+
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x1);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x2);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x3);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x4);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x5);
+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x6);
+
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x0);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x3);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x4);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x5);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x6);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_temp, msi_wmi_platform_temp_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_TEMP_TABLE, 0x7);
+
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x1);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x2);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x3);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x4);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x5);
+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_pwm, msi_wmi_platform_fan_table,
+			       MSI_PLATFORM_FAN_SUBFEATURE_GPU_FAN_TABLE, 0x6);
+
+static struct attribute *msi_wmi_platform_hwmon_attrs[] = {
+	&sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr,
+
+	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr,
+
+	&sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point5_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point6_temp.dev_attr.attr,
+
+	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point5_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point6_pwm.dev_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(msi_wmi_platform_hwmon);
+
 static umode_t msi_wmi_platform_is_visible(const void *drvdata, enum hwmon_sensor_types type,
 					   u32 attr, int channel)
 {
+	if (type == hwmon_pwm && attr == hwmon_pwm_enable)
+		return 0644;
+
 	return 0444;
 }
 
@@ -233,24 +444,102 @@ static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types typ
 	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
 	u8 buffer[32] = { 0 };
 	u16 value;
+	u8 flags;
 	int ret;
 
-	ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, buf, sizeof(buf));
-	if (ret < 0)
-		return ret;
+	switch (type) {
+	case hwmon_fan:
+		switch (attr) {
+		case hwmon_fan_input:
+			buffer[0] = MSI_PLATFORM_FAN_SUBFEATURE_FAN_SPEED;
+			ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, buffer,
+						     sizeof(buffer));
+			if (ret < 0)
+				return ret;
+
+			value = get_unaligned_be16(&buffer[channel * 2 + 1]);
+			if (!value)
+				*val = 0;
+			else
+				*val = 480000 / value;
+
+			return 0;
+		default:
+			return -EOPNOTSUPP;
+		}
+	case hwmon_pwm:
+		switch (attr) {
+		case hwmon_pwm_enable:
+			buffer[0] = MSI_PLATFORM_AP_SUBFEATURE_FAN_MODE;
+			ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_AP, buffer,
+						     sizeof(buffer));
+			if (ret < 0)
+				return ret;
+
+			flags = buffer[MSI_PLATFORM_AP_FAN_FLAGS_OFFSET];
+			if (flags & MSI_PLATFORM_AP_ENABLE_FAN_TABLES)
+				*val = 1;
+			else
+				*val = 2;
+
+			return 0;
+		default:
+			return -EOPNOTSUPP;
+		}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
 
-	value = get_unaligned_be16(&buffer[channel * 2 + 1]);
-	if (!value)
-		*val = 0;
-	else
-		*val = 480000 / value;
+static int msi_wmi_platform_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+				  int channel, long val)
+{
+	struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
+	u8 buffer[32] = { };
+	int ret;
 
-	return 0;
+	switch (type) {
+	case hwmon_pwm:
+		switch (attr) {
+		case hwmon_pwm_enable:
+			guard(mutex)(&data->wmi_lock);
+
+			buffer[0] = MSI_PLATFORM_AP_SUBFEATURE_FAN_MODE;
+			ret = msi_wmi_platform_query_unlocked(
+				data, MSI_PLATFORM_GET_AP, buffer,
+				sizeof(buffer));
+			if (ret < 0)
+				return ret;
+
+			buffer[0] = MSI_PLATFORM_AP_SUBFEATURE_FAN_MODE;
+			switch (val) {
+			case 1:
+				buffer[MSI_PLATFORM_AP_FAN_FLAGS_OFFSET] |=
+					MSI_PLATFORM_AP_ENABLE_FAN_TABLES;
+				break;
+			case 2:
+				buffer[MSI_PLATFORM_AP_FAN_FLAGS_OFFSET] &=
+					~MSI_PLATFORM_AP_ENABLE_FAN_TABLES;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			return msi_wmi_platform_query_unlocked(
+				data, MSI_PLATFORM_SET_AP, buffer,
+				sizeof(buffer));
+		default:
+			return -EOPNOTSUPP;
+		}
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static const struct hwmon_ops msi_wmi_platform_ops = {
 	.is_visible = msi_wmi_platform_is_visible,
 	.read = msi_wmi_platform_read,
+	.write = msi_wmi_platform_write,
 };
 
 static const struct hwmon_channel_info * const msi_wmi_platform_info[] = {
@@ -260,6 +549,10 @@ static const struct hwmon_channel_info * const msi_wmi_platform_info[] = {
 			   HWMON_F_INPUT,
 			   HWMON_F_INPUT
 			   ),
+	HWMON_CHANNEL_INFO(pwm,
+			   HWMON_PWM_ENABLE,
+			   HWMON_PWM_ENABLE
+			   ),
 	NULL
 };
 
@@ -268,8 +561,8 @@ static const struct hwmon_chip_info msi_wmi_platform_chip_info = {
 	.info = msi_wmi_platform_info,
 };
 
-static ssize_t msi_wmi_platform_write(struct file *fp, const char __user *input, size_t length,
-				      loff_t *offset)
+static ssize_t msi_wmi_platform_debugfs_write(struct file *fp, const char __user *input,
+					      size_t length, loff_t *offset)
 {
 	struct seq_file *seq = fp->private_data;
 	struct msi_wmi_platform_debugfs_data *data = seq->private;
@@ -303,7 +596,7 @@ static ssize_t msi_wmi_platform_write(struct file *fp, const char __user *input,
 	return length;
 }
 
-static int msi_wmi_platform_show(struct seq_file *seq, void *p)
+static int msi_wmi_platform_debugfs_show(struct seq_file *seq, void *p)
 {
 	struct msi_wmi_platform_debugfs_data *data = seq->private;
 	int ret;
@@ -315,19 +608,19 @@ static int msi_wmi_platform_show(struct seq_file *seq, void *p)
 	return ret;
 }
 
-static int msi_wmi_platform_open(struct inode *inode, struct file *fp)
+static int msi_wmi_platform_debugfs_open(struct inode *inode, struct file *fp)
 {
 	struct msi_wmi_platform_debugfs_data *data = inode->i_private;
 
 	/* The seq_file uses the last byte of the buffer for detecting buffer overflows */
-	return single_open_size(fp, msi_wmi_platform_show, data, data->length + 1);
+	return single_open_size(fp, msi_wmi_platform_debugfs_show, data, data->length + 1);
 }
 
 static const struct file_operations msi_wmi_platform_debugfs_fops = {
 	.owner = THIS_MODULE,
-	.open = msi_wmi_platform_open,
+	.open = msi_wmi_platform_debugfs_open,
 	.read = seq_read,
-	.write = msi_wmi_platform_write,
+	.write = msi_wmi_platform_debugfs_write,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
@@ -389,7 +682,8 @@ static int msi_wmi_platform_hwmon_init(struct msi_wmi_platform_data *data)
 	struct device *hdev;
 
 	hdev = devm_hwmon_device_register_with_info(&data->wdev->dev, "msi_wmi_platform", data,
-						    &msi_wmi_platform_chip_info, NULL);
+						    &msi_wmi_platform_chip_info,
+						    msi_wmi_platform_hwmon_groups);
 
 	return PTR_ERR_OR_ZERO(hdev);
 }
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ