From: Salih Erim <salih.erim@amd.com>
To: <jic23@kernel.org>, <robh@kernel.org>, <krzk+dt@kernel.org>,
<conor+dt@kernel.org>, <git@amd.com>
Cc: <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>,
Salih Erim <salih.erim@amd.com>
Subject: [PATCH v2 2/5] iio: adc: add Versal SysMon driver
Date: Sat, 2 May 2026 12:19:48 +0100 [thread overview]
Message-ID: <20260502111951.538488-3-salih.erim@amd.com> (raw)
In-Reply-To: <20260502111951.538488-1-salih.erim@amd.com>
Add the AMD/Xilinx Versal System Monitor (SysMon) IIO driver.
The driver is split into a bus-agnostic core module
(versal-sysmon-core) and a memory-mapped I/O platform driver
(versal-sysmon). The core uses the regmap API so that different
bus implementations can share the same IIO logic.
The core provides:
- Static temperature channels (current max/min, peak max/min)
- Supply voltage channels parsed from DT container nodes
- Temperature satellite channels parsed from DT container nodes
- read_raw for IIO_CHAN_INFO_RAW and IIO_CHAN_INFO_PROCESSED
- read_label using the DT label property
The MMIO platform driver provides:
- Memory-mapped register access via custom regmap callbacks
- NPI unlock before every register write (platform management
controller may re-lock NPI unpredictably on Versal devices)
Threshold events, oversampling, and I2C bus support are added in
subsequent patches.
Co-developed-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Salih Erim <salih.erim@amd.com>
---
Changes in v2:
- Split into core (versal-sysmon-core.c) + MMIO platform driver
(versal-sysmon.c) + shared header (versal-sysmon.h)
- Uses regmap API instead of direct readl/writel
- MMIO regmap uses custom callbacks with NPI unlock in write path
- Reverse Christmas Tree variable ordering throughout
- Header include order fixed
- MAINTAINERS entry folded in with wildcard F: pattern
- Kconfig: hidden VERSAL_SYSMON_CORE + VERSAL_SYSMON selects it
- Kconfig/Makefile: alphabetical ordering (VERSAL before VF610)
- Bounds validation on DT reg values
- Named constants replace magic numbers (SYSMON_REG_STRIDE,
SYSMON_SUPPLY_MANTISSA_BITS, SYSMON_MILLI)
- kernel-doc for exported sysmon_core_probe() and sysmon_parse_fw()
- Supply voltage conversion uses proper two's complement sign
extension (s16 cast) matching the hardware specification
- Register offsets sorted by address in header
- Each patch introduces only the defines, fields, and includes
it uses (no dead code in any commit)
- Removed unused linux/limits.h and linux/units.h includes
- Renamed iio_dev_info to sysmon_iio_info
- regmap_write return values checked in probe init path
MAINTAINERS | 7 +
drivers/iio/adc/Kconfig | 20 ++
drivers/iio/adc/Makefile | 2 +
drivers/iio/adc/versal-sysmon-core.c | 320 +++++++++++++++++++++++++++
drivers/iio/adc/versal-sysmon.c | 94 ++++++++
drivers/iio/adc/versal-sysmon.h | 69 ++++++
6 files changed, 512 insertions(+)
create mode 100644 drivers/iio/adc/versal-sysmon-core.c
create mode 100644 drivers/iio/adc/versal-sysmon.c
create mode 100644 drivers/iio/adc/versal-sysmon.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd1..46762c8496d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29216,6 +29216,13 @@ F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-net-ddrmc5.y
F: drivers/edac/versalnet_edac.c
F: include/linux/cdx/edac_cdx_pcol.h
+XILINX VERSAL SYSMON DRIVER
+M: Salih Erim <salih.erim@amd.com>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml
+F: drivers/iio/adc/versal-sysmon*
+
XILINX WATCHDOG DRIVER
M: Srinivas Neeli <srinivas.neeli@amd.com>
R: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a9dedbb8eb4..c7f19057484 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1943,6 +1943,26 @@ config TWL6030_GPADC
This driver can also be built as a module. If so, the module will be
called twl6030-gpadc.
+config VERSAL_SYSMON_CORE
+ tristate
+ select REGMAP
+
+config VERSAL_SYSMON
+ tristate "AMD Versal SysMon driver"
+ depends on ARCH_ZYNQMP || COMPILE_TEST
+ depends on HAS_IOMEM
+ select VERSAL_SYSMON_CORE
+ help
+ Say yes here to have support for the AMD/Xilinx Versal System
+ Monitor (SysMon). This driver provides voltage and temperature
+ monitoring through the IIO subsystem.
+
+ The SysMon measures up to 160 supply voltages and reads up to
+ 64 temperature satellites distributed across the SoC.
+
+ To compile this driver as a module, choose M here: the module
+ will be called versal-sysmon.
+
config VF610_ADC
tristate "Freescale vf610 ADC driver"
depends on HAS_IOMEM
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 097357d146b..d7696b1b157 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -167,6 +167,8 @@ obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
obj-$(CONFIG_TI_TSC2046) += ti-tsc2046.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
+obj-$(CONFIG_VERSAL_SYSMON_CORE) += versal-sysmon-core.o
+obj-$(CONFIG_VERSAL_SYSMON) += versal-sysmon.o
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
obj-$(CONFIG_XILINX_AMS) += xilinx-ams.o
diff --git a/drivers/iio/adc/versal-sysmon-core.c b/drivers/iio/adc/versal-sysmon-core.c
new file mode 100644
index 00000000000..37736c2900b
--- /dev/null
+++ b/drivers/iio/adc/versal-sysmon-core.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Versal SysMon core driver
+ *
+ * Copyright (C) 2019 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "versal-sysmon.h"
+
+#define SYSMON_CHAN_TEMP(_chan, _address, _ext) { \
+ .type = IIO_TEMP, \
+ .indexed = 1, \
+ .address = _address, \
+ .channel = _chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_PROCESSED), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 15, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU, \
+ }, \
+ .datasheet_name = _ext, \
+}
+
+/* Static temperature channels (always present) */
+static const struct iio_chan_spec temp_channels[] = {
+ SYSMON_CHAN_TEMP(0, SYSMON_TEMP_MAX, "temp"),
+ SYSMON_CHAN_TEMP(1, SYSMON_TEMP_MIN, "min"),
+ SYSMON_CHAN_TEMP(2, SYSMON_TEMP_MAX_MAX, "max_max"),
+ SYSMON_CHAN_TEMP(3, SYSMON_TEMP_MIN_MIN, "min_min"),
+};
+
+static void sysmon_q8p7_to_millicelsius(int raw_data, int *val)
+{
+ *val = ((s16)raw_data * SYSMON_MILLI) >> SYSMON_FRACTIONAL_SHIFT;
+}
+
+static void sysmon_supply_rawtoprocessed(int raw_data, int *val)
+{
+ int mantissa, format, exponent;
+
+ mantissa = FIELD_GET(SYSMON_MANTISSA_MASK, raw_data);
+ exponent = SYSMON_SUPPLY_MANTISSA_BITS - FIELD_GET(SYSMON_MODE_MASK, raw_data);
+ format = FIELD_GET(SYSMON_FMT_MASK, raw_data);
+ /*
+ * When format bit is set the mantissa is two's complement
+ * (per hardware spec); sign-extend to int for correct arithmetic.
+ */
+ if (format)
+ mantissa = (int)(s16)mantissa;
+
+ *val = (mantissa * SYSMON_MILLI) >> exponent;
+}
+
+static int sysmon_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct sysmon *sysmon = iio_priv(indio_dev);
+ unsigned int regval;
+ int ret;
+
+ if (mask != IIO_CHAN_INFO_RAW && mask != IIO_CHAN_INFO_PROCESSED)
+ return -EINVAL;
+
+ guard(mutex)(&sysmon->lock);
+
+ switch (chan->type) {
+ case IIO_TEMP:
+ ret = regmap_read(sysmon->regmap, chan->address, ®val);
+ if (ret)
+ return ret;
+ if (mask == IIO_CHAN_INFO_PROCESSED)
+ sysmon_q8p7_to_millicelsius(regval, val);
+ else
+ *val = (int)regval;
+ return IIO_VAL_INT;
+
+ case IIO_VOLTAGE:
+ ret = regmap_read(sysmon->regmap,
+ (chan->address * SYSMON_REG_STRIDE) + SYSMON_SUPPLY_BASE,
+ ®val);
+ if (ret)
+ return ret;
+ if (mask == IIO_CHAN_INFO_PROCESSED)
+ sysmon_supply_rawtoprocessed(regval, val);
+ else
+ *val = (int)regval;
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sysmon_read_label(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ char *label)
+{
+ if (chan->datasheet_name)
+ return sysfs_emit(label, "%s\n", chan->datasheet_name);
+
+ return -EINVAL;
+}
+
+static const struct iio_info sysmon_iio_info = {
+ .read_raw = sysmon_read_raw,
+ .read_label = sysmon_read_label,
+};
+
+/**
+ * sysmon_parse_fw() - Parse firmware nodes and configure IIO channels.
+ * @indio_dev: IIO device instance
+ * @dev: Parent device
+ *
+ * Reads supply-channels and temperature-channels container nodes from
+ * firmware and builds the IIO channel array. Static temperature channels
+ * are prepended, followed by supply and satellite channels from DT.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+static int sysmon_parse_fw(struct iio_dev *indio_dev, struct device *dev)
+{
+ unsigned int idx, temp_chan_idx, volt_chan_idx;
+ struct fwnode_handle *supply_node, *temp_node;
+ unsigned int num_supply = 0, num_temp = 0;
+ struct iio_chan_spec *sysmon_channels;
+ const char *label;
+ u32 reg;
+ int ret;
+
+ supply_node = device_get_named_child_node(dev, "supply-channels");
+ if (supply_node)
+ num_supply = fwnode_get_child_node_count(supply_node);
+
+ temp_node = device_get_named_child_node(dev, "temperature-channels");
+ if (temp_node)
+ num_temp = fwnode_get_child_node_count(temp_node);
+
+ sysmon_channels = devm_kcalloc(dev,
+ ARRAY_SIZE(temp_channels) +
+ num_supply + num_temp,
+ sizeof(*sysmon_channels), GFP_KERNEL);
+ if (!sysmon_channels) {
+ ret = -ENOMEM;
+ goto err_put;
+ }
+
+ /* Static temperature channels first (fixed indices) */
+ idx = 0;
+ memcpy(sysmon_channels, temp_channels, sizeof(temp_channels));
+ idx += ARRAY_SIZE(temp_channels);
+
+ /* Supply channels from DT */
+ if (supply_node) {
+ fwnode_for_each_child_node_scoped(supply_node, child) {
+ ret = fwnode_property_read_u32(child, "reg", ®);
+ if (ret < 0)
+ goto err_put;
+
+ if (reg > SYSMON_SUPPLY_IDX_MAX) {
+ ret = -EINVAL;
+ dev_err(dev, "supply reg %u exceeds max %u\n",
+ reg, SYSMON_SUPPLY_IDX_MAX);
+ goto err_put;
+ }
+
+ ret = fwnode_property_read_string(child, "label",
+ &label);
+ if (ret < 0)
+ goto err_put;
+
+ sysmon_channels[idx++] = (struct iio_chan_spec) {
+ .type = IIO_VOLTAGE,
+ .indexed = 1,
+ .address = reg,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_PROCESSED),
+ .scan_type = {
+ .realbits = 19,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ .sign = fwnode_property_read_bool(child,
+ "bipolar") ? 's' : 'u',
+ },
+ .datasheet_name = label,
+ };
+ }
+ fwnode_handle_put(supply_node);
+ supply_node = NULL;
+ }
+
+ /* Temperature satellite channels from DT */
+ if (temp_node) {
+ fwnode_for_each_child_node_scoped(temp_node, child) {
+ ret = fwnode_property_read_u32(child, "reg", ®);
+ if (ret < 0)
+ goto err_put;
+
+ if (reg < 1 || reg > SYSMON_TEMP_SAT_MAX) {
+ ret = -EINVAL;
+ dev_err(dev, "temp reg %u out of range [1..%u]\n",
+ reg, SYSMON_TEMP_SAT_MAX);
+ goto err_put;
+ }
+
+ ret = fwnode_property_read_string(child, "label",
+ &label);
+ if (ret < 0)
+ goto err_put;
+
+ sysmon_channels[idx++] = (struct iio_chan_spec) {
+ .type = IIO_TEMP,
+ .indexed = 1,
+ .address = SYSMON_TEMP_SAT_BASE +
+ ((reg - 1) * SYSMON_REG_STRIDE),
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_PROCESSED),
+ .scan_type = {
+ .sign = 's',
+ .realbits = 15,
+ .storagebits = 16,
+ .endianness = IIO_CPU,
+ },
+ .datasheet_name = label,
+ };
+ }
+ fwnode_handle_put(temp_node);
+ temp_node = NULL;
+ }
+
+ indio_dev->num_channels = idx;
+ indio_dev->info = &sysmon_iio_info;
+
+ /*
+ * Assign per-type sequential channel numbers.
+ * IIO sysfs uses type prefix (in_tempN, in_voltageN)
+ * so numbers only need to be unique within each type.
+ */
+ temp_chan_idx = 0;
+ volt_chan_idx = 0;
+ for (idx = 0; idx < indio_dev->num_channels; idx++) {
+ if (sysmon_channels[idx].type == IIO_TEMP)
+ sysmon_channels[idx].channel = temp_chan_idx++;
+ else
+ sysmon_channels[idx].channel = volt_chan_idx++;
+ }
+
+ indio_dev->channels = sysmon_channels;
+
+ return 0;
+
+err_put:
+ fwnode_handle_put(supply_node);
+ fwnode_handle_put(temp_node);
+ return ret;
+}
+
+/**
+ * sysmon_core_probe() - Initialize Versal SysMon core
+ * @dev: Parent device
+ * @regmap: Register map for hardware access
+ * @irq: Interrupt number (negative if not available)
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int sysmon_core_probe(struct device *dev, struct regmap *regmap, int irq)
+{
+ struct iio_dev *indio_dev;
+ struct sysmon *sysmon;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*sysmon));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ sysmon = iio_priv(indio_dev);
+ sysmon->dev = dev;
+ sysmon->indio_dev = indio_dev;
+ sysmon->regmap = regmap;
+ sysmon->irq = irq;
+
+ ret = devm_mutex_init(dev, &sysmon->lock);
+ if (ret)
+ return ret;
+
+ /* Disable all interrupts and clear pending status */
+ ret = regmap_write(sysmon->regmap, SYSMON_IDR, SYSMON_INTR_ALL_MASK);
+ if (ret)
+ return ret;
+ ret = regmap_write(sysmon->regmap, SYSMON_ISR, SYSMON_INTR_ALL_MASK);
+ if (ret)
+ return ret;
+
+ indio_dev->name = "versal-sysmon";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = sysmon_parse_fw(indio_dev, dev);
+ if (ret)
+ return ret;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+EXPORT_SYMBOL_GPL(sysmon_core_probe);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AMD Versal SysMon Core Driver");
+MODULE_AUTHOR("Salih Erim <salih.erim@amd.com>");
diff --git a/drivers/iio/adc/versal-sysmon.c b/drivers/iio/adc/versal-sysmon.c
new file mode 100644
index 00000000000..c597934e869
--- /dev/null
+++ b/drivers/iio/adc/versal-sysmon.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Versal SysMon MMIO platform driver
+ *
+ * Copyright (C) 2019 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "versal-sysmon.h"
+
+struct sysmon_mmio {
+ void __iomem *base;
+};
+
+static int sysmon_mmio_reg_read(void *context, unsigned int reg,
+ unsigned int *val)
+{
+ struct sysmon_mmio *mmio = context;
+
+ *val = readl(mmio->base + reg);
+ return 0;
+}
+
+static int sysmon_mmio_reg_write(void *context, unsigned int reg,
+ unsigned int val)
+{
+ struct sysmon_mmio *mmio = context;
+
+ /* NPI must be unlocked before any register write except to NPI_LOCK */
+ if (reg != SYSMON_NPI_LOCK)
+ writel(SYSMON_NPI_UNLOCK_CODE, mmio->base + SYSMON_NPI_LOCK);
+ writel(val, mmio->base + reg);
+
+ return 0;
+}
+
+static const struct regmap_config sysmon_mmio_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = SYSMON_REG_STRIDE,
+ .max_register = SYSMON_MAX_REG,
+ .reg_read = sysmon_mmio_reg_read,
+ .reg_write = sysmon_mmio_reg_write,
+ .fast_io = true,
+};
+
+static int sysmon_platform_probe(struct platform_device *pdev)
+{
+ struct sysmon_mmio *mmio;
+ struct regmap *regmap;
+ int irq;
+
+ mmio = devm_kzalloc(&pdev->dev, sizeof(*mmio), GFP_KERNEL);
+ if (!mmio)
+ return -ENOMEM;
+
+ mmio->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mmio->base))
+ return PTR_ERR(mmio->base);
+
+ regmap = devm_regmap_init(&pdev->dev, NULL, mmio,
+ &sysmon_mmio_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ irq = platform_get_irq_optional(pdev, 0);
+
+ return sysmon_core_probe(&pdev->dev, regmap, irq);
+}
+
+static const struct of_device_id sysmon_of_match_table[] = {
+ { .compatible = "xlnx,versal-sysmon" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sysmon_of_match_table);
+
+static struct platform_driver sysmon_platform_driver = {
+ .probe = sysmon_platform_probe,
+ .driver = {
+ .name = "versal-sysmon",
+ .of_match_table = sysmon_of_match_table,
+ },
+};
+module_platform_driver(sysmon_platform_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AMD Versal SysMon Platform Driver");
+MODULE_AUTHOR("Salih Erim <salih.erim@amd.com>");
diff --git a/drivers/iio/adc/versal-sysmon.h b/drivers/iio/adc/versal-sysmon.h
new file mode 100644
index 00000000000..fc4d2338328
--- /dev/null
+++ b/drivers/iio/adc/versal-sysmon.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * AMD Versal SysMon driver
+ *
+ * Copyright (C) 2019 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
+ */
+
+#ifndef _VERSAL_SYSMON_H_
+#define _VERSAL_SYSMON_H_
+
+#include <linux/iio/iio.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+
+/* Register offsets (sorted by address) */
+#define SYSMON_NPI_LOCK 0x000C
+#define SYSMON_ISR 0x0044
+#define SYSMON_IDR 0x0050
+#define SYSMON_TEMP_MAX 0x1030
+#define SYSMON_TEMP_MIN 0x1034
+#define SYSMON_SUPPLY_BASE 0x1040
+#define SYSMON_TEMP_MIN_MIN 0x1F8C
+#define SYSMON_TEMP_MAX_MAX 0x1F90
+#define SYSMON_TEMP_SAT_BASE 0x1FAC
+#define SYSMON_MAX_REG 0x24C0
+
+/* NPI unlock value written to SYSMON_NPI_LOCK */
+#define SYSMON_NPI_UNLOCK_CODE 0xF9E8D7C6
+
+/* Register stride: 4 bytes per 32-bit register */
+#define SYSMON_REG_STRIDE 4
+
+#define SYSMON_SUPPLY_IDX_MAX 159
+#define SYSMON_TEMP_SAT_MAX 64
+#define SYSMON_INTR_ALL_MASK GENMASK(31, 0)
+
+/* Supply voltage conversion register fields */
+#define SYSMON_MANTISSA_MASK GENMASK(15, 0)
+#define SYSMON_FMT_MASK BIT(16)
+#define SYSMON_MODE_MASK GENMASK(18, 17)
+
+/* Q8.7 fractional shift */
+#define SYSMON_FRACTIONAL_SHIFT 7U
+#define SYSMON_SUPPLY_MANTISSA_BITS 16
+
+/* Signed milli scale (MILLI from linux/units.h is unsigned long) */
+#define SYSMON_MILLI 1000
+
+/**
+ * struct sysmon - Driver data for Versal SysMon
+ * @dev: pointer to device struct
+ * @indio_dev: pointer to the iio device (needed for work callbacks)
+ * @regmap: register map for hardware access
+ * @lock: mutex for serializing user-space access
+ * @irq: interrupt number
+ */
+struct sysmon {
+ struct device *dev;
+ struct iio_dev *indio_dev;
+ struct regmap *regmap;
+ /* Serializes access to device registers and state */
+ struct mutex lock;
+ int irq;
+};
+
+int sysmon_core_probe(struct device *dev, struct regmap *regmap, int irq);
+
+#endif /* _VERSAL_SYSMON_H_ */
--
2.48.1
next prev parent reply other threads:[~2026-05-02 11:20 UTC|newest]
Thread overview: 20+ 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 ` Salih Erim [this message]
2026-05-04 10:18 ` [PATCH v2 2/5] iio: adc: add Versal SysMon driver 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-12 11:35 ` Salih Erim
2026-05-16 10:20 ` Jonathan Cameron
2026-05-16 15:04 ` 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-15 15:50 ` Erim, Salih
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
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=20260502111951.538488-3-salih.erim@amd.com \
--to=salih.erim@amd.com \
--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=jic23@kernel.org \
--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 \
/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.