From patchwork Thu Jan 5 22:51:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Armin Wolf X-Patchwork-Id: 13090657 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89380C3DA7A for ; Thu, 5 Jan 2023 22:51:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236256AbjAEWvd (ORCPT ); Thu, 5 Jan 2023 17:51:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236265AbjAEWvb (ORCPT ); Thu, 5 Jan 2023 17:51:31 -0500 Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 255E65881D; Thu, 5 Jan 2023 14:51:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1672959072; bh=sF0cbtH+Hcn4OuIpkhZqzOz2WGnt+KmjYTWFjzqfdRs=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=iglgxZKnfF3iYKr6i8FOKuiZNJNuRqmThMiFDclQzHPhPEXZOqu9wRSAPZOjTlFLf tBKgHVKwN8hTy+yVmMmJpleDLeBdnNOW/4wDr7oCABqEv8TZCpX/J4d9l+FOyxmaKE NzK7ndx9YGZqeSJtt4LTNWIbj9obmz7Vij5awztuQyOilg9741dzbyeX9QiZKeeboU Q7zfo0qLm5RMbECUMf7Cut2xjtJjbEFNd4+FzVm3IsePwULxwtT0zqrlH006hX3RI5 ZdBKe9EXjgXnaog6o8V3Nv3vMP4kg9mpJODzQvfJ0+cDyJwrHjok+2f7OO3cw5/ASj gplU9sWrLCmaA== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from esprimo-mx.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MSbx3-1pOGQj21xh-00Sz6u; Thu, 05 Jan 2023 23:51:12 +0100 From: Armin Wolf To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] hwmon: (ftsteutates) Convert to devm_hwmon_device_register_with_info() Date: Thu, 5 Jan 2023 23:51:05 +0100 Message-Id: <20230105225107.58308-2-W_Armin@gmx.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230105225107.58308-1-W_Armin@gmx.de> References: <20230105225107.58308-1-W_Armin@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:6qjCMrNiGvw92apmuAVN6D+uC0EY6y87J3abZ1PRfVg3y3JGBLJ /Po3zY0VDvcQhwWZaZtggdjEH1FksL3bZ5BRP5ZeiQPl5McK7e3480nBuzwEP323OaY3/Pz IFdPiIWo1d/2PfXmDqkEUC9MrMO98+BFeFyu/FXHre8ybEAeOAp1wHpAG/OI6Ax0Z73xQr+ +/TISIGjaJJ8mKC9ErTPA== UI-OutboundReport: notjunk:1;M01:P0:49igZ19mFu8=;86YL10wIxz0tUUhD6L1my8moyO0 IX4UvVMEOIt1bi9fMoHlheOyhdCef2AoA5AOxIkVbJ2EnHM8yu9U5uTj7t8msC3dfA+ZYXvMK rjdvChKSuDFxnE6wdBdwqexcgq3JrruxvsPPrE2llAzcTpXbVUatf0hozl+uM5vyontVLp5pq bjKiMj3d4nQhqbhEQQGwcYf8/mlYsOP+GWp7TxKGo4DMO/UW3m2ZknoCjbq4tmhNvH4JJ7xUC lXFYWxN+Vxn/RJOla7ELeBETMGlik3ef+cNtRwJ2ZaAT9l6b8iCUwmep3sL+0eAIsfff/XS2H 4Otqk+q6JnlSmizC/93YVFZPjFM0wHjwoO9C/vdQyKM8fLKp/R7lz9Ojk0nfvFknmZfLbIblp opRvf+gnGKNNtK9DeklYiEEQFq6Kgxo8skNWzH+GcdcJ634uj8XEnrsQpWRSRHQrW6nhFbCaD uxJPqZ6xRYBbTAawowQLT8PVNqHkujPg8lTSHWNHUvt7NbABJhkejZ4HhETL15Y35tpnvhS7I GEBbGHJA+qmncMA/ZM0UKjJVN/gh8sp9fX4zV8cK9P3lAo34W1tswLl23TpjWmECYhxu9+5Lg FrJjd+ZQCo/JAAc8IOULRsdHzaTIf9BQQDWM4J0t3HK0iLE8A7/bFlHriukDbDOJdQ3MEIrS2 bZIGX+EtTsJeObMtLHOjELhnkTO/0nRgwgn/pYJKY/FxUH+KydtiWnx4ScvaL+m3PvoazTAcA oGvAr6duEEZp5aiEN9GQIQ5fxnSh4M8TWtyd08klzyDQM3pzi8atG6e27WojR6ozdmJyIf0PP lGd8DU0ZNdma53/Vo5HcmFUdCeKiH6WkPYYrRlvJULI+M+J8/z0CMYrMN5QhljBGubD3RiEnp Jen4GhEum+tcu2OY9l2QCIpnCIdKSUWDY4Q9wBXMFMldFiVtEF7+2404W7FzRfD0W2JjWkBNH BMNsYd9YM1UA6O04OtEfTXHO6z4= Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Convert driver to use devm_hwmon_device_register_with_info() to reduce module size by ~30%. Tested on a Fujitsu DS3401-B1. Signed-off-by: Armin Wolf --- drivers/hwmon/ftsteutates.c | 532 ++++++++++++++---------------------- 1 file changed, 204 insertions(+), 328 deletions(-) -- 2.30.2 diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index e860924f90aa..23dc3a74f84b 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #define FTS_DEVICE_ID_REG 0x0000 @@ -340,376 +339,255 @@ static int fts_watchdog_init(struct fts_data *data) return devm_watchdog_register_device(&data->client->dev, &data->wdd); } -/*****************************************************************************/ -/* SysFS handler functions */ -/*****************************************************************************/ -static ssize_t in_value_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int value, err; - - err = fts_update_device(data); - if (err < 0) - return err; - - value = DIV_ROUND_CLOSEST(data->volt[index] * 3300, 255); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t temp_value_show(struct device *dev, +static ssize_t fan_source_show(struct device *dev, struct device_attribute *devattr, char *buf) { struct fts_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(devattr)->index; - int value, err; + int err; err = fts_update_device(data); if (err < 0) return err; - value = (data->temp_input[index] - 64) * 1000; - - return sprintf(buf, "%d\n", value); + return sprintf(buf, "%u\n", data->fan_source[index]); } -static ssize_t temp_fault_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int err; +static SENSOR_DEVICE_ATTR_RO(fan1_source, fan_source, 0); +static SENSOR_DEVICE_ATTR_RO(fan2_source, fan_source, 1); +static SENSOR_DEVICE_ATTR_RO(fan3_source, fan_source, 2); +static SENSOR_DEVICE_ATTR_RO(fan4_source, fan_source, 3); +static SENSOR_DEVICE_ATTR_RO(fan5_source, fan_source, 4); +static SENSOR_DEVICE_ATTR_RO(fan6_source, fan_source, 5); +static SENSOR_DEVICE_ATTR_RO(fan7_source, fan_source, 6); +static SENSOR_DEVICE_ATTR_RO(fan8_source, fan_source, 7); - err = fts_update_device(data); - if (err < 0) - return err; +static struct attribute *fts_fan_attrs[] = { + &sensor_dev_attr_fan1_source.dev_attr.attr, + &sensor_dev_attr_fan2_source.dev_attr.attr, + &sensor_dev_attr_fan3_source.dev_attr.attr, + &sensor_dev_attr_fan4_source.dev_attr.attr, + &sensor_dev_attr_fan5_source.dev_attr.attr, + &sensor_dev_attr_fan6_source.dev_attr.attr, + &sensor_dev_attr_fan7_source.dev_attr.attr, + &sensor_dev_attr_fan8_source.dev_attr.attr, + NULL +}; - /* 00h Temperature = Sensor Error */ - return sprintf(buf, "%d\n", data->temp_input[index] == 0); -} +static const struct attribute_group fts_attr_group = { + .attrs = fts_fan_attrs +}; -static ssize_t temp_alarm_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int err; +static const struct attribute_group *fts_attr_groups[] = { + &fts_attr_group, + NULL +}; - err = fts_update_device(data); - if (err < 0) - return err; +static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, u32 attr, + int channel) +{ + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + case hwmon_temp_fault: + return 0444; + case hwmon_temp_alarm: + return 0644; + default: + break; + } + break; + case hwmon_fan: + switch (attr) { + case hwmon_fan_input: + return 0444; + case hwmon_fan_alarm: + return 0644; + default: + break; + } + break; + case hwmon_in: + return 0444; + default: + break; + } - return sprintf(buf, "%u\n", !!(data->temp_alarm & BIT(index))); + return 0; } -static ssize_t -temp_alarm_store(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long *val) { struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - long ret; + int ret = fts_update_device(data); - ret = fts_update_device(data); if (ret < 0) return ret; - if (kstrtoul(buf, 10, &ret) || ret != 0) - return -EINVAL; - - mutex_lock(&data->update_lock); - ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(index)); - if (ret < 0) - goto error; - - ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(index), - ret | 0x1); - if (ret < 0) - goto error; - - data->valid = false; - ret = count; -error: - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t fan_value_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int value, err; - - err = fts_update_device(data); - if (err < 0) - return err; - - value = data->fan_input[index] * 60; + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + *val = (data->temp_input[channel] - 64) * 1000; - return sprintf(buf, "%d\n", value); -} + return 0; + case hwmon_temp_alarm: + *val = !!(data->temp_alarm & BIT(channel)); -static ssize_t fan_source_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int err; + return 0; + case hwmon_temp_fault: + /* 00h Temperature = Sensor Error */; + *val = (data->temp_input[channel] == 0); - err = fts_update_device(data); - if (err < 0) - return err; + return 0; + default: + break; + } + break; + case hwmon_fan: + switch (attr) { + case hwmon_fan_input: + *val = data->fan_input[channel] * 60; - return sprintf(buf, "%u\n", data->fan_source[index]); -} + return 0; + case hwmon_fan_alarm: + *val = !!(data->fan_alarm & BIT(channel)); -static ssize_t fan_alarm_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int err; + return 0; + default: + break; + } + break; + case hwmon_in: + switch (attr) { + case hwmon_in_input: + *val = DIV_ROUND_CLOSEST(data->volt[channel] * 3300, 255); - err = fts_update_device(data); - if (err < 0) - return err; + return 0; + default: + break; + } + break; + default: + break; + } - return sprintf(buf, "%d\n", !!(data->fan_alarm & BIT(index))); + return -EOPNOTSUPP; } -static ssize_t -fan_alarm_store(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static int fts_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long val) { struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - long ret; + int ret = fts_update_device(data); - ret = fts_update_device(data); if (ret < 0) return ret; - if (kstrtoul(buf, 10, &ret) || ret != 0) - return -EINVAL; - - mutex_lock(&data->update_lock); - ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(index)); - if (ret < 0) - goto error; - - ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(index), - ret | 0x1); - if (ret < 0) - goto error; + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_alarm: + if (val) + return -EINVAL; + + mutex_lock(&data->update_lock); + ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(channel)); + if (ret >= 0) + ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(channel), + ret | 0x1); + if (ret >= 0) + data->valid = false; + + mutex_unlock(&data->update_lock); + if (ret < 0) + return ret; + + return 0; + default: + break; + } + break; + case hwmon_fan: + switch (attr) { + case hwmon_fan_alarm: + if (val) + return -EINVAL; + + mutex_lock(&data->update_lock); + ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(channel)); + if (ret >= 0) + ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(channel), + ret | 0x1); + if (ret >= 0) + data->valid = false; + + mutex_unlock(&data->update_lock); + if (ret < 0) + return ret; + + return 0; + default: + break; + } + break; + default: + break; + } - data->valid = false; - ret = count; -error: - mutex_unlock(&data->update_lock); - return ret; + return -EOPNOTSUPP; } -/*****************************************************************************/ -/* SysFS structs */ -/*****************************************************************************/ - -/* Temperature sensors */ -static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_value, 0); -static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_value, 1); -static SENSOR_DEVICE_ATTR_RO(temp3_input, temp_value, 2); -static SENSOR_DEVICE_ATTR_RO(temp4_input, temp_value, 3); -static SENSOR_DEVICE_ATTR_RO(temp5_input, temp_value, 4); -static SENSOR_DEVICE_ATTR_RO(temp6_input, temp_value, 5); -static SENSOR_DEVICE_ATTR_RO(temp7_input, temp_value, 6); -static SENSOR_DEVICE_ATTR_RO(temp8_input, temp_value, 7); -static SENSOR_DEVICE_ATTR_RO(temp9_input, temp_value, 8); -static SENSOR_DEVICE_ATTR_RO(temp10_input, temp_value, 9); -static SENSOR_DEVICE_ATTR_RO(temp11_input, temp_value, 10); -static SENSOR_DEVICE_ATTR_RO(temp12_input, temp_value, 11); -static SENSOR_DEVICE_ATTR_RO(temp13_input, temp_value, 12); -static SENSOR_DEVICE_ATTR_RO(temp14_input, temp_value, 13); -static SENSOR_DEVICE_ATTR_RO(temp15_input, temp_value, 14); -static SENSOR_DEVICE_ATTR_RO(temp16_input, temp_value, 15); - -static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0); -static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1); -static SENSOR_DEVICE_ATTR_RO(temp3_fault, temp_fault, 2); -static SENSOR_DEVICE_ATTR_RO(temp4_fault, temp_fault, 3); -static SENSOR_DEVICE_ATTR_RO(temp5_fault, temp_fault, 4); -static SENSOR_DEVICE_ATTR_RO(temp6_fault, temp_fault, 5); -static SENSOR_DEVICE_ATTR_RO(temp7_fault, temp_fault, 6); -static SENSOR_DEVICE_ATTR_RO(temp8_fault, temp_fault, 7); -static SENSOR_DEVICE_ATTR_RO(temp9_fault, temp_fault, 8); -static SENSOR_DEVICE_ATTR_RO(temp10_fault, temp_fault, 9); -static SENSOR_DEVICE_ATTR_RO(temp11_fault, temp_fault, 10); -static SENSOR_DEVICE_ATTR_RO(temp12_fault, temp_fault, 11); -static SENSOR_DEVICE_ATTR_RO(temp13_fault, temp_fault, 12); -static SENSOR_DEVICE_ATTR_RO(temp14_fault, temp_fault, 13); -static SENSOR_DEVICE_ATTR_RO(temp15_fault, temp_fault, 14); -static SENSOR_DEVICE_ATTR_RO(temp16_fault, temp_fault, 15); - -static SENSOR_DEVICE_ATTR_RW(temp1_alarm, temp_alarm, 0); -static SENSOR_DEVICE_ATTR_RW(temp2_alarm, temp_alarm, 1); -static SENSOR_DEVICE_ATTR_RW(temp3_alarm, temp_alarm, 2); -static SENSOR_DEVICE_ATTR_RW(temp4_alarm, temp_alarm, 3); -static SENSOR_DEVICE_ATTR_RW(temp5_alarm, temp_alarm, 4); -static SENSOR_DEVICE_ATTR_RW(temp6_alarm, temp_alarm, 5); -static SENSOR_DEVICE_ATTR_RW(temp7_alarm, temp_alarm, 6); -static SENSOR_DEVICE_ATTR_RW(temp8_alarm, temp_alarm, 7); -static SENSOR_DEVICE_ATTR_RW(temp9_alarm, temp_alarm, 8); -static SENSOR_DEVICE_ATTR_RW(temp10_alarm, temp_alarm, 9); -static SENSOR_DEVICE_ATTR_RW(temp11_alarm, temp_alarm, 10); -static SENSOR_DEVICE_ATTR_RW(temp12_alarm, temp_alarm, 11); -static SENSOR_DEVICE_ATTR_RW(temp13_alarm, temp_alarm, 12); -static SENSOR_DEVICE_ATTR_RW(temp14_alarm, temp_alarm, 13); -static SENSOR_DEVICE_ATTR_RW(temp15_alarm, temp_alarm, 14); -static SENSOR_DEVICE_ATTR_RW(temp16_alarm, temp_alarm, 15); - -static struct attribute *fts_temp_attrs[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp5_input.dev_attr.attr, - &sensor_dev_attr_temp6_input.dev_attr.attr, - &sensor_dev_attr_temp7_input.dev_attr.attr, - &sensor_dev_attr_temp8_input.dev_attr.attr, - &sensor_dev_attr_temp9_input.dev_attr.attr, - &sensor_dev_attr_temp10_input.dev_attr.attr, - &sensor_dev_attr_temp11_input.dev_attr.attr, - &sensor_dev_attr_temp12_input.dev_attr.attr, - &sensor_dev_attr_temp13_input.dev_attr.attr, - &sensor_dev_attr_temp14_input.dev_attr.attr, - &sensor_dev_attr_temp15_input.dev_attr.attr, - &sensor_dev_attr_temp16_input.dev_attr.attr, - - &sensor_dev_attr_temp1_fault.dev_attr.attr, - &sensor_dev_attr_temp2_fault.dev_attr.attr, - &sensor_dev_attr_temp3_fault.dev_attr.attr, - &sensor_dev_attr_temp4_fault.dev_attr.attr, - &sensor_dev_attr_temp5_fault.dev_attr.attr, - &sensor_dev_attr_temp6_fault.dev_attr.attr, - &sensor_dev_attr_temp7_fault.dev_attr.attr, - &sensor_dev_attr_temp8_fault.dev_attr.attr, - &sensor_dev_attr_temp9_fault.dev_attr.attr, - &sensor_dev_attr_temp10_fault.dev_attr.attr, - &sensor_dev_attr_temp11_fault.dev_attr.attr, - &sensor_dev_attr_temp12_fault.dev_attr.attr, - &sensor_dev_attr_temp13_fault.dev_attr.attr, - &sensor_dev_attr_temp14_fault.dev_attr.attr, - &sensor_dev_attr_temp15_fault.dev_attr.attr, - &sensor_dev_attr_temp16_fault.dev_attr.attr, - - &sensor_dev_attr_temp1_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_alarm.dev_attr.attr, - &sensor_dev_attr_temp4_alarm.dev_attr.attr, - &sensor_dev_attr_temp5_alarm.dev_attr.attr, - &sensor_dev_attr_temp6_alarm.dev_attr.attr, - &sensor_dev_attr_temp7_alarm.dev_attr.attr, - &sensor_dev_attr_temp8_alarm.dev_attr.attr, - &sensor_dev_attr_temp9_alarm.dev_attr.attr, - &sensor_dev_attr_temp10_alarm.dev_attr.attr, - &sensor_dev_attr_temp11_alarm.dev_attr.attr, - &sensor_dev_attr_temp12_alarm.dev_attr.attr, - &sensor_dev_attr_temp13_alarm.dev_attr.attr, - &sensor_dev_attr_temp14_alarm.dev_attr.attr, - &sensor_dev_attr_temp15_alarm.dev_attr.attr, - &sensor_dev_attr_temp16_alarm.dev_attr.attr, - NULL +static const struct hwmon_ops fts_ops = { + .is_visible = fts_is_visible, + .read = fts_read, + .write = fts_write, }; -/* Fans */ -static SENSOR_DEVICE_ATTR_RO(fan1_input, fan_value, 0); -static SENSOR_DEVICE_ATTR_RO(fan2_input, fan_value, 1); -static SENSOR_DEVICE_ATTR_RO(fan3_input, fan_value, 2); -static SENSOR_DEVICE_ATTR_RO(fan4_input, fan_value, 3); -static SENSOR_DEVICE_ATTR_RO(fan5_input, fan_value, 4); -static SENSOR_DEVICE_ATTR_RO(fan6_input, fan_value, 5); -static SENSOR_DEVICE_ATTR_RO(fan7_input, fan_value, 6); -static SENSOR_DEVICE_ATTR_RO(fan8_input, fan_value, 7); - -static SENSOR_DEVICE_ATTR_RO(fan1_source, fan_source, 0); -static SENSOR_DEVICE_ATTR_RO(fan2_source, fan_source, 1); -static SENSOR_DEVICE_ATTR_RO(fan3_source, fan_source, 2); -static SENSOR_DEVICE_ATTR_RO(fan4_source, fan_source, 3); -static SENSOR_DEVICE_ATTR_RO(fan5_source, fan_source, 4); -static SENSOR_DEVICE_ATTR_RO(fan6_source, fan_source, 5); -static SENSOR_DEVICE_ATTR_RO(fan7_source, fan_source, 6); -static SENSOR_DEVICE_ATTR_RO(fan8_source, fan_source, 7); - -static SENSOR_DEVICE_ATTR_RW(fan1_alarm, fan_alarm, 0); -static SENSOR_DEVICE_ATTR_RW(fan2_alarm, fan_alarm, 1); -static SENSOR_DEVICE_ATTR_RW(fan3_alarm, fan_alarm, 2); -static SENSOR_DEVICE_ATTR_RW(fan4_alarm, fan_alarm, 3); -static SENSOR_DEVICE_ATTR_RW(fan5_alarm, fan_alarm, 4); -static SENSOR_DEVICE_ATTR_RW(fan6_alarm, fan_alarm, 5); -static SENSOR_DEVICE_ATTR_RW(fan7_alarm, fan_alarm, 6); -static SENSOR_DEVICE_ATTR_RW(fan8_alarm, fan_alarm, 7); - -static struct attribute *fts_fan_attrs[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan4_input.dev_attr.attr, - &sensor_dev_attr_fan5_input.dev_attr.attr, - &sensor_dev_attr_fan6_input.dev_attr.attr, - &sensor_dev_attr_fan7_input.dev_attr.attr, - &sensor_dev_attr_fan8_input.dev_attr.attr, - - &sensor_dev_attr_fan1_source.dev_attr.attr, - &sensor_dev_attr_fan2_source.dev_attr.attr, - &sensor_dev_attr_fan3_source.dev_attr.attr, - &sensor_dev_attr_fan4_source.dev_attr.attr, - &sensor_dev_attr_fan5_source.dev_attr.attr, - &sensor_dev_attr_fan6_source.dev_attr.attr, - &sensor_dev_attr_fan7_source.dev_attr.attr, - &sensor_dev_attr_fan8_source.dev_attr.attr, - - &sensor_dev_attr_fan1_alarm.dev_attr.attr, - &sensor_dev_attr_fan2_alarm.dev_attr.attr, - &sensor_dev_attr_fan3_alarm.dev_attr.attr, - &sensor_dev_attr_fan4_alarm.dev_attr.attr, - &sensor_dev_attr_fan5_alarm.dev_attr.attr, - &sensor_dev_attr_fan6_alarm.dev_attr.attr, - &sensor_dev_attr_fan7_alarm.dev_attr.attr, - &sensor_dev_attr_fan8_alarm.dev_attr.attr, +static const struct hwmon_channel_info *fts_info[] = { + HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT, + HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT + ), + HWMON_CHANNEL_INFO(fan, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM, + HWMON_F_INPUT | HWMON_F_ALARM + ), + HWMON_CHANNEL_INFO(in, + HWMON_I_INPUT, + HWMON_I_INPUT, + HWMON_I_INPUT, + HWMON_I_INPUT + ), NULL }; -/* Voltages */ -static SENSOR_DEVICE_ATTR_RO(in1_input, in_value, 0); -static SENSOR_DEVICE_ATTR_RO(in2_input, in_value, 1); -static SENSOR_DEVICE_ATTR_RO(in3_input, in_value, 2); -static SENSOR_DEVICE_ATTR_RO(in4_input, in_value, 3); -static struct attribute *fts_voltage_attrs[] = { - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_in4_input.dev_attr.attr, - NULL -}; - -static const struct attribute_group fts_voltage_attr_group = { - .attrs = fts_voltage_attrs -}; - -static const struct attribute_group fts_temp_attr_group = { - .attrs = fts_temp_attrs -}; - -static const struct attribute_group fts_fan_attr_group = { - .attrs = fts_fan_attrs -}; - -static const struct attribute_group *fts_attr_groups[] = { - &fts_voltage_attr_group, - &fts_temp_attr_group, - &fts_fan_attr_group, - NULL +static const struct hwmon_chip_info fts_chip_info = { + .ops = &fts_ops, + .info = fts_info, }; /*****************************************************************************/ @@ -793,10 +671,8 @@ static int fts_probe(struct i2c_client *client) return err; revision = err; - hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, - "ftsteutates", - data, - fts_attr_groups); + hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "ftsteutates", data, + &fts_chip_info, fts_attr_groups); if (IS_ERR(hwmon_dev)) return PTR_ERR(hwmon_dev); From patchwork Thu Jan 5 22:51:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Armin Wolf X-Patchwork-Id: 13090656 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8336AC4708E for ; Thu, 5 Jan 2023 22:51:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232346AbjAEWvb (ORCPT ); Thu, 5 Jan 2023 17:51:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236225AbjAEWva (ORCPT ); Thu, 5 Jan 2023 17:51:30 -0500 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B50A5881E; Thu, 5 Jan 2023 14:51:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1672959074; bh=RjBrwrzDF0HUQvM108jehXVM85PyLM9sDZAL/eCo9+M=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=C9bEvWCx2W8Vru8k/xxoqFq+fEoeBjgnMInhC7r5LI4XZju164jhgyLA7KVrOyeul RAwa1hUOkukbV0noUBlIC/9Y3lDopcVMFRhDAeBHV6B1EKXLDC+bi/oEPaNKKhOkah kTItynBceGjZwFMkzzIZLIpXjE8LJdwYZmxmXuj2yeOwp2CzmiAm06iO5Gc2UrR1K3 uFzq8X/PuB6VGUNHVP1mPbFxbaxI4qbLHmbIVNUSwuMWkSzCHrfSJUqte3lT4PlIAp p4c6K4w+zUBkkLwsaKdUQRCL7WGtBssWnpbLGWo11C9ydmHghcctvR1UXMiN/n9lix 7Tic554Hq2kXQ== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from esprimo-mx.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MKsjH-1pVvPY3gRp-00LBJf; Thu, 05 Jan 2023 23:51:13 +0100 From: Armin Wolf To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] hwmon: (ftsteutates) Replace fanX_source with pwmX_auto_channels_temp Date: Thu, 5 Jan 2023 23:51:06 +0100 Message-Id: <20230105225107.58308-3-W_Armin@gmx.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230105225107.58308-1-W_Armin@gmx.de> References: <20230105225107.58308-1-W_Armin@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:qQrA4b148lSVLX8UdMqK/Gj8LX7LaLydj8KCi7RZ/PBspX/3Czh kQIRqlEarBb3wOPD2GXkhPe0BuA1cXF+K/fO5oMhClGoI2u7Bc+wYym1b/vfuHq79GwWsjs //oYI+1i5Mom5sA0skXIO4Yv/piHe8NkU12+/ddN4kVpFqxGcLMb6FsVD9J7i/LJjFdUt5e BKV2X5ikDc2fJqrlpdmog== UI-OutboundReport: notjunk:1;M01:P0:67q0j3DOJHo=;cAMZ8cvMj/epiNtrS5c4MF/IjTF FycRaiDshPKslNucIYNze+i0KZehZrr3OH/Qi8FGHCyIJqpH+Q4yFklP+9B7Rg0dP+6coYaHm gG7xq4oEC1dRuxxlDp8SY8+HHXqapt7zu79nzQFHY5KKQz26he1AXlfA3Xj+onrs+0hpjttFD xAykjAAsnG4g2WQaRMr4eqfPsohJsS0+kPGRilkQDGNDycHIT4dhHeNkic6OKZhS6gnuUxDXc JBIx+HG8B2gHdXixcgUtoLjT+SnbDTRtdz1wZvXhU3CVZFVghF5nmQ42d9G10BYqRbTfxghH+ HSpSFE7jKSOukYv5e5PfnymDVwyA1FYZdB2pIycZhGr8QStPl7I6lCvFaqjp0F/nCkB3W1unj +0V1Fkld4f/ZQ8BPrKDc3XQOAbRQMxe3xKX5r8c+0OxgjkPR07dFqOLXjaC9pxL/xWs+dT11z 6UhzmBJyDwiDaShBAbLkmAGeRdJjBXCJrHvaAD6nzfeJCgdH+rmh/UhuJneZWYJaAcXmQU1Ys gFGMtjfpFBY5G3IZoExErLQ6ryKqqTT/mB57VoMk9hGVM3mSZ+Y2p6g+fmXt6OCCyjT/1b5cO BXXvI9ONURVUTaEZOPAYIqzxrak+uBK+ozVUQAvgN5+GZJ0kL7kIj8z8jFC7XDicrzA1FE9I8 /9hihkvz9kUwXhDMZngqyTIF3IP2TEH6qCQ1VaxOf7ASp7qtvXku8gp85EnQS9Ibs6o+03+OG MYNX+u25jVKynNdOcLqtzwKXH9vJ4Kka6IL2k7bCCo/lvoxoM7Nn+PTQheUFFYe4/YLdZH/uf swjSCdOOd/Wkuw8v38b7hrWU23V2povnnJSJ49EqAKHwGoUZu1Si++KaZvpPuVCmuHzwTu3Nz tT/qwjUSHwvKlLa8SxtohekhG2mrF8vnzSzAyF4k6LinCLF1T60SCnWjqwR51uMoPAi9v9XzO YpVp4uBbINcWDtD416dJ+CZupPg= Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Replace the nonstandard fanX_source attributes with the standardized pwmX_auto_channels_temp attributes and document the special behaviour associated with those attributes. Tested on a Fujitsu DS3401-B1. Signed-off-by: Armin Wolf --- Documentation/hwmon/ftsteutates.rst | 5 ++ drivers/hwmon/ftsteutates.c | 77 +++++++++++------------------ 2 files changed, 33 insertions(+), 49 deletions(-) -- 2.30.2 diff --git a/Documentation/hwmon/ftsteutates.rst b/Documentation/hwmon/ftsteutates.rst index 198fa8e2819d..b3bfec36661d 100644 --- a/Documentation/hwmon/ftsteutates.rst +++ b/Documentation/hwmon/ftsteutates.rst @@ -22,6 +22,11 @@ enhancements. It can monitor up to 4 voltages, 16 temperatures and 8 fans. It also contains an integrated watchdog which is currently implemented in this driver. +The ``pwmX_auto_channels_temp`` attributes show which temperature sensor +is currently driving which fan channel. This value might dynamically change +during runtime depending on the temperature sensor selected by +the fan control circuit. + The 4 voltages require a board-specific multiplier, since the BMC can only measure voltages up to 3.3V and thus relies on voltage dividers. Consult your motherboard manual for details. diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index 23dc3a74f84b..0d8ab94250a9 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -6,9 +6,7 @@ * Thilo Cestonaro */ #include -#include #include -#include #include #include #include @@ -16,7 +14,6 @@ #include #include #include -#include #include #define FTS_DEVICE_ID_REG 0x0000 @@ -48,6 +45,8 @@ #define FTS_NO_TEMP_SENSORS 0x10 #define FTS_NO_VOLT_SENSORS 0x04 +#define FTS_FAN_SOURCE_INVALID 0xff + static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; static const struct i2c_device_id fts_id[] = { @@ -187,7 +186,7 @@ static int fts_update_device(struct fts_data *data) data->fan_source[i] = err; } else { data->fan_input[i] = 0; - data->fan_source[i] = 0; + data->fan_source[i] = FTS_FAN_SOURCE_INVALID; } } @@ -339,50 +338,6 @@ static int fts_watchdog_init(struct fts_data *data) return devm_watchdog_register_device(&data->client->dev, &data->wdd); } -static ssize_t fan_source_show(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct fts_data *data = dev_get_drvdata(dev); - int index = to_sensor_dev_attr(devattr)->index; - int err; - - err = fts_update_device(data); - if (err < 0) - return err; - - return sprintf(buf, "%u\n", data->fan_source[index]); -} - -static SENSOR_DEVICE_ATTR_RO(fan1_source, fan_source, 0); -static SENSOR_DEVICE_ATTR_RO(fan2_source, fan_source, 1); -static SENSOR_DEVICE_ATTR_RO(fan3_source, fan_source, 2); -static SENSOR_DEVICE_ATTR_RO(fan4_source, fan_source, 3); -static SENSOR_DEVICE_ATTR_RO(fan5_source, fan_source, 4); -static SENSOR_DEVICE_ATTR_RO(fan6_source, fan_source, 5); -static SENSOR_DEVICE_ATTR_RO(fan7_source, fan_source, 6); -static SENSOR_DEVICE_ATTR_RO(fan8_source, fan_source, 7); - -static struct attribute *fts_fan_attrs[] = { - &sensor_dev_attr_fan1_source.dev_attr.attr, - &sensor_dev_attr_fan2_source.dev_attr.attr, - &sensor_dev_attr_fan3_source.dev_attr.attr, - &sensor_dev_attr_fan4_source.dev_attr.attr, - &sensor_dev_attr_fan5_source.dev_attr.attr, - &sensor_dev_attr_fan6_source.dev_attr.attr, - &sensor_dev_attr_fan7_source.dev_attr.attr, - &sensor_dev_attr_fan8_source.dev_attr.attr, - NULL -}; - -static const struct attribute_group fts_attr_group = { - .attrs = fts_fan_attrs -}; - -static const struct attribute_group *fts_attr_groups[] = { - &fts_attr_group, - NULL -}; - static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, u32 attr, int channel) { @@ -408,6 +363,7 @@ static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, break; } break; + case hwmon_pwm: case hwmon_in: return 0444; default: @@ -460,6 +416,19 @@ static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, break; } break; + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_auto_channels_temp: + if (data->fan_source[channel] == FTS_FAN_SOURCE_INVALID) + *val = 0; + else + *val = BIT(data->fan_source[channel]); + + return 0; + default: + break; + } + break; case hwmon_in: switch (attr) { case hwmon_in_input: @@ -576,6 +545,16 @@ static const struct hwmon_channel_info *fts_info[] = { HWMON_F_INPUT | HWMON_F_ALARM, HWMON_F_INPUT | HWMON_F_ALARM ), + HWMON_CHANNEL_INFO(pwm, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP + ), HWMON_CHANNEL_INFO(in, HWMON_I_INPUT, HWMON_I_INPUT, @@ -672,7 +651,7 @@ static int fts_probe(struct i2c_client *client) revision = err; hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "ftsteutates", data, - &fts_chip_info, fts_attr_groups); + &fts_chip_info, NULL); if (IS_ERR(hwmon_dev)) return PTR_ERR(hwmon_dev); From patchwork Thu Jan 5 22:51:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Armin Wolf X-Patchwork-Id: 13090658 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 633AEC4708E for ; Thu, 5 Jan 2023 22:51:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236293AbjAEWvf (ORCPT ); Thu, 5 Jan 2023 17:51:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236273AbjAEWvc (ORCPT ); Thu, 5 Jan 2023 17:51:32 -0500 Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 701CB58820; Thu, 5 Jan 2023 14:51:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1672959075; bh=jGqmtBpJFhDWl3+/3Q4iGUyNOyvE0pOn9VoLM3cxvNw=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=SX+53odXcOSY/gg9DN4453hhebH3D8CpXdcsg1EoQesO8lVZFFw1MOlmxLfQnmS6S 9SKG/gIREabUvtxNbNzB6f4TOeKLuAMBxOiVr4pS1xtKLbdsdY49FaNSuV5QJViRYZ EMRH2UH7mUZI5EQaOnNR2HM6ZqD5t0dysMc6Ut41f6XodFH3ft24G456S+n1rqotZ7 +zUAOJVnhJIXGLiHbGq2oyAlY+j8E8czcbJUepQr56GDCGRSUw3ljMLfSy2t3YmW6l zwfXLV4Y4X1nEJwMXephrlCJXZzZRREceJWSl45IMYYUK7yQeXWWXFFyLpoL2GesEU okwJmHUvEVStQ== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from esprimo-mx.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MD9XF-1p4WeY1ACP-0099E0; Thu, 05 Jan 2023 23:51:15 +0100 From: Armin Wolf To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] hwmon: (ftsteutates) Add support for fanX_fault attributes Date: Thu, 5 Jan 2023 23:51:07 +0100 Message-Id: <20230105225107.58308-4-W_Armin@gmx.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230105225107.58308-1-W_Armin@gmx.de> References: <20230105225107.58308-1-W_Armin@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:1IbpAIpZxtlA3c3W6IInAlAIKGzqpBwvLzm1zc41/PnopcAoh8x miGWNOsjZS0vMQLkqnnwObDuIfs/eEts/k/PWIXx5Cis4X52iDH690+O8GAuDEA8sa/Oj6/ ZZ+x3Abj9qDVnknFtlwx/jDx8Da4Rrp/1+SUFOsSn/b5Ra8sykx9q5y0rTBUlke+02kKQDP byOfk2kPpJaVrdQBM4t9g== UI-OutboundReport: notjunk:1;M01:P0:RrZhXS+p/QQ=;ff2fMn08FZn1+MKmcFLfPg+uqg4 GBjmVOf+eRtK8a4sOry9wMNFsHKBVQVlnvsNhrUHVXUDEmQfjG/xnqXrdxUOBUxQbCd4OKvvt wcv685P8tJo1sCDlXNUk0SuGh/xlyjt9L/0WaS7xsUq9HIeqRqcbyTjf0B8FC4rzqvIzCjuSI sSpmYmP0BpVvixZ4MuLOHQU1LbSF4zZFYpXAv9tmzYK4k3vLhGImKxWRzLTUoiWIzuSp6SzJN zm6U0dsq1maUvnoi6v0NC5j1W4KVQOxyErTvSt/QBPLnsPFC1EqNVmRcIy69g6aLf4H5j5SpW C9i80frIG6pcwPn6p/FBwLzELQgS47/HPH64rf5j2/dkbzDg1Br05U/dD6pp6J+Dm9Y67Pjbw GhjwRfuM8e4fySNAS3Ri99hwsLSCLf3Sfi22Oabxh4NsuSpH4J3YU1rfgV+X/yF09PhG/qPYO q6qdAxHEJf2xnawmybTXDV6pJ3TOIulW3tKVULpnGO3xv19FsLDtOg7+pPel/vInfN/bkI8hl JxyrhF4QXnWvQCmgF06AbwN2mrlVfSl0t8yj1iOpbkJeN7QbNv5yC/3wv+GELW8oc0Och+hgu uhpuBW3TSa1Z05oCSD0nZFpaDPGbSd57p1Af0oslCukEzHvjJcoaPOnFxnPMpF8mAS8XNfs9U CJPBgSrNkZcFNL5HVBZt2wyMdNuKJawbkJSdRBUKsBwEILPdywyIavUWM2vuW2e67ZuaUtBvG VP/ImIhyO8yWO/HQ81AGvyPfwzZD3d7rqU2trHYylGADgr74mIsLy/jnpfsJbaAeNTNyw93dl 66H5v1EMXR0nKx4DZ2Q+5I4kBOMtBfjPyiLNCtyttJjOJP7CVg8l57jApGQa2tnLKKhutQ2am 4U2bpAxaAr2SbjP7PSMU4mt+CCuJQslt+pLLnl97PPlKfjfPdfYQaLa718RPzCc6SX+QLpm75 vODjDTmiWF3iiwEdCUwhzmZTH9U= Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org The driver knows internally when a fan is not connected, but does not export this knowledge to userspace. Use the standard fanX_fault attributes to notify userspace if a fan is not connected. Tested on a Fujitsu DS3401-B1. Signed-off-by: Armin Wolf --- drivers/hwmon/ftsteutates.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) -- 2.30.2 diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index 0d8ab94250a9..25afd9167a34 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -356,6 +356,7 @@ static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, case hwmon_fan: switch (attr) { case hwmon_fan_input: + case hwmon_fan_fault: return 0444; case hwmon_fan_alarm: return 0644; @@ -411,6 +412,10 @@ static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, case hwmon_fan_alarm: *val = !!(data->fan_alarm & BIT(channel)); + return 0; + case hwmon_fan_fault: + *val = !(data->fan_present & BIT(channel)); + return 0; default: break; @@ -536,14 +541,14 @@ static const struct hwmon_channel_info *fts_info[] = { HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT ), HWMON_CHANNEL_INFO(fan, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM, - HWMON_F_INPUT | HWMON_F_ALARM + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT ), HWMON_CHANNEL_INFO(pwm, HWMON_PWM_AUTO_CHANNELS_TEMP,