From: Jonathan Cameron <jic23@kernel.org>
To: Salih Erim <salih.erim@amd.com>
Cc: <robh@kernel.org>, <krzk+dt@kernel.org>, <conor+dt@kernel.org>,
<git@amd.com>, <nuno.sa@analog.com>, <andy@kernel.org>,
<dlechner@baylibre.com>, <michal.simek@amd.com>,
<conall.ogriofa@amd.com>, <erimsalih@gmail.com>,
<linux-iio@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 4/5] iio: adc: versal-sysmon: add threshold event support
Date: Mon, 4 May 2026 18:44:15 +0100 [thread overview]
Message-ID: <20260504184415.7b6688f5@jic23-huawei> (raw)
In-Reply-To: <20260502111951.538488-5-salih.erim@amd.com>
On Sat, 2 May 2026 12:19:50 +0100
Salih Erim <salih.erim@amd.com> wrote:
> Add threshold event support for temperature and supply voltage
> channels.
>
> Temperature events:
> - Rising/falling threshold with configurable values
> - Over-temperature (OT) alarm with separate thresholds
> - Per-channel hysteresis configuration
>
> Supply voltage events:
> - Rising/falling threshold per supply channel
> - Per-channel alarm enable via alarm configuration registers
>
> The interrupt handler masks active threshold interrupts (which are
> level-sensitive) and schedules a delayed worker to poll for condition
> clear before unmasking. When no hardware IRQ is available (irq <= 0),
> event channels are not created and interrupt init is skipped, since
> the I2C regmap backend cannot be called from atomic context.
>
> When disabling a supply channel alarm, the group interrupt remains
> active if any other channel in the same alarm group still has an
> alarm enabled.
>
> Named constants replace magic numbers for hysteresis bit positions
> (SYSMON_OT_HYST_BIT, SYSMON_TEMP_HYST_BIT) and alarm register width
> (SYSMON_ALARM_BITS_PER_REG).
>
> Hysteresis values are validated to single-bit range (0 or 1) before
> writing to the hardware register.
>
> Signed-off-by: Salih Erim <salih.erim@amd.com>
A few minor comments inline to add to what Andy found.
> drivers/iio/adc/versal-sysmon-core.c | 539 ++++++++++++++++++++++++++-
> drivers/iio/adc/versal-sysmon.h | 36 ++
> 2 files changed, 574 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iio/adc/versal-sysmon-core.c b/drivers/iio/adc/versal-sysmon-core.c
> index 37736c2900b..857fe21db7a 100644
> --- a/drivers/iio/adc/versal-sysmon-core.c
> +++ b/drivers/iio/adc/versal-sysmon-core.c
>
> +/* OT and TEMP hysteresis bit positions in SYSMON_TEMP_EV_CFG */
> +#define SYSMON_OT_HYST_BIT BIT(0)
> +#define SYSMON_TEMP_HYST_BIT BIT(1)
You use a mix of these defines and manual shift. Use FIELD_GET()
/FIELD_PREP() to avoid that.
>
> +#define SYSMON_CHAN_TEMP_EVENT(_chan, _address, _ext, _events) { \
> + .type = IIO_TEMP, \
> + .indexed = 1, \
> + .address = _address, \
> + .channel = _chan, \
> + .event_spec = _events, \
> + .num_event_specs = ARRAY_SIZE(_events), \
> + .scan_type = { \
> + .sign = 's', \
> + .realbits = 15, \
> + .storagebits = 16, \
> + .endianness = IIO_CPU, \
> + }, \
> + .datasheet_name = _ext, \
As before - consider renaming this.
> +}
> +
> +static int sysmon_read_event_value(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan,
> + enum iio_event_type type,
> + enum iio_event_direction dir,
> + enum iio_event_info info, int *val,
> + int *val2)
> +{
> + struct sysmon *sysmon = iio_priv(indio_dev);
> + unsigned int reg_val;
> + u32 mask, shift;
> + int offset;
> + int ret;
> +
> + guard(mutex)(&sysmon->lock);
> +
> + if (chan->type == IIO_TEMP) {
> + if (info == IIO_EV_INFO_VALUE) {
> + offset = sysmon_temp_thresh_offset(chan->address, dir);
> + if (offset < 0)
> + return offset;
> + ret = regmap_read(sysmon->regmap, offset, ®_val);
> + if (ret)
> + return ret;
> + sysmon_q8p7_to_millicelsius(reg_val, val);
> + return IIO_VAL_INT;
> + }
> + if (info == IIO_EV_INFO_HYSTERESIS) {
> + mask = (chan->address == SYSMON_ADDR_OT_EVENT) ?
> + SYSMON_OT_HYST_BIT : SYSMON_TEMP_HYST_BIT;
Not a massive amount of sharing for OT_EVENT vs others. Maybe just split it
and then you can use FIELD_GET() and get shift handling included via the mask.
ret = regmap_read(sysmon->regmap, SYSMON_TEMP_EV_CFG,
®_val);
if (ret)
return ret;
if (chan->addres == SYSMBO_ADDR_OT_EVENT) {
*val = FIELD_GET(SYSMON_OT_HYST_BIT, reg_val);
else
*val = FIELD_GET(YSMON_TEMP_HYST_BIT, reg_val);
> + *val = (reg_val & mask) >> shift;
}
> + shift = (chan->address == SYSMON_ADDR_OT_EVENT) ? 0 : 1;
> + ret = regmap_read(sysmon->regmap, SYSMON_TEMP_EV_CFG,
> + ®_val);
> + if (ret)
> + return ret;
> + *val = (reg_val & mask) >> shift;
> + return IIO_VAL_INT;
> + }
> +
> +static int sysmon_write_event_value(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan,
> + enum iio_event_type type,
> + enum iio_event_direction dir,
> + enum iio_event_info info, int val, int val2)
> +{
> + struct sysmon *sysmon = iio_priv(indio_dev);
> + unsigned int reg_val;
> + u32 mask, shift;
> + u32 raw_val;
> + int offset;
> + int ret;
> +
> + guard(mutex)(&sysmon->lock);
> +
> + if (chan->type == IIO_TEMP) {
> + if (info == IIO_EV_INFO_VALUE) {
> + offset = sysmon_temp_thresh_offset(chan->address, dir);
> + if (offset < 0)
> + return offset;
> + sysmon_millicelsius_to_q8p7(&raw_val, val);
> + return regmap_write(sysmon->regmap, offset, raw_val);
> + }
> + if (info == IIO_EV_INFO_HYSTERESIS) {
> + mask = (chan->address == SYSMON_ADDR_OT_EVENT) ?
> + SYSMON_OT_HYST_BIT : SYSMON_TEMP_HYST_BIT;
> + shift = (chan->address == SYSMON_ADDR_OT_EVENT) ? 0 : 1;
> + if (val & ~1)
Just to confirm - this only has hysteresis values of 0 or 1? That's unusually
small given hysteresis should be in same units as _raw.
Also similar to above, I'd split the two cases and use FIELD_PREP()
> + return -EINVAL;
> + return regmap_update_bits(sysmon->regmap,
> + SYSMON_TEMP_EV_CFG,
> + mask, val << shift);
> + }
> + } else if (chan->type == IIO_VOLTAGE) {
> + offset = sysmon_supply_thresh_offset(chan->address, dir);
> + if (offset < 0)
> + return offset;
> + ret = regmap_read(sysmon->regmap, offset, ®_val);
> + if (ret)
> + return ret;
> + sysmon_supply_processedtoraw(val, reg_val, &raw_val);
> + return regmap_write(sysmon->regmap, offset, raw_val);
> + }
> +
> + return -EINVAL;
> +}
next prev parent reply other threads:[~2026-05-04 17:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-02 11:19 [PATCH v2 0/5] iio: adc: add AMD/Xilinx Versal SysMon driver Salih Erim
2026-05-02 11:19 ` [PATCH v2 1/5] dt-bindings: iio: adc: add xlnx,versal-sysmon binding Salih Erim
2026-05-03 14:20 ` Krzysztof Kozlowski
2026-05-03 22:52 ` Salih Erim
2026-05-02 11:19 ` [PATCH v2 2/5] iio: adc: add Versal SysMon driver Salih Erim
2026-05-04 10:18 ` Andy Shevchenko
2026-05-04 15:50 ` Salih Erim
2026-05-05 7:12 ` Andy Shevchenko
2026-05-04 17:32 ` Jonathan Cameron
2026-05-04 19:26 ` Guenter Roeck
2026-05-02 11:19 ` [PATCH v2 3/5] iio: adc: versal-sysmon: add I2C driver Salih Erim
2026-05-04 10:25 ` Andy Shevchenko
2026-05-02 11:19 ` [PATCH v2 4/5] iio: adc: versal-sysmon: add threshold event support Salih Erim
2026-05-04 10:52 ` Andy Shevchenko
2026-05-04 17:44 ` Jonathan Cameron [this message]
2026-05-02 11:19 ` [PATCH v2 5/5] iio: adc: versal-sysmon: add oversampling support Salih Erim
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=20260504184415.7b6688f5@jic23-huawei \
--to=jic23@kernel.org \
--cc=andy@kernel.org \
--cc=conall.ogriofa@amd.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=erimsalih@gmail.com \
--cc=git@amd.com \
--cc=krzk+dt@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.simek@amd.com \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
--cc=salih.erim@amd.com \
/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