From nobody Wed Apr 8 00:01:09 2026 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 3A0CBC433FE for ; Sun, 23 Oct 2022 21:32:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229682AbiJWVcf (ORCPT ); Sun, 23 Oct 2022 17:32:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229610AbiJWVc2 (ORCPT ); Sun, 23 Oct 2022 17:32:28 -0400 Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D54666874; Sun, 23 Oct 2022 14:32:26 -0700 (PDT) Received: by mail-ed1-x531.google.com with SMTP id e18so24819370edj.3; Sun, 23 Oct 2022 14:32:26 -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=o/WWyardHDeunJw22FO+VGvjkWyXMQtTw3JR+S/2Av8=; b=ENCT85RC4P/1cD6/b31zN30Cd2nQA8pOviebSGQPXlV3mGWvz+wkvaFpZmVg4anpD/ T10p3Z8trVQyrLMPX9aaAlsuSm59xPCo0aihevA9QSaPH21wdWpAeASrhWj6sHdUr3W9 lV0v93GH3Q0wpTisZTWk+mBfQG4AqApQ3v4F2hUKJhldfjSzkNcKDNvM5LxajU/VNE7y 2uSWBViWO23K6oc7zOAyJAaq9au+YWShkFQqrrGDdYP7BhUl5arhw80YEIzH1xWNoSwy D8tq0NJpCAODuQEKSST8fgZdzXUAlCOLjREtBcTLD6+Du29wXD6jtFbghYW+mJcX9uv1 4r+A== 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=o/WWyardHDeunJw22FO+VGvjkWyXMQtTw3JR+S/2Av8=; b=QFHRgd2mXjccZZn32J+yUgSsQm/MhYC+Fugv6URk1mq4kT+QqnIJAdR/x8kmgA8K+Y vgZuWsY6mN/VZ3C9NKNg9uw5acOQ2xVqDseCe2kRcFoL9nLp+96pMHZ1LiyonSkHzcoj dQaSdApJhFGKIccIZtgH4XDYTxg3vyOvRMsx3nLPUPLdpB1kA7pczPS0J7XEOE/GEkfM X+siVm3IpEyo8RPuDDmKJ2giAnjyfFMiBWVmi8X2ixW/1oxnvyd2jhOVtWigIus4zeng TtxOBCNk7b0DVM1VRMhIsEmthKA1CfRLC4xU0ppX2z0HRxpEg/hOevlTqCQSdOQWGfVc Cu7Q== X-Gm-Message-State: ACrzQf1m+04ZXW/1HSgvqryOpCx/VNVMaXXvGxrsQco7DCp3l1gnj3Nu bCIwnv/bmpm8DY2OkucjsfA= X-Google-Smtp-Source: AMsMyM7WpIjzAia6y2jC16/sUeBgvG3k1Tr9D8Co+XHy1ScXUjdB1LYaGwgSV8F7EEYBj8vMeBXwWg== X-Received: by 2002:aa7:d889:0:b0:460:62ef:2695 with SMTP id u9-20020aa7d889000000b0046062ef2695mr17987383edq.273.1666560744801; Sun, 23 Oct 2022 14:32:24 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c10a-8500-f22f-74ff-fe21-0725.c23.pool.telefonica.de. [2a01:c23:c10a:8500:f22f:74ff:fe21:725]) by smtp.googlemail.com with ESMTPSA id p22-20020a056402045600b0044e01e2533asm17287454edw.43.2022.10.23.14.32.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 14:32:24 -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: [PATCH v4 1/2] hwmon: (jc42) Convert register access and caching to regmap/regcache Date: Sun, 23 Oct 2022 23:31:56 +0200 Message-Id: <20221023213157.11078-2-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023213157.11078-1-martin.blumenstingl@googlemail.com> References: <20221023213157.11078-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Switch the jc42 driver to use an I2C regmap to access the registers. Also 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. The cache For JC42_REG_TEMP is dropped (regmap can't cache it because it's volatile, meaning it can change at any time) as well for simplicity and consistency with other drivers. Signed-off-by: Martin Blumenstingl --- drivers/hwmon/Kconfig | 1 + drivers/hwmon/jc42.c | 233 ++++++++++++++++++++++++------------------ 2 files changed, 132 insertions(+), 102 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..355639d208d0 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 /* Addresses to scan */ static const unsigned short normal_i2c[] =3D { @@ -199,31 +200,14 @@ static struct jc42_chips jc42_chips[] =3D { { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, }; =20 -enum temp_index { - t_input =3D 0, - t_crit, - t_min, - t_max, - t_num_temp -}; - -static const u8 temp_regs[t_num_temp] =3D { - [t_input] =3D JC42_REG_TEMP, - [t_crit] =3D JC42_REG_TEMP_CRITICAL, - [t_min] =3D JC42_REG_TEMP_LOWER, - [t_max] =3D JC42_REG_TEMP_UPPER, -}; - /* Each client has this additional data */ struct jc42_data { - struct i2c_client *client; struct mutex update_lock; /* protect register access */ + struct regmap *regmap; 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[t_num_temp];/* Temperatures */ }; =20 #define JC42_TEMP_MIN_EXTENDED (-40000) @@ -248,85 +232,102 @@ static int jc42_temp_from_reg(s16 reg) return reg * 125 / 2; } =20 -static struct jc42_data *jc42_update_device(struct device *dev) -{ - struct jc42_data *data =3D dev_get_drvdata(dev); - struct i2c_client *client =3D data->client; - struct jc42_data *ret =3D data; - int i, val; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - for (i =3D 0; i < t_num_temp; i++) { - val =3D i2c_smbus_read_word_swapped(client, temp_regs[i]); - if (val < 0) { - ret =3D ERR_PTR(val); - goto abort; - } - data->temp[i] =3D val; - } - data->last_updated =3D jiffies; - data->valid =3D true; - } -abort: - mutex_unlock(&data->update_lock); - return ret; -} - static int jc42_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { - struct jc42_data *data =3D jc42_update_device(dev); - int temp, hyst; + struct jc42_data *data =3D dev_get_drvdata(dev); + unsigned int regval; + int ret, temp, hyst; =20 - if (IS_ERR(data)) - return PTR_ERR(data); + mutex_lock(&data->update_lock); =20 switch (attr) { case hwmon_temp_input: - *val =3D jc42_temp_from_reg(data->temp[t_input]); - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + + *val =3D jc42_temp_from_reg(regval); + break; case hwmon_temp_min: - *val =3D jc42_temp_from_reg(data->temp[t_min]); - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val); + if (ret) + break; + + *val =3D jc42_temp_from_reg(regval); + break; case hwmon_temp_max: - *val =3D jc42_temp_from_reg(data->temp[t_max]); - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); + if (ret) + break; + + *val =3D jc42_temp_from_reg(regval); + break; case hwmon_temp_crit: - *val =3D jc42_temp_from_reg(data->temp[t_crit]); - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) + break; + + *val =3D jc42_temp_from_reg(regval); + break; case hwmon_temp_max_hyst: - temp =3D jc42_temp_from_reg(data->temp[t_max]); + ret =3D regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); + if (ret) + break; + + temp =3D jc42_temp_from_reg(regval); hyst =3D jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) >> JC42_CFG_HYST_SHIFT]; *val =3D temp - hyst; - return 0; + break; case hwmon_temp_crit_hyst: - temp =3D jc42_temp_from_reg(data->temp[t_crit]); + ret =3D regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) + break; + + temp =3D jc42_temp_from_reg(regval); hyst =3D jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) >> JC42_CFG_HYST_SHIFT]; *val =3D temp - hyst; - return 0; + break; case hwmon_temp_min_alarm: - *val =3D (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1; - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + + *val =3D (regval >> JC42_ALARM_MIN_BIT) & 1; + break; case hwmon_temp_max_alarm: - *val =3D (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1; - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + + *val =3D (regval >> JC42_ALARM_MAX_BIT) & 1; + break; case hwmon_temp_crit_alarm: - *val =3D (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1; - return 0; + ret =3D regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + + *val =3D (regval >> JC42_ALARM_CRIT_BIT) & 1; + break; default: - return -EOPNOTSUPP; + ret =3D -EOPNOTSUPP; + break; } + + mutex_unlock(&data->update_lock); + + return ret; } =20 static int jc42_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { struct jc42_data *data =3D dev_get_drvdata(dev); - struct i2c_client *client =3D data->client; + unsigned int regval; int diff, hyst; int ret; =20 @@ -334,21 +335,23 @@ static int jc42_write(struct device *dev, enum hwmon_= sensor_types type, =20 switch (attr) { case hwmon_temp_min: - data->temp[t_min] =3D jc42_temp_to_reg(val, data->extended); - ret =3D i2c_smbus_write_word_swapped(client, temp_regs[t_min], - data->temp[t_min]); + ret =3D regmap_write(data->regmap, JC42_REG_TEMP_LOWER, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_max: - data->temp[t_max] =3D jc42_temp_to_reg(val, data->extended); - ret =3D i2c_smbus_write_word_swapped(client, temp_regs[t_max], - data->temp[t_max]); + ret =3D regmap_write(data->regmap, JC42_REG_TEMP_UPPER, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_crit: - data->temp[t_crit] =3D jc42_temp_to_reg(val, data->extended); - ret =3D i2c_smbus_write_word_swapped(client, temp_regs[t_crit], - data->temp[t_crit]); + ret =3D regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL, + jc42_temp_to_reg(val, data->extended)); break; case hwmon_temp_crit_hyst: + ret =3D 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. @@ -356,7 +359,7 @@ static int jc42_write(struct device *dev, enum hwmon_se= nsor_types type, val =3D clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED : JC42_TEMP_MIN) - 6000, JC42_TEMP_MAX); - diff =3D jc42_temp_from_reg(data->temp[t_crit]) - val; + diff =3D jc42_temp_from_reg(regval) - val; hyst =3D 0; if (diff > 0) { if (diff < 2250) @@ -368,9 +371,8 @@ static int jc42_write(struct device *dev, enum hwmon_se= nsor_types type, } data->config =3D (data->config & ~JC42_CFG_HYST_MASK) | (hyst << JC42_CFG_HYST_SHIFT); - ret =3D i2c_smbus_write_word_swapped(data->client, - JC42_REG_CONFIG, - data->config); + ret =3D regmap_write(data->regmap, JC42_REG_CONFIG, + data->config); break; default: ret =3D -EOPNOTSUPP; @@ -470,51 +472,80 @@ static const struct hwmon_chip_info jc42_chip_info = =3D { .info =3D jc42_info, }; =20 +static bool jc42_readable_reg(struct device *dev, unsigned int reg) +{ + return (reg >=3D JC42_REG_CAP && reg <=3D JC42_REG_DEVICEID) || + reg =3D=3D JC42_REG_SMBUS; +} + +static bool jc42_writable_reg(struct device *dev, unsigned int reg) +{ + return (reg >=3D JC42_REG_CONFIG && reg <=3D JC42_REG_TEMP_CRITICAL) || + reg =3D=3D JC42_REG_SMBUS; +} + +static bool jc42_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg =3D=3D JC42_REG_CONFIG || reg =3D=3D JC42_REG_TEMP; +} + +static const struct regmap_config jc42_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 16, + .val_format_endian =3D REGMAP_ENDIAN_BIG, + .max_register =3D JC42_REG_SMBUS, + .writeable_reg =3D jc42_writable_reg, + .readable_reg =3D jc42_readable_reg, + .volatile_reg =3D jc42_volatile_reg, + .cache_type =3D REGCACHE_RBTREE, +}; + static int jc42_probe(struct i2c_client *client) { struct device *dev =3D &client->dev; struct device *hwmon_dev; + unsigned int config, cap; struct jc42_data *data; - int config, cap; + int ret; =20 data =3D devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); if (!data) return -ENOMEM; =20 - data->client =3D client; + data->regmap =3D 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); =20 - cap =3D i2c_smbus_read_word_swapped(client, JC42_REG_CAP); - if (cap < 0) - return cap; + ret =3D regmap_read(data->regmap, JC42_REG_CAP, &cap); + if (ret) + return ret; =20 data->extended =3D !!(cap & JC42_CAP_RANGE); =20 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 =3D 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 =3D regmap_set_bits(data->regmap, JC42_REG_SMBUS, + SMBUS_STMOUT); + if (ret) + return ret; } =20 - config =3D i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); - if (config < 0) - return config; + ret =3D regmap_read(data->regmap, JC42_REG_CONFIG, &config); + if (ret) + return ret; =20 data->orig_config =3D config; if (config & JC42_CFG_SHUTDOWN) { config &=3D ~JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); + regmap_write(data->regmap, JC42_REG_CONFIG, config); } data->config =3D config; =20 @@ -535,7 +566,7 @@ static void jc42_remove(struct i2c_client *client) =20 config =3D (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); } } =20 @@ -546,8 +577,7 @@ static int jc42_suspend(struct device *dev) struct jc42_data *data =3D dev_get_drvdata(dev); =20 data->config |=3D 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; } =20 @@ -556,8 +586,7 @@ static int jc42_resume(struct device *dev) struct jc42_data *data =3D dev_get_drvdata(dev); =20 data->config &=3D ~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; } =20 --=20 2.38.1 From nobody Wed Apr 8 00:01:09 2026 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 51D08C433FE for ; Sun, 23 Oct 2022 21:32:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229515AbiJWVca (ORCPT ); Sun, 23 Oct 2022 17:32:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229682AbiJWVc2 (ORCPT ); Sun, 23 Oct 2022 17:32:28 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3322F66A69; Sun, 23 Oct 2022 14:32:27 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id a67so24768033edf.12; Sun, 23 Oct 2022 14:32:27 -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=tbxBj4cHR0O9Tm6ny2CUATl3dmKfE6mD40zGUFRdT3M=; b=g0Wv389vZYexEiBB6x0bUbiAzEL6HZEryQ0TfOe5RZI7qvXro8T5rWuOWXhzdhQUlS 6M2/aKbg0cjF6lmT9+wVytNsuZ21GDzemSsvCAj9raKHIdtOftwkQ4PBQ/MnFmlDLmYm uxG06CSENL8gKhT41aoXAlmeO0KfQWJj2OKv/l0xBjkp9oqlhuOpaE+W2lEFpEiiRgn+ XNPEmdm8PWQXuaV4rTcMtR5zvoXOCmc/5WLZI8COxhnUN2rW4NRqpQovD4WilaYQ/MCm 1oe/xXIbZUaAJYylvOuk/NFWKgFqQdkKQgSZ3vH2TdFVuYRf2rec0+kwypswu1PXaGRS 4vlg== 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=tbxBj4cHR0O9Tm6ny2CUATl3dmKfE6mD40zGUFRdT3M=; b=pW8eeTANYX9h+q4lfewC3pc97HRXRhaW6sfxx6ywJIPyZpL1wVYlgF4k74K6xPbJOR bYkqf/NSpnGuBGh/YKGaXnotsMSV0ZEk2V9wh0Ep/RLcPXFoEwCeo927Pock/2iobGSs TZhuaxfRUEavH3Ai9vLnLsai0fdweRNl1+UXPsoCKO2HpEC16YAzYEC5xnCxqx/9RvF9 3tDvrgbhIDedLyGZ9MAjQaiYmuYgnGrGVO4YDkaYum56efmbYv3xJA+DNYphfB35tl8e 2B5FKw/cG1l99mToDFrKSToLHoXS+vaekkZSsI0vCWSdaHHrhVrCBfFXKRscpatswYnL 37tw== X-Gm-Message-State: ACrzQf2jkN4ANqoHvPQt9kPqUDee/3lVNnOwUHMv49aabUyeMPyIGeDV E7/0GPd6Ydsfvqd0yQCQrk4= X-Google-Smtp-Source: AMsMyM5W9+MO9IuRjniRiUEW49IEKOGggkRPB2VW0P/+OJcd/E05rQHUbRqfQtlb9kud+SlAXTdz2Q== X-Received: by 2002:a05:6402:2486:b0:460:8f86:1fca with SMTP id q6-20020a056402248600b004608f861fcamr17824549eda.70.1666560745723; Sun, 23 Oct 2022 14:32:25 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a01-0c23-c10a-8500-f22f-74ff-fe21-0725.c23.pool.telefonica.de. [2a01:c23:c10a:8500:f22f:74ff:fe21:725]) by smtp.googlemail.com with ESMTPSA id p22-20020a056402045600b0044e01e2533asm17287454edw.43.2022.10.23.14.32.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 14:32:25 -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: [PATCH v4 2/2] hwmon: (jc42) Restore the min/max/critical temperatures on resume Date: Sun, 23 Oct 2022 23:31:57 +0200 Message-Id: <20221023213157.11078-3-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023213157.11078-1-martin.blumenstingl@googlemail.com> References: <20221023213157.11078-1-martin.blumenstingl@googlemail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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=C2=B0C (so any environment temperature greater than 0=C2=B0C will trigger the alarm). Example before system suspend: jc42-i2c-0-1a Adapter: SMBus PIIX4 adapter port 0 at 0b00 temp1: +34.8=C2=B0C (low =3D +0.0=C2=B0C) (high =3D +85.0=C2=B0C, hyst =3D +85.0=C2=B0C) (crit =3D +95.0=C2=B0C, hyst =3D +95.0=C2=B0C) Example after system resume (without this change): jc42-i2c-0-1a Adapter: SMBus PIIX4 adapter port 0 at 0b00 temp1: +34.8=C2=B0C (low =3D +0.0=C2=B0C) ALARM (HI= GH, CRIT) (high =3D +0.0=C2=B0C, hyst =3D +0.0=C2=B0C) (crit =3D +0.0=C2=B0C, hyst =3D +0.0=C2=B0C) 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=C2=B0C because the previously applied limits (set by userspac= e) are re-applied on system resume. Fixes: 175c490c9e7f ("hwmon: (jc42) Add support for STTS2004 and AT30TSE004= ") Reviewed-by: Guenter Roeck 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 355639d208d0..0554b41c32bc 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -578,6 +578,10 @@ static int jc42_suspend(struct device *dev) =20 data->config |=3D 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; } =20 @@ -585,9 +589,13 @@ static int jc42_resume(struct device *dev) { struct jc42_data *data =3D dev_get_drvdata(dev); =20 + regcache_cache_only(data->regmap, false); + data->config &=3D ~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); } =20 static const struct dev_pm_ops jc42_dev_pm_ops =3D { --=20 2.38.1