Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51d76b72 authored by Loic Prylli's avatar Loic Prylli Committed by Greg Kroah-Hartman
Browse files

hwmon: (aspeed-pwm-tacho) mutex for tach reading



[ Upstream commit 1168491e7f53581ba7b6014a39a49cfbbb722feb ]

the ASPEED_PTCR_RESULT Register can only hold the result for a
single fan input. Adding a mutex to protect the register until the
reading is done.

Signed-off-by: default avatarLoic Prylli <lprylli@netflix.com>
Signed-off-by: default avatarAlexander Hansen <alexander.hansen@9elements.com>
Fixes: 2d7a548a ("drivers: hwmon: Support for ASPEED PWM/Fan tach")
Link: https://lore.kernel.org/r/121d888762a1232ef403cf35230ccf7b3887083a.1699007401.git.alexander.hansen@9elements.com


Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent df096593
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -194,6 +194,8 @@ struct aspeed_pwm_tacho_data {
	u8 fan_tach_ch_source[16];
	struct aspeed_cooling_device *cdev[8];
	const struct attribute_group *groups[3];
	/* protects access to shared ASPEED_PTCR_RESULT */
	struct mutex tach_lock;
};

enum type { TYPEM, TYPEN, TYPEO };
@@ -528,6 +530,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
	u8 fan_tach_ch_source, type, mode, both;
	int ret;

	mutex_lock(&priv->tach_lock);

	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0);
	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch);

@@ -545,6 +549,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
		ASPEED_RPM_STATUS_SLEEP_USEC,
		usec);

	mutex_unlock(&priv->tach_lock);

	/* return -ETIMEDOUT if we didn't get an answer. */
	if (ret)
		return ret;
@@ -909,6 +915,7 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	mutex_init(&priv->tach_lock);
	priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs,
			&aspeed_pwm_tacho_regmap_config);
	if (IS_ERR(priv->regmap))