From patchwork Thu Oct 20 21:03:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 13014035 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 6D80EC433FE for ; Thu, 20 Oct 2022 21:03:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229753AbiJTVDq (ORCPT ); Thu, 20 Oct 2022 17:03:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229925AbiJTVDp (ORCPT ); Thu, 20 Oct 2022 17:03:45 -0400 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BEBCCABC0; Thu, 20 Oct 2022 14:03:44 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id b12so1411903edd.6; Thu, 20 Oct 2022 14:03:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gHw/+KFKVZbjIecQIVXVGAioojTxw4dIL71FgSte190=; b=DcLN++pOsGTUM/bBGhTHiekkfMBSUqBFRiYN7viTVfr9qLgr2rh1ZD6NCtO6HnOrRY AKBduYuKXtORMXK9RcjLjWKX3x4YNXFqkBxt2FjR4i+ST4ln7Z5A0h3Ef7qcBmxWf0QO nl3SV6KCmv7qiJ7LQ2/KY7+lpIBVunBWY/HrOMCsPS224f6U3B5ciKOjcJURa2WwU80G dbKqed0CVF9AGkI3irGC7EsXaL47OGzVJwI1ZEghkszTWmSR/V9LrE4omKuRhQGYb91g p826C499e3g3XUjiJWI1Dl8dh2zzWCff/rJMTj9mjZhA+IrZHGYahYBDZdXf5Xb6u7np hAtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gHw/+KFKVZbjIecQIVXVGAioojTxw4dIL71FgSte190=; b=ZivmC8Njuwsue2h/hcn7atyGk1NR5esppl1p5DcgsBTbTUriP8byGTfiSx1mTjKxgI K3tGkUmiDUe09KmNWfEbWndhd30//i+rVrTq0ZFYrhFCzNzWw6B4ei3uvbeoVxGeiQHx RIOD9vQDsOWqXxUlkljriAchxYnOzuPWoJSl17Jp9fu6fJi2jzxc4UZktPcRZ3luswsd loqwTSJMU5z6K35JpZURizSigzrJZm/qvq2AoyD1O3af6FBaZAbotTXmbWlh5iNd/904 gAnhFaGv4vnq8zFH7NjSJaAaOcVvZHdBDVt/TkF6RdXeXxXZ4w4hs2WE79QUbAqoevc2 lvjg== X-Gm-Message-State: ACrzQf1Ekz3HpZOiiaBPLlgs6YCC+8K/BY8o3HAY5qFQRTf/w/k8Uhmc XOn1T8oFOSukARnWEAHj6LTrj/Yoc90= X-Google-Smtp-Source: AMsMyM6F3Uw6RFZv+xkLM7GwFHbkdqHL3nfta9o1T2+0lxdYVEeCFjesYoYbZHgu11HIG+jby4ZaQw== X-Received: by 2002:a05:6402:1cc1:b0:45c:3a90:9499 with SMTP id ds1-20020a0564021cc100b0045c3a909499mr14262814edb.61.1666299822800; Thu, 20 Oct 2022 14:03:42 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c046-3500-0000-0000-0000-0e63.c23.pool.telefonica.de. [2a01:c23:c046:3500::e63]) by smtp.googlemail.com with ESMTPSA id 18-20020a170906211200b00779cde476e4sm10748721ejt.62.2022.10.20.14.03.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 14:03:42 -0700 (PDT) From: Martin Blumenstingl To: linux@roeck-us.net, linux-hwmon@vger.kernel.org Cc: jdelvare@suse.com, linux-kernel@vger.kernel.org, Martin Blumenstingl Subject: [RFC PATCH v2 1/4] hwmon: (jc42) Convert register access to use an I2C regmap Date: Thu, 20 Oct 2022 23:03:17 +0200 Message-Id: <20221020210320.1624617-2-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> References: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Switch the jc42 driver to use an I2C regmap to access the registers. This is done in preparation for improving the caching of registers and to restore the cached limits during system resume. Signed-off-by: Martin Blumenstingl --- drivers/hwmon/Kconfig | 1 + drivers/hwmon/jc42.c | 102 +++++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 7ac3daaf59ce..d3bccc8176c5 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -799,6 +799,7 @@ config SENSORS_IT87 config SENSORS_JC42 tristate "JEDEC JC42.4 compliant memory module temperature sensors" depends on I2C + select REGMAP_I2C help If you say yes here, you get support for JEDEC JC42.4 compliant temperature sensors, which are used on many DDR3 memory modules for diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 30888feaf589..329a80264556 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { @@ -216,7 +217,7 @@ static const u8 temp_regs[t_num_temp] = { /* Each client has this additional data */ struct jc42_data { - struct i2c_client *client; + struct regmap *regmap; struct mutex update_lock; /* protect register access */ bool extended; /* true if extended range supported */ bool valid; @@ -251,19 +252,16 @@ static int jc42_temp_from_reg(s16 reg) static struct jc42_data *jc42_update_device(struct device *dev) { struct jc42_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - struct jc42_data *ret = data; - int i, val; + unsigned int i, val; + int ret; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { for (i = 0; i < t_num_temp; i++) { - val = i2c_smbus_read_word_swapped(client, temp_regs[i]); - if (val < 0) { - ret = ERR_PTR(val); + ret = regmap_read(data->regmap, temp_regs[i], &val); + if (ret) goto abort; - } data->temp[i] = val; } data->last_updated = jiffies; @@ -271,7 +269,7 @@ static struct jc42_data *jc42_update_device(struct device *dev) } abort: mutex_unlock(&data->update_lock); - return ret; + return ret ? ERR_PTR(ret) : data; } static int jc42_read(struct device *dev, enum hwmon_sensor_types type, @@ -326,7 +324,6 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { struct jc42_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; int diff, hyst; int ret; @@ -335,18 +332,18 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, switch (attr) { case hwmon_temp_min: data->temp[t_min] = jc42_temp_to_reg(val, data->extended); - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min], - data->temp[t_min]); + ret = regmap_write(data->regmap, temp_regs[t_min], + data->temp[t_min]); break; case hwmon_temp_max: data->temp[t_max] = jc42_temp_to_reg(val, data->extended); - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max], - data->temp[t_max]); + ret = regmap_write(data->regmap, temp_regs[t_max], + data->temp[t_max]); break; case hwmon_temp_crit: data->temp[t_crit] = jc42_temp_to_reg(val, data->extended); - ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit], - data->temp[t_crit]); + ret = regmap_write(data->regmap, temp_regs[t_crit], + data->temp[t_crit]); break; case hwmon_temp_crit_hyst: /* @@ -368,9 +365,8 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, } data->config = (data->config & ~JC42_CFG_HYST_MASK) | (hyst << JC42_CFG_HYST_SHIFT); - ret = i2c_smbus_write_word_swapped(data->client, - JC42_REG_CONFIG, - data->config); + ret = regmap_write(data->regmap, JC42_REG_CONFIG, + data->config); break; default: ret = -EOPNOTSUPP; @@ -470,51 +466,79 @@ static const struct hwmon_chip_info jc42_chip_info = { .info = jc42_info, }; +static bool jc42_readable_reg(struct device *dev, unsigned int reg) +{ + return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) || + reg == JC42_REG_SMBUS; +} + +static bool jc42_writable_reg(struct device *dev, unsigned int reg) +{ + return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) || + reg == JC42_REG_SMBUS; +} + +static bool jc42_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP; +} + +static const struct regmap_config jc42_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = JC42_REG_SMBUS, + .writeable_reg = jc42_writable_reg, + .readable_reg = jc42_readable_reg, + .volatile_reg = jc42_volatile_reg, +}; + static int jc42_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct device *hwmon_dev; + unsigned int config, cap; struct jc42_data *data; - int config, cap; + int ret; data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); if (!data) return -ENOMEM; - data->client = client; + data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); - if (cap < 0) - return cap; + ret = regmap_read(data->regmap, JC42_REG_CAP, &cap); + if (ret) + return ret; data->extended = !!(cap & JC42_CAP_RANGE); if (device_property_read_bool(dev, "smbus-timeout-disable")) { - int smbus; - /* * Not all chips support this register, but from a * quick read of various datasheets no chip appears * incompatible with the below attempt to disable * the timeout. And the whole thing is opt-in... */ - smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS); - if (smbus < 0) - return smbus; - i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS, - smbus | SMBUS_STMOUT); + ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS, + SMBUS_STMOUT); + if (ret) + return ret; } - config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); - if (config < 0) - return config; + ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config); + if (ret) + return ret; data->orig_config = config; if (config & JC42_CFG_SHUTDOWN) { config &= ~JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); + regmap_write(data->regmap, JC42_REG_CONFIG, config); } data->config = config; @@ -535,7 +559,7 @@ static void jc42_remove(struct i2c_client *client) config = (data->orig_config & ~JC42_CFG_HYST_MASK) | (data->config & JC42_CFG_HYST_MASK); - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); + regmap_write(data->regmap, JC42_REG_CONFIG, config); } } @@ -546,8 +570,7 @@ static int jc42_suspend(struct device *dev) struct jc42_data *data = dev_get_drvdata(dev); data->config |= JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, - data->config); + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); return 0; } @@ -556,8 +579,7 @@ static int jc42_resume(struct device *dev) struct jc42_data *data = dev_get_drvdata(dev); data->config &= ~JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, - data->config); + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); return 0; } From patchwork Thu Oct 20 21:03:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 13014036 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 A343BC43217 for ; Thu, 20 Oct 2022 21:03:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229939AbiJTVDr (ORCPT ); Thu, 20 Oct 2022 17:03:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229929AbiJTVDq (ORCPT ); Thu, 20 Oct 2022 17:03:46 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 46ED6CABC4; Thu, 20 Oct 2022 14:03:45 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id b2so2532088eja.6; Thu, 20 Oct 2022 14:03:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=91jTp+vVBC1xOtBKmUzVXsrC90O9nlN7ucaxFP7eflw=; b=hYiKVyh8jRh+Q8Z+uKI1QnM+J+GZKFFzW995sNAH0k1n0J6RAGOkmFbrAfnXkOCtUu NoQFd4G93JmgZp6VB/8RIXBSGMKMsDW6q7qleTpWj3TVXLP11AWSH36gbEU9NAvbn1Si qn5s+MXslAElNnT67RIBd4PTVydhHCIv32bCunnlh8/OB0OCCU3i2VOoYsWXUEt+1irj fKnLmRxTi3yx4HBLcnQzzk+wpfeMYUgOiUAxMjgmo020wJqPSSG3x0NBzAKrE9/csQbB QHNaU+WJy3W88ZI6sw11gIk8J/tH//dT8i7AX2AGIDcXubtvD8LwkqHuUTp3BVD+05m5 IxRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=91jTp+vVBC1xOtBKmUzVXsrC90O9nlN7ucaxFP7eflw=; b=FcW8r7VwHomsG8Q6EjUleWwCf+jhl4ZQPcZgqj5BXtMjqpD1gvPsxrze0Kp1wiRl1O jodPgVUVpd2r6R+YMSi4aC3uaS4yzq6e8CQ4OsOjVEWzTQjGAeDSPjeG266vo6DrdPTi 8m9L6F7L7gnOgpUszWQHw+/z7oA/xs0kUQIUckGqOycAQe+fSNAAVa0ZMyt+5nhs96Bo sBruNMnyZPBx9dKTuZHswmUxNSvVVqumXIb+r6xgu7ubmCvBzNBbhApfTO510V81SkLh MPkjiLZ7eIE5mt9+rE9xG8fwCQgU0VG2M8V7Zcpt9kj+P4GEi2KOLSv9UWf8acDO8QTj kzvQ== X-Gm-Message-State: ACrzQf0To4lnyfp4e7biT6amAg4ndD7vtGsReJZxaDv2DE/Wxoj6VPZA 2xXFzBQgOvTv9jxqCD+hILt7WhLIS0I= X-Google-Smtp-Source: AMsMyM7qec1p6lhMfzqbJ0J+8jmaMuL+DjIT0ye2Az0/DuVbluJ34AFkDTfe+dunJjcqJbzHucii7g== X-Received: by 2002:a17:906:8447:b0:78d:776f:c544 with SMTP id e7-20020a170906844700b0078d776fc544mr12817470ejy.405.1666299823728; Thu, 20 Oct 2022 14:03:43 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c046-3500-0000-0000-0000-0e63.c23.pool.telefonica.de. [2a01:c23:c046:3500::e63]) by smtp.googlemail.com with ESMTPSA id 18-20020a170906211200b00779cde476e4sm10748721ejt.62.2022.10.20.14.03.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 14:03:43 -0700 (PDT) From: Martin Blumenstingl To: linux@roeck-us.net, linux-hwmon@vger.kernel.org Cc: jdelvare@suse.com, linux-kernel@vger.kernel.org, Martin Blumenstingl Subject: [RFC PATCH v2 2/4] hwmon: (jc42) Convert to regmap's built-in caching Date: Thu, 20 Oct 2022 23:03:18 +0200 Message-Id: <20221020210320.1624617-3-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> References: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Move over to regmap's built-in caching instead of adding a custom caching implementation. This works for JC42_REG_TEMP_UPPER, JC42_REG_TEMP_LOWER and JC42_REG_TEMP_CRITICAL as these values never change except when explicitly written. For JC42_REG_TEMP a cache variable is still kept as regmap cannot cache this register (because it's volatile, meaning it can change at any time). Signed-off-by: Martin Blumenstingl --- drivers/hwmon/jc42.c | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 329a80264556..3f524ab5451c 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -200,21 +200,6 @@ static struct jc42_chips jc42_chips[] = { { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, }; -enum temp_index { - t_input = 0, - t_crit, - t_min, - t_max, - t_num_temp -}; - -static const u8 temp_regs[t_num_temp] = { - [t_input] = JC42_REG_TEMP, - [t_crit] = JC42_REG_TEMP_CRITICAL, - [t_min] = JC42_REG_TEMP_LOWER, - [t_max] = JC42_REG_TEMP_UPPER, -}; - /* Each client has this additional data */ struct jc42_data { struct regmap *regmap; @@ -224,7 +209,7 @@ struct jc42_data { unsigned long last_updated; /* In jiffies */ u16 orig_config; /* original configuration */ u16 config; /* current configuration */ - u16 temp[t_num_temp];/* Temperatures */ + u16 temp; /* Cached temperature register value */ }; #define JC42_TEMP_MIN_EXTENDED (-40000) @@ -252,18 +237,17 @@ static int jc42_temp_from_reg(s16 reg) static struct jc42_data *jc42_update_device(struct device *dev) { struct jc42_data *data = dev_get_drvdata(dev); - unsigned int i, val; + unsigned int val; int ret; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - for (i = 0; i < t_num_temp; i++) { - ret = regmap_read(data->regmap, temp_regs[i], &val); - if (ret) - goto abort; - data->temp[i] = val; - } + ret = regmap_read(data->regmap, JC42_REG_TEMP, &val); + if (ret) + goto abort; + + data->temp = val; data->last_updated = jiffies; data->valid = true; } @@ -276,44 +260,67 @@ static int jc42_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { struct jc42_data *data = jc42_update_device(dev); - int temp, hyst; + unsigned int regval; + int ret, temp, hyst; if (IS_ERR(data)) return PTR_ERR(data); switch (attr) { case hwmon_temp_input: - *val = jc42_temp_from_reg(data->temp[t_input]); + *val = jc42_temp_from_reg(data->temp); return 0; case hwmon_temp_min: - *val = jc42_temp_from_reg(data->temp[t_min]); + ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val); + if (ret) + return ret; + + *val = jc42_temp_from_reg(regval); return 0; case hwmon_temp_max: - *val = jc42_temp_from_reg(data->temp[t_max]); + ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); + if (ret) + return ret; + + *val = jc42_temp_from_reg(regval); return 0; case hwmon_temp_crit: - *val = jc42_temp_from_reg(data->temp[t_crit]); + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) + return ret; + + *val = jc42_temp_from_reg(regval); return 0; case hwmon_temp_max_hyst: - temp = jc42_temp_from_reg(data->temp[t_max]); + ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); + if (ret) + return ret; + + temp = jc42_temp_from_reg(regval); hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) >> JC42_CFG_HYST_SHIFT]; *val = temp - hyst; return 0; case hwmon_temp_crit_hyst: - temp = jc42_temp_from_reg(data->temp[t_crit]); + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) + return ret; + + temp = jc42_temp_from_reg(regval); hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) >> JC42_CFG_HYST_SHIFT]; *val = temp - hyst; return 0; case hwmon_temp_min_alarm: - *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1; + *val = (data->temp >> JC42_ALARM_MIN_BIT) & 1; return 0; case hwmon_temp_max_alarm: - *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1; + *val = (data->temp >> JC42_ALARM_MAX_BIT) & 1; return 0; case hwmon_temp_crit_alarm: - *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1; + *val = (data->temp >> JC42_ALARM_CRIT_BIT) & 1; return 0; default: return -EOPNOTSUPP; @@ -324,6 +331,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { struct jc42_data *data = dev_get_drvdata(dev); + unsigned int regval; int diff, hyst; int ret; @@ -331,21 +339,23 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, switch (attr) { case hwmon_temp_min: - data->temp[t_min] = jc42_temp_to_reg(val, data->extended); - ret = regmap_write(data->regmap, temp_regs[t_min], - data->temp[t_min]); + ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_max: - data->temp[t_max] = jc42_temp_to_reg(val, data->extended); - ret = regmap_write(data->regmap, temp_regs[t_max], - data->temp[t_max]); + ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_crit: - data->temp[t_crit] = jc42_temp_to_reg(val, data->extended); - ret = regmap_write(data->regmap, temp_regs[t_crit], - data->temp[t_crit]); + ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_crit_hyst: + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) + return ret; + /* * JC42.4 compliant chips only support four hysteresis values. * Pick best choice and go from there. @@ -353,7 +363,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED : JC42_TEMP_MIN) - 6000, JC42_TEMP_MAX); - diff = jc42_temp_from_reg(data->temp[t_crit]) - val; + diff = jc42_temp_from_reg(regval) - val; hyst = 0; if (diff > 0) { if (diff < 2250) @@ -491,6 +501,7 @@ static const struct regmap_config jc42_regmap_config = { .writeable_reg = jc42_writable_reg, .readable_reg = jc42_readable_reg, .volatile_reg = jc42_volatile_reg, + .cache_type = REGCACHE_RBTREE, }; static int jc42_probe(struct i2c_client *client) From patchwork Thu Oct 20 21:03:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 13014037 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 5F02EC43219 for ; Thu, 20 Oct 2022 21:03:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229823AbiJTVDs (ORCPT ); Thu, 20 Oct 2022 17:03:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47630 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229934AbiJTVDr (ORCPT ); Thu, 20 Oct 2022 17:03:47 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DEC3CABC0; Thu, 20 Oct 2022 14:03:46 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id g27so1374018edf.11; Thu, 20 Oct 2022 14:03:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VcGsClt3EeHDOcwNreFbmj7M3tyyEYsggkdvW5UHGGM=; b=oLpOq5hMgEz8wPlei0nKhKh1Xpou/ksdbhusfa3NMyvCI+C68vxtrpTI3riwbsjvlY Qle2gY108r3XtwAq8ZMxr0pFoh2T0KANSzSE+E46ZQJ9WzE0qznHwSI47NAJ8n4diFjJ 7Mbn61S6+dLcsKHBhLkyWAPq6kjruhblVmQqXCueZsTBp1WU1dLT8n07EyyLejdsz78v CIznAV8C0b5gW3xtPT/fduziMZK6MxewF+sHN4jTqPbhARuwsiuO0wnE9YgoU+zhDLke 4Xxm6RFVoddWhPQiRdmsxGTBq7zek+LIl7kCWuEixLji89BK1eZJGgYe849e+t2F9Sz4 78IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VcGsClt3EeHDOcwNreFbmj7M3tyyEYsggkdvW5UHGGM=; b=vZzY93TsHc302d2Rgl/GU2pJnNNjmrYpcqboBKatEi9q+i/bVKkTwfnFNxN1+aOQ5I fuTB7xAsA9mvKwA2G07zNz1kc3vy9EGxZrTXfiHMpZcmaFc0OtJx2833cWDvZFubl2rG xzvdJhtgKpotUZmwHgab+z6r90H9c4THs91Mmyip/aIbuztVNcI+XGWNBg7YO/tWd/03 kYKLmDikmvvF0HsT5Wf4y3pVyhbZ1i5c/tRikLy+8XYVO6MIIm3+fjsHWJiWX4GJNrS9 ++QUSkTqlJUatzRCg6FKGm4xKCC3COkuitB1stt1nJBMWx9ke9S+tsZFHiwxf4hXObKZ 5DCA== X-Gm-Message-State: ACrzQf1r/s4xDS9cJcnPnxQXQOiSD6Rcc8TRwfTqs5HBQW50TM4jPcjj ssQcyWsMtWTARQaLl+wKbxY= X-Google-Smtp-Source: AMsMyM53hf5WFVTFQ/0Etgg2GbkKIWsfEPAwVjQ8peO0OvmUyC9OYc9QlAIQHgybBr3PzknZ6m7aZw== X-Received: by 2002:a05:6402:26d2:b0:45d:280b:5878 with SMTP id x18-20020a05640226d200b0045d280b5878mr14204625edd.385.1666299824877; Thu, 20 Oct 2022 14:03:44 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c046-3500-0000-0000-0000-0e63.c23.pool.telefonica.de. [2a01:c23:c046:3500::e63]) by smtp.googlemail.com with ESMTPSA id 18-20020a170906211200b00779cde476e4sm10748721ejt.62.2022.10.20.14.03.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 14:03:44 -0700 (PDT) From: Martin Blumenstingl To: linux@roeck-us.net, linux-hwmon@vger.kernel.org Cc: jdelvare@suse.com, linux-kernel@vger.kernel.org, Martin Blumenstingl Subject: [RFC PATCH v2 3/4] hwmon: (jc42) Restore the min/max/critical temperatures on resume Date: Thu, 20 Oct 2022 23:03:19 +0200 Message-Id: <20221020210320.1624617-4-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> References: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org The JC42 compatible thermal sensor on Kingston KSM32ES8/16ME DIMMs (using Micron E-Die) is an ST Microelectronics STTS2004 (manufacturer 0x104a, device 0x2201). It does not keep the previously programmed minimum, maximum and critical temperatures after system suspend and resume (which is a shutdown / startup cycle for the JC42 temperature sensor). This results in an alarm on system resume because the hardware default for these values is 0°C (so any environment temperature greater than 0°C will trigger the alarm). Example before system suspend: jc42-i2c-0-1a Adapter: SMBus PIIX4 adapter port 0 at 0b00 temp1: +34.8°C (low = +0.0°C) (high = +85.0°C, hyst = +85.0°C) (crit = +95.0°C, hyst = +95.0°C) Example after system resume (without this change): jc42-i2c-0-1a Adapter: SMBus PIIX4 adapter port 0 at 0b00 temp1: +34.8°C (low = +0.0°C) ALARM (HIGH, CRIT) (high = +0.0°C, hyst = +0.0°C) (crit = +0.0°C, hyst = +0.0°C) Apply the cached values from the JC42_REG_TEMP_UPPER, JC42_REG_TEMP_LOWER, JC42_REG_TEMP_CRITICAL and JC42_REG_SMBUS (where the SMBUS register is not related to this issue but a side-effect of using regcache_sync() during system resume with the previously cached/programmed values. This fixes the alarm due to the hardware defaults of 0°C because the previously applied limits (set by userspace) are re-applied on system resume. Fixes: 175c490c9e7f ("hwmon: (jc42) Add support for STTS2004 and AT30TSE004") Signed-off-by: Martin Blumenstingl --- drivers/hwmon/jc42.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 3f524ab5451c..61311483a5c6 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -582,6 +582,10 @@ static int jc42_suspend(struct device *dev) data->config |= JC42_CFG_SHUTDOWN; regmap_write(data->regmap, JC42_REG_CONFIG, data->config); + + regcache_cache_only(data->regmap, true); + regcache_mark_dirty(data->regmap); + return 0; } @@ -589,9 +593,13 @@ static int jc42_resume(struct device *dev) { struct jc42_data *data = dev_get_drvdata(dev); + regcache_cache_only(data->regmap, false); + data->config &= ~JC42_CFG_SHUTDOWN; regmap_write(data->regmap, JC42_REG_CONFIG, data->config); - return 0; + + /* Restore cached register values to hardware */ + return regcache_sync(data->regmap); } static const struct dev_pm_ops jc42_dev_pm_ops = { From patchwork Thu Oct 20 21:03:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 13014038 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 6C431C4332F for ; Thu, 20 Oct 2022 21:04:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229934AbiJTVEI (ORCPT ); Thu, 20 Oct 2022 17:04:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229961AbiJTVDt (ORCPT ); Thu, 20 Oct 2022 17:03:49 -0400 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 072BCCABC7; Thu, 20 Oct 2022 14:03:47 -0700 (PDT) Received: by mail-ed1-x52d.google.com with SMTP id a67so1365396edf.12; Thu, 20 Oct 2022 14:03:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qxDfXjVat7Kys3E9Hetmxuq6ShOthTcFMt0dPFfzKbQ=; b=D8hXj+ChWswhe8UJrupSd4sNYASfYoDr07zqXfug9iPu9Ljxrsd/WQ84QMLzpJT46p IMwKw2MgZ103Ax6dPFPeJ+Vedme4vcFZUOdwa1l6Khkk2NItYJeIFc1Ve1e+d0XcCXml b+5qHBcLEwVlan/fAyjDXlV6qZnVKyLaPrfhQHA6k5mGpZZ2pKPEBmOramwK4Qwj7vrN q3rX54KOWu+u6DW3iZCG0iVPhddJOj+ZKeQMs/d7I77aiwzrkFVp/JOkM4LsotLW7n8i 2fx+ZdVJOG6tW0EjS3mQv7hTTjNHv61NAVcToRYOriTrBUcXShIx+Zhh4doR9tjRGX0K iPrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qxDfXjVat7Kys3E9Hetmxuq6ShOthTcFMt0dPFfzKbQ=; b=RzKH8ykXPOxzYYFvx9koh5yb/0FAQ/H9PlJDdEo2t80dmpaJ2lideLYQOyuR0ZppQV kbRmShLAQMaj0yNwYElGIU4ERXXdomI4cjt1jud6YMqK0G0lgdgUqvhvcXpE4UAs+mfD U4CB5BU6+fyxbbV5ZqWzfXahw2TMWje5qzrRQV/NfZ+4BeuYoS7qE9PwOr2Ewe4x5hXI 3pUb2yyeEYKk+r+m/d+JNUoLmu5ZikBnmfuLqaWDPccMyNNZuYuzh+lqMISuYlO8k0mX AGKWQeSO+WhKCerBUWiQBDipofjJur9WcfAadLCq1tFWTpKNZwxwzCrRFTaRSbMtNTrF NMVA== X-Gm-Message-State: ACrzQf2iHvyoZtgOh0ifGkJqe59l2VFQsJzK7Xr0b3djR1gCKhViDjSd Kq/bih8u1lJe4pJkZJ0T1jk= X-Google-Smtp-Source: AMsMyM7fmIolWQu5P5hRljBOaKGe/fWqGpMhwL4KbCOrpkKS/YAp8rcw6q3b6koeaLGzX/5Uy4TGsw== X-Received: by 2002:a05:6402:148a:b0:459:2eab:9b0a with SMTP id e10-20020a056402148a00b004592eab9b0amr13877085edv.139.1666299826177; Thu, 20 Oct 2022 14:03:46 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c046-3500-0000-0000-0000-0e63.c23.pool.telefonica.de. [2a01:c23:c046:3500::e63]) by smtp.googlemail.com with ESMTPSA id 18-20020a170906211200b00779cde476e4sm10748721ejt.62.2022.10.20.14.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 14:03:45 -0700 (PDT) From: Martin Blumenstingl To: linux@roeck-us.net, linux-hwmon@vger.kernel.org Cc: jdelvare@suse.com, linux-kernel@vger.kernel.org, Martin Blumenstingl Subject: [RFC PATCH v2 4/4] hwmon: (jc42) Don't cache the temperature register Date: Thu, 20 Oct 2022 23:03:20 +0200 Message-Id: <20221020210320.1624617-5-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> References: <20221020210320.1624617-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Now that we're utilizing regmap and it's regcache for the minimum/maximum/critical temperature registers the only cached register that's left is the actual temperature register. Drop the custom cache implementation as it just complicates things. Signed-off-by: Martin Blumenstingl --- drivers/hwmon/jc42.c | 59 ++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 61311483a5c6..52a60eb0791b 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -203,13 +203,10 @@ static struct jc42_chips jc42_chips[] = { /* Each client has this additional data */ struct jc42_data { struct regmap *regmap; - struct mutex update_lock; /* protect register access */ bool extended; /* true if extended range supported */ bool valid; - unsigned long last_updated; /* In jiffies */ u16 orig_config; /* original configuration */ u16 config; /* current configuration */ - u16 temp; /* Cached temperature register value */ }; #define JC42_TEMP_MIN_EXTENDED (-40000) @@ -234,41 +231,20 @@ static int jc42_temp_from_reg(s16 reg) return reg * 125 / 2; } -static struct jc42_data *jc42_update_device(struct device *dev) -{ - struct jc42_data *data = dev_get_drvdata(dev); - unsigned int val; - int ret; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - ret = regmap_read(data->regmap, JC42_REG_TEMP, &val); - if (ret) - goto abort; - - data->temp = val; - data->last_updated = jiffies; - data->valid = true; - } -abort: - mutex_unlock(&data->update_lock); - return ret ? ERR_PTR(ret) : data; -} - static int jc42_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { - struct jc42_data *data = jc42_update_device(dev); + struct jc42_data *data = dev_get_drvdata(dev); unsigned int regval; int ret, temp, hyst; - if (IS_ERR(data)) - return PTR_ERR(data); - switch (attr) { case hwmon_temp_input: - *val = jc42_temp_from_reg(data->temp); + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + return ret; + + *val = jc42_temp_from_reg(regval); return 0; case hwmon_temp_min: ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val); @@ -314,13 +290,25 @@ static int jc42_read(struct device *dev, enum hwmon_sensor_types type, *val = temp - hyst; return 0; case hwmon_temp_min_alarm: - *val = (data->temp >> JC42_ALARM_MIN_BIT) & 1; + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + return ret; + + *val = (regval >> JC42_ALARM_MIN_BIT) & 1; return 0; case hwmon_temp_max_alarm: - *val = (data->temp >> JC42_ALARM_MAX_BIT) & 1; + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + return ret; + + *val = (regval >> JC42_ALARM_MAX_BIT) & 1; return 0; case hwmon_temp_crit_alarm: - *val = (data->temp >> JC42_ALARM_CRIT_BIT) & 1; + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + return ret; + + *val = (regval >> JC42_ALARM_CRIT_BIT) & 1; return 0; default: return -EOPNOTSUPP; @@ -335,8 +323,6 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, int diff, hyst; int ret; - mutex_lock(&data->update_lock); - switch (attr) { case hwmon_temp_min: ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER, @@ -383,8 +369,6 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, break; } - mutex_unlock(&data->update_lock); - return ret; } @@ -521,7 +505,6 @@ static int jc42_probe(struct i2c_client *client) return PTR_ERR(data->regmap); i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); ret = regmap_read(data->regmap, JC42_REG_CAP, &cap); if (ret)