From: Ivy Lopez <skunkolee@gmail.com>
To: lee@kernel.org, sre@kernel.org, linux@roeck-us.net
Cc: patches@opensource.cirrus.com, mfd@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
linux-hwmon@vger.kernel.org, Ivy Lopez <skunkolee@gmail.com>
Subject: [PATCH] mfd: wm8350: propagate ADC read timeout instead of returning 0
Date: Tue, 4 Aug 2026 19:42:21 -0600 [thread overview]
Message-ID: <20260805014221.16412-1-skunkolee@gmail.com> (raw)
wm8350_read_auxadc() logs an error via dev_err() when the AUX ADC
read times out, but then falls through to return the masked value
of `result`, which was left at its initial value of 0. Callers have
no way to distinguish a genuine 0V reading from a failed read.
Return -ETIMEDOUT on timeout instead, and update the wm8350 hwmon
and power_supply drivers, which call this function directly, to
check for a negative return and propagate the error rather than
using it as a voltage value.
Signed-off-by: Ivy Lopez <skunkolee@gmail.com>
---
drivers/hwmon/wm8350-hwmon.c | 9 ++++--
drivers/mfd/wm8350-core.c | 14 ++++++---
drivers/power/supply/wm8350_power.c | 45 ++++++++++++++++++++++-------
3 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
index 10e17bb79895..a455e1c5476c 100644
--- a/drivers/hwmon/wm8350-hwmon.c
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -23,14 +23,17 @@ static const char * const input_names[] = {
};
static ssize_t show_voltage(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
int channel = to_sensor_dev_attr(attr)->index;
int val;
- val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF;
- val = DIV_ROUND_CLOSEST(val, 1000);
+ val = wm8350_read_auxadc(wm8350, channel, 0, 0);
+ if (val < 0)
+ return val;
+
+ val = DIV_ROUND_CLOSEST(val * WM8350_AUX_COEFF, 1000);
return sprintf(buf, "%d\n", val);
}
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index fbc77b218215..3120c6b8fa3f 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -188,6 +188,7 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
{
u16 reg, result = 0;
+ int ret = 0;
if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
return -EINVAL;
@@ -221,19 +222,24 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- if (reg & WM8350_AUXADC_POLL)
+ if (reg & WM8350_AUXADC_POLL) {
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
- else
+ ret = -ETIMEDOUT;
+ } else {
result = wm8350_reg_read(wm8350,
- WM8350_AUX1_READBACK + channel);
+ WM8350_AUX1_READBACK + channel);
+ }
/* Turn off the ADC */
reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5,
- reg & ~WM8350_AUXADC_ENA);
+ reg & ~WM8350_AUXADC_ENA);
mutex_unlock(&wm8350->auxadc_mutex);
+ if (ret)
+ return ret;
+
return result & WM8350_AUXADC_DATA1_MASK;
}
EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
diff --git a/drivers/power/supply/wm8350_power.c b/drivers/power/supply/wm8350_power.c
index b0eb6e0ce8bc..111373027905 100644
--- a/drivers/power/supply/wm8350_power.c
+++ b/drivers/power/supply/wm8350_power.c
@@ -19,20 +19,32 @@
static int wm8350_read_battery_uvolts(struct wm8350 *wm8350)
{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_BATT, 0, 0)
- * WM8350_AUX_COEFF;
+ int val = wm8350_read_auxadc(wm8350, WM8350_AUXADC_BATT, 0, 0);
+
+ if (val < 0)
+ return val;
+
+ return val * WM8350_AUX_COEFF;
}
static int wm8350_read_line_uvolts(struct wm8350 *wm8350)
{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_LINE, 0, 0)
- * WM8350_AUX_COEFF;
+ int val = wm8350_read_auxadc(wm8350, WM8350_AUXADC_LINE, 0, 0);
+
+ if (val < 0)
+ return val;
+
+ return val * WM8350_AUX_COEFF;
}
static int wm8350_read_usb_uvolts(struct wm8350 *wm8350)
{
- return wm8350_read_auxadc(wm8350, WM8350_AUXADC_USB, 0, 0)
- * WM8350_AUX_COEFF;
+ int val = wm8350_read_auxadc(wm8350, WM8350_AUXADC_USB, 0, 0);
+
+ if (val < 0)
+ return val;
+
+ return val * WM8350_AUX_COEFF;
}
#define WM8350_BATT_SUPPLY 1
@@ -257,7 +269,10 @@ static int wm8350_ac_get_prop(struct power_supply *psy,
WM8350_LINE_SUPPLY);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_line_uvolts(wm8350);
+ ret = wm8350_read_line_uvolts(wm8350);
+ if (ret < 0)
+ return ret;
+ val->intval = ret;
break;
default:
ret = -EINVAL;
@@ -287,7 +302,10 @@ static int wm8350_usb_get_prop(struct power_supply *psy,
WM8350_USB_SUPPLY);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_usb_uvolts(wm8350);
+ ret = wm8350_read_usb_uvolts(wm8350);
+ if (ret < 0)
+ return ret;
+ val->intval = ret;
break;
default:
ret = -EINVAL;
@@ -308,8 +326,12 @@ static enum power_supply_property wm8350_usb_props[] = {
static int wm8350_bat_check_health(struct wm8350 *wm8350)
{
u16 reg;
+ int uvolts = wm8350_read_battery_uvolts(wm8350);
+
+ if (uvolts < 0)
+ return POWER_SUPPLY_HEALTH_UNKNOWN;
- if (wm8350_read_battery_uvolts(wm8350) < 2850000)
+ if (uvolts < 2850000)
return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
reg = wm8350_reg_read(wm8350, WM8350_CHARGER_OVERRIDES);
@@ -356,7 +378,10 @@ static int wm8350_bat_get_property(struct power_supply *psy,
WM8350_BATT_SUPPLY);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = wm8350_read_battery_uvolts(wm8350);
+ ret = wm8350_read_battery_uvolts(wm8350);
+ if (ret < 0)
+ return ret;
+ val->intval = ret;
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = wm8350_bat_check_health(wm8350);
--
2.55.0
next reply other threads:[~2026-08-05 1:42 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 1:42 Ivy Lopez [this message]
2026-08-05 3:00 ` [PATCH] mfd: wm8350: propagate ADC read timeout instead of returning 0 Guenter Roeck
2026-08-06 1:19 ` Ivy Lopez
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=20260805014221.16412-1-skunkolee@gmail.com \
--to=skunkolee@gmail.com \
--cc=lee@kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mfd@lists.linux.dev \
--cc=patches@opensource.cirrus.com \
--cc=sre@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