[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e42249ba-f04b-4c83-9d71-a943c195b953@gmx.de>
Date: Mon, 19 May 2025 03:35:16 +0200
From: Armin Wolf <W_Armin@....de>
To: Antheas Kapenekakis <lkml@...heas.dev>,
platform-driver-x86@...r.kernel.org
Cc: 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
Subject: Re: [PATCH v1 04/10] platform/x86: msi-wmi-platform: Add support for
fan control
Am 13.05.25 um 22:58 schrieb Armin Wolf:
> Am 11.05.25 um 22:44 schrieb Antheas Kapenekakis:
>
>> 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.
>
> I assume that not all devices support this feature? If so then please
> hide it behind
> a quirk.
>
> Thanks,
> Armin Wolf
>
>> 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);
I forgot to mention that the temp table is not documented inside the documentation.
>> +
>> +static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_pwm,
>> msi_wmi_platform_fan_table,
>> + MSI_PLATFORM_FAN_SUBFEATURE_CPU_FAN_TABLE, 0x1);
I just noticed that the documentation does not mention that the fan table starts at offset 0x1.
Please add this minor detail to the documentation.
Thanks,
Armin Wolf
>> +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);
>> }
>
Powered by blists - more mailing lists