From patchwork Tue Aug 7 08:57:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: IKEGAMI Tokunori X-Patchwork-Id: 10558403 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69C331390 for ; Tue, 7 Aug 2018 08:58:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5960329B73 for ; Tue, 7 Aug 2018 08:58:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4DE9729B76; Tue, 7 Aug 2018 08:58:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,URIBL_SBL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 082C329B83 for ; Tue, 7 Aug 2018 08:58:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732703AbeHGLMI (ORCPT ); Tue, 7 Aug 2018 07:12:08 -0400 Received: from mail1.bemta23.messagelabs.com ([67.219.246.210]:61577 "EHLO mail1.bemta23.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727669AbeHGLMI (ORCPT ); Tue, 7 Aug 2018 07:12:08 -0400 Received: from [67.219.247.52] (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256 bits)) by server-3.bemta.az-d.us-east-1.aws.symcld.net id 83/5D-01612-74F596B5; Tue, 07 Aug 2018 08:58:47 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeJIrShJLcpLzFFi42KZFv5DRNc9PjP a4N03NYv211sZHRg9Pm+SC2CMYs3MS8qvSGDNuHbqJXvBUoeKW4vnMzcwNpt0MXJxCAnMYZTo ndLKDOH8ZJT4c/0KkMPJwSZgKjH91UJGEFtEQEViy7o1YEXMAqsYJb4vO8AEkhAWCJbYtmAem M0ioCrRd+geSxcjBwevgKPE+nmVIGEJAXmJw2+aWEFsTgEniUvP28BmCgGVdFxZwgJha0o87/ nOCFEfLPFw6ySWCYy8CxgZVjGaJRVlpmeU5CZm5ugaGhjoGhoa6VroGpoa6SVW6abolRbrpiY Wl+ga6iWWF+sVV+Ym56To5aWWbGIEhgoDEOxg7JmdeohRkoNJSZS3SDkzWogvKT+lMiOxOCO+ qDQntfgQowwHh5IEr14cUE6wKDU9tSItMwcYtDBpCQ4eJRHeHJA0b3FBYm5xZjpE6hSjMcef9 1MnMXPs6542iVmIJS8/L1VKnLcWpFQApDSjNA9uECyaLjHKSgnzMgKdJsRTkFqUm1mCKv+KUZ yDUUmY93ss0BSezLwSuH2vgE5hAjrljTbYKSWJCCmpBkbPOVybZjddu2D+p+nSVZUt/+dnhl0 93PBjS8L6W5tn/A2qyd/ynTd5v+AB3oe6U9jeXP5iccHvs3Vt5SWPH9Kzg1mYEuIYNl2bUbFF /0BOT+mEn0ueKs7cs2hDsM0LtqePrZ7Ga/6rSC6vDt3M11j7093n3Z2VC1e5yfJ3/o/gMWj4f eKwZb+LEktxRqKhFnNRcSIAjKoe86ECAAA= X-Env-Sender: ikegami@allied-telesis.co.jp X-Msg-Ref: server-17.tower-424.messagelabs.com!1533632326!1613165!1 X-Originating-IP: [150.87.248.20] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.9.15; banners=-,-,- X-VirusChecked: Checked Received: (qmail 7750 invoked from network); 7 Aug 2018 08:58:47 -0000 Received: from abricot-inet.allied-telesis.co.jp (HELO TKY-DS01.at.lc) (150.87.248.20) by server-17.tower-424.messagelabs.com with SMTP; 7 Aug 2018 08:58:47 -0000 Received: from swim-manx.rd.allied-telesis.co.jp ([150.87.21.50]) by TKY-DS01.at.lc with Microsoft SMTPSVC(8.0.9200.16384); Tue, 7 Aug 2018 17:58:46 +0900 Received: from ikegami-pc.rd.allied-telesis.co.jp by swim-manx.rd.allied-telesis.co.jp (AlliedTelesis SMTPRS 1.3 pl 1 ++E6B86F8C687C6288D9B5559052954DC9) with ESMTP id ; Tue, 7 Aug 2018 17:58:45 +0900 From: Tokunori Ikegami To: Jean Delvare Cc: Tokunori Ikegami , Guenter Roeck , Chris Packham , linux-hwmon@vger.kernel.org Subject: [PATCH 3/4] hwmon: (adt7475) Change update functions to add error handling Date: Tue, 7 Aug 2018 17:57:32 +0900 Message-Id: <20180807085733.28756-4-ikegami@allied-telesis.co.jp> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180807085733.28756-1-ikegami@allied-telesis.co.jp> References: <20180807085733.28756-1-ikegami@allied-telesis.co.jp> X-OriginalArrivalTime: 07 Aug 2018 08:58:46.0155 (UTC) FILETIME=[D968CDB0:01D42E2C] Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I2C SMBus is sometimes possible to return error codes. And at the error case the measurement values are updated incorrectly. The sensor application sends warning log message and SNMP trap. To prevent this add error handling into the update functions. Signed-off-by: Tokunori Ikegami Cc: Guenter Roeck Cc: Chris Packham Cc: linux-hwmon@vger.kernel.org --- drivers/hwmon/adt7475.c | 202 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 158 insertions(+), 44 deletions(-) diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 5f03a93632c3..fb89b88f1998 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -1658,127 +1658,236 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) } } -static void adt7475_update_measure(struct device *dev) +static int adt7475_update_measure(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adt7475_data *data = i2c_get_clientdata(client); u16 ext; int i; + int ret; - data->alarms = adt7475_read(REG_STATUS2) << 8; - data->alarms |= adt7475_read(REG_STATUS1); + ret = adt7475_read(REG_STATUS2); + if (ret < 0) + return ret; + data->alarms = ret << 8; + + ret = adt7475_read(REG_STATUS1); + if (ret < 0) + return ret; + data->alarms |= ret; + + ret = adt7475_read(REG_EXTEND2); + if (ret < 0) + return ret; + + ext = (ret << 8); + + ret = adt7475_read(REG_EXTEND1); + if (ret < 0) + return ret; + + ext |= ret; - ext = (adt7475_read(REG_EXTEND2) << 8) | - adt7475_read(REG_EXTEND1); for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { if (!(data->has_voltage & (1 << i))) continue; + ret = adt7475_read(VOLTAGE_REG(i)); + if (ret < 0) + return ret; data->voltage[INPUT][i] = - (adt7475_read(VOLTAGE_REG(i)) << 2) | + (ret << 2) | ((ext >> (i * 2)) & 3); } - for (i = 0; i < ADT7475_TEMP_COUNT; i++) + for (i = 0; i < ADT7475_TEMP_COUNT; i++) { + ret = adt7475_read(TEMP_REG(i)); + if (ret < 0) + return ret; data->temp[INPUT][i] = - (adt7475_read(TEMP_REG(i)) << 2) | + (ret << 2) | ((ext >> ((i + 5) * 2)) & 3); + } if (data->has_voltage & (1 << 5)) { - data->alarms |= adt7475_read(REG_STATUS4) << 24; - ext = adt7475_read(REG_EXTEND3); - data->voltage[INPUT][5] = adt7475_read(REG_VTT) << 2 | + ret = adt7475_read(REG_STATUS4); + if (ret < 0) + return ret; + data->alarms |= ret << 24; + + ret = adt7475_read(REG_EXTEND3); + if (ret < 0) + return ret; + ext = ret; + + ret = adt7475_read(REG_VTT); + if (ret < 0) + return ret; + data->voltage[INPUT][5] = ret << 2 | ((ext >> 4) & 3); } for (i = 0; i < ADT7475_TACH_COUNT; i++) { if (i == 3 && !data->has_fan4) continue; - data->tach[INPUT][i] = - adt7475_read_word(client, TACH_REG(i)); + ret = adt7475_read_word(client, TACH_REG(i)); + if (ret < 0) + return ret; + data->tach[INPUT][i] = ret; } /* Updated by hw when in auto mode */ for (i = 0; i < ADT7475_PWM_COUNT; i++) { if (i == 1 && !data->has_pwm2) continue; - data->pwm[INPUT][i] = adt7475_read(PWM_REG(i)); + ret = adt7475_read(PWM_REG(i)); + if (ret < 0) + return ret; + data->pwm[INPUT][i] = ret; } - if (data->has_vid) - data->vid = adt7475_read(REG_VID) & 0x3f; + if (data->has_vid) { + ret = adt7475_read(REG_VID); + if (ret < 0) + return ret; + data->vid = ret & 0x3f; + } + + return 0; } -static void adt7475_update_limits(struct device *dev) +static int adt7475_update_limits(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adt7475_data *data = i2c_get_clientdata(client); int i; + int ret; - data->config4 = adt7475_read(REG_CONFIG4); - data->config5 = adt7475_read(REG_CONFIG5); + ret = adt7475_read(REG_CONFIG4); + if (ret < 0) + return ret; + data->config4 = ret; + + ret = adt7475_read(REG_CONFIG5); + if (ret < 0) + return ret; + data->config5 = ret; for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { if (!(data->has_voltage & (1 << i))) continue; /* Adjust values so they match the input precision */ - data->voltage[MIN][i] = - adt7475_read(VOLTAGE_MIN_REG(i)) << 2; - data->voltage[MAX][i] = - adt7475_read(VOLTAGE_MAX_REG(i)) << 2; + ret = adt7475_read(VOLTAGE_MIN_REG(i)); + if (ret < 0) + return ret; + data->voltage[MIN][i] = ret << 2; + + ret = adt7475_read(VOLTAGE_MAX_REG(i)); + if (ret < 0) + return ret; + data->voltage[MAX][i] = ret << 2; } if (data->has_voltage & (1 << 5)) { - data->voltage[MIN][5] = adt7475_read(REG_VTT_MIN) << 2; - data->voltage[MAX][5] = adt7475_read(REG_VTT_MAX) << 2; + ret = adt7475_read(REG_VTT_MIN); + if (ret < 0) + return ret; + data->voltage[MIN][5] = ret << 2; + + ret = adt7475_read(REG_VTT_MAX); + if (ret < 0) + return ret; + data->voltage[MAX][5] = ret << 2; } for (i = 0; i < ADT7475_TEMP_COUNT; i++) { /* Adjust values so they match the input precision */ - data->temp[MIN][i] = - adt7475_read(TEMP_MIN_REG(i)) << 2; - data->temp[MAX][i] = - adt7475_read(TEMP_MAX_REG(i)) << 2; - data->temp[AUTOMIN][i] = - adt7475_read(TEMP_TMIN_REG(i)) << 2; - data->temp[THERM][i] = - adt7475_read(TEMP_THERM_REG(i)) << 2; - data->temp[OFFSET][i] = - adt7475_read(TEMP_OFFSET_REG(i)); + ret = adt7475_read(TEMP_MIN_REG(i)); + if (ret < 0) + return ret; + data->temp[MIN][i] = ret << 2; + + ret = adt7475_read(TEMP_MAX_REG(i)); + if (ret < 0) + return ret; + data->temp[MAX][i] = ret << 2; + + ret = adt7475_read(TEMP_TMIN_REG(i)); + if (ret < 0) + return ret; + data->temp[AUTOMIN][i] = ret << 2; + + ret = adt7475_read(TEMP_THERM_REG(i)); + if (ret < 0) + return ret; + data->temp[THERM][i] = ret << 2; + + ret = adt7475_read(TEMP_OFFSET_REG(i)); + if (ret < 0) + return ret; + data->temp[OFFSET][i] = ret; } adt7475_read_hystersis(client); for (i = 0; i < ADT7475_TACH_COUNT; i++) { if (i == 3 && !data->has_fan4) continue; - data->tach[MIN][i] = - adt7475_read_word(client, TACH_MIN_REG(i)); + ret = adt7475_read_word(client, TACH_MIN_REG(i)); + if (ret < 0) + return ret; + data->tach[MIN][i] = ret; } for (i = 0; i < ADT7475_PWM_COUNT; i++) { if (i == 1 && !data->has_pwm2) continue; - data->pwm[MAX][i] = adt7475_read(PWM_MAX_REG(i)); - data->pwm[MIN][i] = adt7475_read(PWM_MIN_REG(i)); + ret = adt7475_read(PWM_MAX_REG(i)); + if (ret < 0) + return ret; + data->pwm[MAX][i] = ret; + + ret = adt7475_read(PWM_MIN_REG(i)); + if (ret < 0) + return ret; + data->pwm[MIN][i] = ret; /* Set the channel and control information */ adt7475_read_pwm(client, i); } - data->range[0] = adt7475_read(TEMP_TRANGE_REG(0)); - data->range[1] = adt7475_read(TEMP_TRANGE_REG(1)); - data->range[2] = adt7475_read(TEMP_TRANGE_REG(2)); + ret = adt7475_read(TEMP_TRANGE_REG(0)); + if (ret < 0) + return ret; + data->range[0] = ret; + + ret = adt7475_read(TEMP_TRANGE_REG(1)); + if (ret < 0) + return ret; + data->range[1] = ret; + + ret = adt7475_read(TEMP_TRANGE_REG(2)); + if (ret < 0) + return ret; + data->range[2] = ret; + + return 0; } static struct adt7475_data *adt7475_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adt7475_data *data = i2c_get_clientdata(client); + int ret; mutex_lock(&data->lock); /* Measurement values update every 2 seconds */ if (time_after(jiffies, data->measure_updated + HZ * 2) || !data->valid) { - adt7475_update_measure(dev); + ret = adt7475_update_measure(dev); + if (ret < 0) { + data->valid = false; + mutex_unlock(&data->lock); + return ERR_PTR(ret); + } data->measure_updated = jiffies; data->valid = true; } @@ -1786,7 +1895,12 @@ static struct adt7475_data *adt7475_update_device(struct device *dev) /* Limits and settings, should never change update every 60 seconds */ if (time_after(jiffies, data->limits_updated + HZ * 60) || !data->valid) { - adt7475_update_limits(dev); + ret = adt7475_update_limits(dev); + if (ret < 0) { + data->valid = false; + mutex_unlock(&data->lock); + return ERR_PTR(ret); + } data->limits_updated = jiffies; data->valid = true; }