linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: "Guenter Roeck" <linux@roeck-us.net>,
	"Jan Kundrát" <jan.kundrat@cesnet.cz>,
	"Václav Kubernát" <kubernat@cesnet.cz>,
	"Sasha Levin" <sashal@kernel.org>,
	linux-hwmon@vger.kernel.org, linux-doc@vger.kernel.org
Subject: [PATCH AUTOSEL 5.4 37/50] hwmon: (max31790) Fix pwmX_enable attributes
Date: Sun,  4 Jul 2021 19:09:25 -0400	[thread overview]
Message-ID: <20210704230938.1490742-37-sashal@kernel.org> (raw)
In-Reply-To: <20210704230938.1490742-1-sashal@kernel.org>

From: Guenter Roeck <linux@roeck-us.net>

[ Upstream commit 148c847c9e5a54b99850617bf9c143af9a344f92 ]

pwmX_enable supports three possible values:

0: Fan control disabled. Duty cycle is fixed to 0%
1: Fan control enabled, pwm mode. Duty cycle is determined by
   values written into Target Duty Cycle registers.
2: Fan control enabled, rpm mode
   Duty cycle is adjusted such that fan speed matches
   the values in Target Count registers

The current code does not do this; instead, it mixes pwm control
configuration with fan speed monitoring configuration. Worse, it
reports that pwm control would be disabled (pwmX_enable==0) when
it is in fact enabled in pwm mode. Part of the problem may be that
the chip sets the "TACH input enable" bit on its own whenever the
mode bit is set to RPM mode, but that doesn't mean that "TACH input
enable" accurately reflects the pwm mode.

Fix it up and only handle pwm control with the pwmX_enable attributes.
In the documentation, clarify that disabling pwm control (pwmX_enable=0)
sets the pwm duty cycle to 0%. In the code, explain why TACH_INPUT_EN
is set together with RPM_MODE.

While at it, only update the configuration register if the configuration
has changed, and only update the cached configuration if updating the
chip configuration was successful.

Cc: Jan Kundrát <jan.kundrat@cesnet.cz>
Cc: Václav Kubernát <kubernat@cesnet.cz>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Václav Kubernát <kubernat@cesnet.cz>
Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
Link: https://lore.kernel.org/r/20210526154022.3223012-4-linux@roeck-us.net
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/hwmon/max31790.rst |  2 +-
 drivers/hwmon/max31790.c         | 41 ++++++++++++++++++++------------
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst
index 9f12aac4fab5..f4749c44cfb8 100644
--- a/Documentation/hwmon/max31790.rst
+++ b/Documentation/hwmon/max31790.rst
@@ -38,7 +38,7 @@ Sysfs entries
 fan[1-12]_input    RO  fan tachometer speed in RPM
 fan[1-12]_fault    RO  fan experienced fault
 fan[1-6]_target    RW  desired fan speed in RPM
-pwm[1-6]_enable    RW  regulator mode, 0=disabled, 1=manual mode, 2=rpm mode
+pwm[1-6]_enable    RW  regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode
 pwm[1-6]           RW  read: current pwm duty cycle,
                        write: target pwm duty cycle (0-255)
 ================== === =======================================================
diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
index 344be7829d58..21b6b63b1c07 100644
--- a/drivers/hwmon/max31790.c
+++ b/drivers/hwmon/max31790.c
@@ -27,6 +27,7 @@
 
 /* Fan Config register bits */
 #define MAX31790_FAN_CFG_RPM_MODE	0x80
+#define MAX31790_FAN_CFG_CTRL_MON	0x10
 #define MAX31790_FAN_CFG_TACH_INPUT_EN	0x08
 #define MAX31790_FAN_CFG_TACH_INPUT	0x01
 
@@ -271,12 +272,12 @@ static int max31790_read_pwm(struct device *dev, u32 attr, int channel,
 		*val = data->pwm[channel] >> 8;
 		return 0;
 	case hwmon_pwm_enable:
-		if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
+		if (fan_config & MAX31790_FAN_CFG_CTRL_MON)
+			*val = 0;
+		else if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
 			*val = 2;
-		else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN)
-			*val = 1;
 		else
-			*val = 0;
+			*val = 1;
 		return 0;
 	default:
 		return -EOPNOTSUPP;
@@ -307,23 +308,33 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
 	case hwmon_pwm_enable:
 		fan_config = data->fan_config[channel];
 		if (val == 0) {
-			fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN |
-					MAX31790_FAN_CFG_RPM_MODE);
+			fan_config |= MAX31790_FAN_CFG_CTRL_MON;
+			/*
+			 * Disable RPM mode; otherwise disabling fan speed
+			 * monitoring is not possible.
+			 */
+			fan_config &= ~MAX31790_FAN_CFG_RPM_MODE;
 		} else if (val == 1) {
-			fan_config = (fan_config |
-				      MAX31790_FAN_CFG_TACH_INPUT_EN) &
-				     ~MAX31790_FAN_CFG_RPM_MODE;
+			fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE);
 		} else if (val == 2) {
-			fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN |
-				      MAX31790_FAN_CFG_RPM_MODE;
+			fan_config &= ~MAX31790_FAN_CFG_CTRL_MON;
+			/*
+			 * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its
+			 * own if MAX31790_FAN_CFG_RPM_MODE is set.
+			 * Do it here as well to reflect the actual register
+			 * value in the cache.
+			 */
+			fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN);
 		} else {
 			err = -EINVAL;
 			break;
 		}
