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: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 1:42 Ivy Lopez [this message]
2026-08-05 1:54 ` [PATCH] mfd: wm8350: propagate ADC read timeout instead of returning 0 sashiko-bot
2026-08-05 3:00 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.