From: Tabrez Ahmed <tabreztalks@gmail.com>
To: linux@roeck-us.net
Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org,
shuah@kernel.org, me@brighamcampbell.com,
Tabrez Ahmed <tabreztalks@gmail.com>
Subject: [PATCH v2 2/2] hwmon: (ads7871) Use DMA-safe buffer for SPI writes
Date: Sun, 29 Mar 2026 13:03:52 +0530 [thread overview]
Message-ID: <20260329073352.270451-3-tabreztalks@gmail.com> (raw)
In-Reply-To: <20260329073352.270451-1-tabreztalks@gmail.com>
The driver currently passes a stack-allocated buffer to spi_write(),
which is incompatible with DMA on systems with CONFIG_VMAP_STACK
enabled.
Move the transfer buffer into the driver's private data structure
to ensure it is DMA-safe. Since this shared buffer now requires
serialization, this change depends on the previous commit which
migrated the driver to the hwmon 'with_info' API.
While moving the logic, also:
- Corrected the sign extension for 14-bit data by casting to s16.
- Scaled the output to millivolts (2500mV full scale
) to comply with the hwmon ABI.
Signed-off-by: Tabrez Ahmed <tabreztalks@gmail.com>
---
drivers/hwmon/ads7871.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c
index 41a1e9bbd4050..cd58c960690f1 100644
--- a/drivers/hwmon/ads7871.c
+++ b/drivers/hwmon/ads7871.c
@@ -63,6 +63,7 @@
struct ads7871_data {
struct spi_device *spi;
+ u8 tx_buf[2] ____cacheline_aligned;
};
static umode_t ads7871_is_visible(const void *data,
enum hwmon_sensor_types type,
@@ -78,6 +79,7 @@ static int ads7871_read_reg8(struct spi_device *spi, int reg)
{
int ret;
+
reg = reg | INST_READ_BM;
ret = spi_w8r8(spi, reg);
return ret;
@@ -92,11 +94,12 @@ static int ads7871_read_reg16(struct spi_device *spi, int reg)
return ret;
}
-static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)
+static int ads7871_write_reg8(struct ads7871_data *pdata, int reg, u8 val)
{
- u8 tmp[2] = {reg, val};
+ pdata->tx_buf[0] = reg;
+ pdata->tx_buf[1] = val;
- return spi_write(spi, tmp, sizeof(tmp));
+ return spi_write(pdata->spi, pdata->tx_buf, 2);
}
static int ads7871_read(struct device *dev, enum hwmon_sensor_types type,
@@ -115,7 +118,7 @@ static int ads7871_read(struct device *dev, enum hwmon_sensor_types type,
*/
/*MUX_M3_BM forces single ended*/
/*This is also where the gain of the PGA would be set*/
- ret = ads7871_write_reg8(spi, REG_GAIN_MUX,
+ ret = ads7871_write_reg8(pdata, REG_GAIN_MUX,
(MUX_CNV_BM | MUX_M3_BM | channel));
if (ret < 0)
return ret;
@@ -123,6 +126,7 @@ static int ads7871_read(struct device *dev, enum hwmon_sensor_types type,
ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
if (ret < 0)
return ret;
+
mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV);
/*
* on 400MHz arm9 platform the conversion
@@ -142,8 +146,11 @@ static int ads7871_read(struct device *dev, enum hwmon_sensor_types type,
if (raw_val < 0)
return raw_val;
- /*result in volts*10000 = (val/8192)*2.5*10000*/
- *val = ((raw_val >> 2) * 25000) / 8192;
+ /*
+ * Use (s16) to ensure the sign bit is preserved during the shift.
+ * Report millivolts (2.5V = 2500mV).
+ */
+ *val = ((s16)raw_val >> 2) * 2500 / 8192;
return 0;
}
@@ -180,11 +187,17 @@ static int ads7871_probe(struct spi_device *spi)
spi->bits_per_word = 8;
spi_setup(spi);
- ads7871_write_reg8(spi, REG_SER_CONTROL, 0);
- ads7871_write_reg8(spi, REG_AD_CONTROL, 0);
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->spi = spi;
+
+ ads7871_write_reg8(pdata, REG_SER_CONTROL, 0);
+ ads7871_write_reg8(pdata, REG_AD_CONTROL, 0);
val = (OSC_OSCR_BM | OSC_OSCE_BM | OSC_REFE_BM | OSC_BUFE_BM);
- ads7871_write_reg8(spi, REG_OSC_CONTROL, val);
+ ads7871_write_reg8(pdata, REG_OSC_CONTROL, val);
ret = ads7871_read_reg8(spi, REG_OSC_CONTROL);
dev_dbg(dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret);
@@ -195,11 +208,6 @@ static int ads7871_probe(struct spi_device *spi)
if (val != ret)
return -ENODEV;
- pdata = devm_kzalloc(dev, sizeof(struct ads7871_data), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
-
- pdata->spi = spi;
hwmon_dev = devm_hwmon_device_register_with_info(dev, spi->modalias,
pdata,
&ads7871_chip_info,
--
2.43.0
next prev parent reply other threads:[~2026-03-29 7:34 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-29 7:33 [PATCH v2 0/2] hwmon: (ads7871) Modernize and fix DMA safety Tabrez Ahmed
2026-03-29 7:33 ` [PATCH v2 1/2] hwmon: (ads7871) Convert to hwmon_device_register_with_info Tabrez Ahmed
2026-03-29 15:01 ` Guenter Roeck
2026-03-29 7:33 ` Tabrez Ahmed [this message]
2026-03-29 14:52 ` [PATCH v2 2/2] hwmon: (ads7871) Use DMA-safe buffer for SPI writes Guenter Roeck
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=20260329073352.270451-3-tabreztalks@gmail.com \
--to=tabreztalks@gmail.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=me@brighamcampbell.com \
--cc=shuah@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