-		data->fan_config[channel] = fan_config;
-		err = i2c_smbus_write_byte_data(client,
-					MAX31790_REG_FAN_CONFIG(channel),
-					fan_config);
+		if (fan_config != data->fan_config[channel]) {
+			err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),
+							fan_config);
+			if (!err)
+				data->fan_config[channel] = fan_config;
+		}
 		break;
 	default:
 		err = -EOPNOTSUPP;
-- 
2.30.2


  parent reply	other threads:[~2021-07-04 23:23 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-04 23:08 [PATCH AUTOSEL 5.4 01/50] spi: Make of_register_spi_device also set the fwnode Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 02/50] media: mdk-mdp: fix pm_runtime_get_sync() usage count Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 03/50] media: s5p: " Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 04/50] media: sh_vou: " Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 05/50] media: mtk-vcodec: fix PM runtime get logic Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 06/50] media: s5p-jpeg: fix pm_runtime_get_sync() usage count Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 07/50] media: sti/bdisp: " Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 08/50] media: exynos-gsc: " Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 09/50] spi: spi-loopback-test: Fix 'tx_buf' might be 'rx_buf' Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 10/50] spi: spi-topcliff-pch: Fix potential double free in pch_spi_process_messages() Sasha Levin
2021-07-04 23:08 ` [PATCH AUTOSEL 5.4 11/50] spi: omap-100k: Fix the length judgment problem Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 12/50] regulator: uniphier: Add missing MODULE_DEVICE_TABLE Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 13/50] hwrng: exynos - Fix runtime PM imbalance on error Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 14/50] crypto: nx - add missing MODULE_DEVICE_TABLE Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 15/50] media: sti: fix obj-$(config) targets Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 16/50] media: cpia2: fix memory leak in cpia2_usb_probe Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 17/50] media: cobalt: fix race condition in setting HPD Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 18/50] media: pvrusb2: fix warning in pvr2_i2c_core_done Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 19/50] media: imx: imx7_mipi_csis: Fix logging of only error event counters Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 20/50] crypto: qat - check return code of qat_hal_rd_rel_reg() Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 21/50] crypto: qat - remove unused macro in FW loader Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 22/50] sched/fair: Fix ascii art by relpacing tabs Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 23/50] media: em28xx: Fix possible memory leak of em28xx struct Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 24/50] media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 25/50] media: bt8xx: Fix a missing check bug in bt878_probe Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 26/50] media: st-hva: Fix potential NULL pointer dereferences Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 27/50] Makefile: fix GDB warning with CONFIG_RELR Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 28/50] media: dvd_usb: memory leak in cinergyt2_fe_attach Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 29/50] memstick: rtsx_usb_ms: fix UAF Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 30/50] mmc: sdhci-sprd: use sdhci_sprd_writew Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 31/50] mmc: via-sdmmc: add a check against NULL pointer dereference Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 32/50] crypto: shash - avoid comparing pointers to exported functions under CFI Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 33/50] media: dvb_net: avoid speculation from net slot Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 34/50] media: siano: fix device register error path Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 35/50] media: imx-csi: Skip first few frames from a BT.656 source Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 36/50] hwmon: (max31790) Report correct current pwm duty cycles Sasha Levin
2021-07-04 23:09 ` Sasha Levin [this message]
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 38/50] drivers/perf: fix the missed ida_simple_remove() in ddr_perf_probe() Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 39/50] KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10 processors Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 40/50] btrfs: fix error handling in __btrfs_update_delayed_inode Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 41/50] btrfs: abort transaction if we fail to update the delayed inode Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 42/50] btrfs: make Private2 lifespan more consistent Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 43/50] btrfs: fix the filemap_range_has_page() call in btrfs_punch_hole_lock_range() Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 44/50] btrfs: disable build on platforms having page size 256K Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 45/50] locking/lockdep: Fix the dep path printing for backwards BFS Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 46/50] lockding/lockdep: Avoid to find wrong lock dep path in check_irq_usage() Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 47/50] KVM: s390: get rid of register asm usage Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 48/50] regulator: mt6358: Fix vdram2 .vsel_mask Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 49/50] regulator: da9052: Ensure enough delay time for .set_voltage_time_sel Sasha Levin
2021-07-04 23:09 ` [PATCH AUTOSEL 5.4 50/50] media: Fix Media Controller API config checks Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210704230938.1490742-37-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=jan.kundrat@cesnet.cz \
    --cc=kubernat@cesnet.cz \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).