Skip to contentSkip to conversation

Add driver support for ESWIN EIC7700 PVT controller

PATCH Superseded [email protected] 3 participants 7 messages Jun 11 – Jun 23

Subsystems (2)

v7 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v7 cover Add driver support for ESWIN EIC7700 PVT controller

From: Huan He <[email protected]>

Add support for the ESWIN EIC7700 PVT (Voltage, Temperature) sensor

Features:
The driver supports monitoring of voltage and temperature parameters through the hardware monitoring subsystem. It provides an access to the sampled Temperature and Voltage.

Test:
Tested this patch on the SiFive HiFive Premier P550 (which uses the ESWIN EIC7700 SoC).

Updates:

Changes in v7:
- Remove the unused reset control pointer from struct pvt_hwmon and keep the reset control handle local to eic7700_pvt_probe()
- Update eic7700_pvt_init_iface() to disable PVT_ENA_EN before clearing the interrupt status, preventing a possible level-triggered interrupt storm if the bootloader leaves the conversion engine running
- Update eic7700_pvt_disable_pm_runtime() to explicitly disable runtime PM and avoid an unbalanced disable_depth

Changes in v6:
- Fix the !CONFIG_PM probe error path by disabling the clock if IRQ request fails before the PM cleanup action is registered
- Replace pm_runtime_put_noidle() with pm_runtime_put() in the IRQ handler to avoid a runtime PM reference-count race with the read path
- Remove the unused pvt_clear_data() devres action and its associated devm_add_action() registration

Changes in v5:
- Update eswin,eic7700-pvt.yaml
- Drop the label enum constraint and remove label from the required list
- Add '#thermal-sensor-cells' to the required list
- Rename the example node to the generic sensor@... form
- Update the binding description to describe one temperature sensor and one voltage sensor
- Update eic7700-pvt.c
- Register the hwmon device with the fixed name "pvt"
- Remove label-based instance identification from the driver
- Fix CONFIG_PM=n support by keeping the clock enabled when runtime PM is unavailable
- Add pm_runtime_force_suspend() in the cleanup path to avoid leaving the device active during unbind
- Switch system sleep callbacks to pm_runtime_force_suspend() and pm_runtime_force_resume()
- Guard ISR register accesses with pm_runtime_get_if_active()
- Add synchronize_irq() on the timeout path to avoid stale completion races
- Remove temp_offset support because the raw trim register does not match the hwmon ABI
- Align the commit message with the implementation (one temperature sensor, one voltage sensor)

Changes in v4:
- Update eswin,eic7700-pvt.yaml
- Delete reviewed-by tag of Conor Dooley, because the label enum constraint is introduced
- Update eic7700-pvt.c and eic7700-pvt.h
- Remove the unused LVT/ULVT/SVT process-monitoring channels
- Remove the probe-time power check since the PVT block is always powered on EIC7700 and the extra verification is unnecessary
- Stop requesting the interrupt as shared and use the dedicated PVT IRQ only
- Reorder probe initialization so the interface is initialized before the clock is disabled, avoiding register accesses with the clock gated
- Fix runtime PM reference handling on error paths by balancing pm_runtime_get_noresume() with pm_runtime_put_noidle()
- Add pm_runtime_put_noidle() handling for failed pm_runtime_get_sync() calls in hwmon read/write paths
- Switch the PM callback registration from pm_sleep_ptr() to pm_ptr()

Changes in v3:
- Update eswin,eic7700-pvt.yaml
- Remove redundant label property description and use 'label: true' to reference the definition in hwmon-common.yaml
- Replace 'additionalProperties: false' with 'unevaluatedProperties: false'
- Remove the description for '#thermal-sensor-cells'
- Update eic7700-pvt.c and eic7700-pvt.h
- Fix clock reference count imbalance with Runtime PM:
Replace devm_clk_get_enabled() with devm_clk_get() and manually manage clock enable/disable to avoid double-disable in remove() when Runtime PM is active. Clock is now enabled only during probe for eic7700_pvt_check_pwr(), then disabled before enabling Runtime PM, which takes full control of the clock thereafter
- Add detailed comment explaining the spurious interrupt risk in eic7700_pvt_check_pwr()
- Replace wait_for_completion_interruptible() with wait_for_completion_timeout() to prevent infinite wait

Changes in v2:
- Update eswin,eic7700-pvt.yaml
- Reference the hwmon-common.yaml file
- Remove the clock-names and reset-names properties
- Move additionalProperties: false after the required block
- Remove one example node to avoid redundancy
- Update eic7700-pvt.c and eic7700-pvt.h
- Remove unused sensor macros (PVT_SENSOR_FIRST, PVT_SENSOR_LAST, PVT_SENSORS_NUM)
- Drop the unnecessary hwmon-sysfs.h header
- Replace dynamic sensor info allocation with a static array and unify sensor labels
- Remove unused hwmon_temp_type attribute
- Eliminate redundant validation checks
- Remove mutex and related locking, relying on hwmon core serialization
- Replace per-sensor caches and completions with a single data cache and completion object
- Remove pvt->sensor tracking. ISR no longer depends on the currently selected sensor
- Move devm_add_action() registration after init_completion() for safer cleanup, and update cleanup function (pvt_clear_data)
- Replace devm_reset_control_get_optional_exclusive() with devm_reset_control_get_exclusive_deasserted()
- Replace eic7700_pvt_remove() with eic7700_pvt_disable_pm_runtime() and move it after PM runtime enable to avoid resource leaks on probe failure and remove clock disable and reset assert from eic7700_pvt_disable_pm_runtime() as it is already handled by devm_* framework
- Remove redundant clock presence check in runtime_resume

- Link to v1: https://lore.kernel.org/all/[email protected]/

Huan He (2):
dt-bindings: hwmon: Add Eswin EIC7700 PVT sensor
hwmon: Add Eswin EIC7700 PVT sensor driver

 .../bindings/hwmon/eswin,eic7700-pvt.yaml     |  63 +++
 drivers/hwmon/Kconfig                         |  12 +
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/eic7700-pvt.c                   | 497 ++++++++++++++++++
 drivers/hwmon/eic7700-pvt.h                   |  98 ++++
 5 files changed, 671 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/eswin,eic7700-pvt.yaml
 create mode 100644 drivers/hwmon/eic7700-pvt.c
 create mode 100644 drivers/hwmon/eic7700-pvt.h
Signature · 1 line
2.25.1
#1 lore raw

PATCH v7 1/2 dt-bindings: hwmon: Add Eswin EIC7700 PVT sensor

From: Huan He <[email protected]>

Add device tree binding documentation for ESWIN EIC7700 Voltage and Temperature sensor.

The EIC7700 SoC integrates two PVT instances for monitoring SoC and DDR power domains respectively.

---
 .../bindings/hwmon/eswin,eic7700-pvt.yaml     | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/eswin,eic7700-pvt.yaml
Documentation/devicetree/bindings/hwmon/eswin,eic7700-pvt.yaml new file +63 -0
new file mode 100644
index 000000000000..27cc90e52d4b
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/eswin,eic7700-pvt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ESWIN EIC7700 PVT Sensor
+
+maintainers:
+  - Yulin Lu <[email protected]>
+  - Huan He <[email protected]>
+
+description:
+  ESWIN EIC7700 SoC integrates embedded voltage and temperature sensors to
+  monitor the internal SoC environment. The system includes two PVT sensor
+  instances. The PVT0 monitors the main SoC power domain. The PVT1 sensor
+  monitors the DDR core power domain.
+
+allOf:
+  - $ref: /schemas/hwmon/hwmon-common.yaml#
+
+properties:
+  compatible:
+    const: eswin,eic7700-pvt
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  '#thermal-sensor-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - resets
+  - '#thermal-sensor-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    sensor@50b00000 {
+      compatible = "eswin,eic7700-pvt";
+      reg = <0x50b00000 0x10000>;
+      clocks = <&clocks 244>;
+      interrupts = <349>;
+      interrupt-parent = <&plic>;
+      label = "pvt0";
+      resets = <&reset 111>;
+      #thermal-sensor-cells = <0>;
+    };
+...
Signature · 1 line
2.25.1
#2 lore raw

Re: [PATCH v7 1/2] dt-bindings: hwmon: Add Eswin EIC7700 PVT sensor

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 10 lines

From: Huan He <[email protected]>

Add device tree binding documentation for ESWIN EIC7700 Voltage and Temperature sensor.

The EIC7700 SoC integrates two PVT instances for monitoring SoC and DDR power domains respectively.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#3 lore raw

PATCH v7 2/2 hwmon: Add Eswin EIC7700 PVT sensor driver

In reply to [email protected]

From: Huan He <[email protected]>

Add support for ESWIN EIC7700 Voltage and Temperature sensor. The driver supports temperature and voltage monitoring with polynomial conversion, and provides sysfs interface for sensor data access.

The PVT IP contains one temperature sensor and one voltage sensor.

---
 drivers/hwmon/Kconfig       |  12 +
 drivers/hwmon/Makefile      |   1 +
 drivers/hwmon/eic7700-pvt.c | 497 ++++++++++++++++++++++++++++++++++++
 drivers/hwmon/eic7700-pvt.h |  98 +++++++
 4 files changed, 608 insertions(+)
 create mode 100644 drivers/hwmon/eic7700-pvt.c
 create mode 100644 drivers/hwmon/eic7700-pvt.h
drivers/hwmon/Kconfig +12 -0
index 14e4cea48acc..6cb60355aa0c 100644
@@ -2033,6 +2033,18 @@ config SENSORS_DME1737
 	  This driver can also be built as a module. If so, the module
 	  will be called dme1737.
 
+config SENSORS_EIC7700_PVT
+	tristate "Eswin EIC7700 Voltage, Temperature sensor driver"
+	depends on ARCH_ESWIN || COMPILE_TEST
+	depends on HWMON
+	select POLYNOMIAL
+	help
+	  If you say yes here you get support for Eswin EIC7700 PVT sensor
+	  embedded into the SoC.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called eic7700-pvt.
+
 config SENSORS_EMC1403
 	tristate "SMSC EMC1403/23 thermal sensor"
 	depends on I2C
drivers/hwmon/Makefile +1 -0
index 982ee2c6f9de..d647669074e1 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
 obj-$(CONFIG_SENSORS_DRIVETEMP)	+= drivetemp.o
 obj-$(CONFIG_SENSORS_DS620)	+= ds620.o
 obj-$(CONFIG_SENSORS_DS1621)	+= ds1621.o
+obj-$(CONFIG_SENSORS_EIC7700_PVT) += eic7700-pvt.o
 obj-$(CONFIG_SENSORS_EMC1403)	+= emc1403.o
 obj-$(CONFIG_SENSORS_EMC2103)	+= emc2103.o
 obj-$(CONFIG_SENSORS_EMC2305)	+= emc2305.o
drivers/hwmon/eic7700-pvt.c new file +497 -0

497 lines not on this page · raw message

drivers/hwmon/eic7700-pvt.h new file +98 -0

98 lines not on this page · raw message

Signature · 1 line
2.25.1
#4 lore raw

Re: [PATCH v7 2/2] hwmon: Add Eswin EIC7700 PVT sensor driver

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] The IRQ is requested before the PM runtime cleanup action is registered, leading to a possible…

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The IRQ is requested before the PM runtime cleanup action is registered, leading to a possible use-after-disable of the hardware clock in the ISR on driver removal.
- [Medium] The interrupt handler eic7700_pvt_hard_isr does not check the hardware interrupt status bit to verify if the device actually generated the interrupt. --

commit 0f4c8aefb83780ee09652639eb2843f01c2baf38
Author: Huan He <[email protected]>

hwmon: Add Eswin EIC7700 PVT sensor driver

Add support for ESWIN EIC7700 Voltage and Temperature sensor. The driver supports temperature and voltage monitoring with polynomial conversion, and provides sysfs interface for sensor data access.

Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +0 -0
new file mode 100644
index 0000000000000..3b3aed74c3941

[ ... ]

Quoted 9 lines
drivers/hwmon/eic7700-pvt.c new file +9 -0
+static irqreturn_t eic7700_pvt_hard_isr(int irq, void *data)
+{
+	struct pvt_hwmon *pvt = data;
+	int active;
+	u32 val;
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		active = pm_runtime_get_if_active(pvt->dev);
+		if (active <= 0)

drivers/hwmon/eic7700-pvt.c line 129

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+			return IRQ_NONE;
+	}
+
+	eic7700_pvt_update(pvt->regs + PVT_INT, PVT_INT_CLR, PVT_INT_CLR);
+	/*
+	 * Read the data, update the cache and notify a waiter of this event.
+	 */
+	val = readl(pvt->regs + PVT_DATA);
+	WRITE_ONCE(pvt->data_cache, FIELD_GET(PVT_DATA_OUT, val));
+	complete(&pvt->conversion);

[Severity: Medium]
Does this unconditionally process the interrupt without checking if the device actually generated it?

If a spurious interrupt occurs, the ISR will prematurely clear the interrupt, read whatever stale value is in PVT_DATA, and call complete(&pvt->conversion). This will cause the waiting thread in eic7700_pvt_read_data() to wake up early and return stale or garbage data to userspace.

Should the ISR read the status register and return IRQ_NONE if its device did not assert the interrupt?

[ ... ]

Quoted 4 lines
drivers/hwmon/eic7700-pvt.c new file +4 -0
+	ret = eic7700_pvt_request_irq(pvt);
+	if (ret) {
+		if (!IS_ENABLED(CONFIG_PM))
+			clk_disable_unprepare(pvt->clk);

drivers/hwmon/eic7700-pvt.c line 429

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 3000);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
+
+	ret = devm_add_action_or_reset(pvt->dev, eic7700_pvt_disable_pm_runtime,
+				       pvt);

[Severity: High]
Can this devres setup lead to accessing unclocked registers during device removal?

Because devres executes teardown callbacks in reverse order of their registration, eic7700_pvt_disable_pm_runtime() will run before the IRQ is freed by devm_request_threaded_irq()'s teardown.

During removal, eic7700_pvt_disable_pm_runtime() disables the clock:

eic7700_pvt_disable_pm_runtime() {
    ...
    if (!pm_runtime_status_suspended(pvt->dev)) {
        clk_disable_unprepare(pvt->clk);
        pm_runtime_set_suspended(pvt->dev);
    }
}

If an interrupt fires concurrently and the ISR executes past the pm_runtime_get_if_active() check before the clock is disabled, the ISR will attempt to access hardware registers while unclocked, which can lead to an external abort or kernel panic:

eic7700_pvt_hard_isr() {
    ...
    eic7700_pvt_update(pvt->regs + PVT_INT, ...);
}

Should the PM runtime cleanup action be registered before the IRQ is requested?

Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +5 -0
+	if (ret) {
+		pm_runtime_put_noidle(&pdev->dev);
+		return dev_err_probe(&pdev->dev, ret,
+				     "Can't register PM cleanup\n");
+	}
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
maintainer
#5 lore raw

Re: [PATCH v7 2/2] hwmon: Add Eswin EIC7700 PVT sensor driver

Quoted 94 lines · On 6/11/26 02:17, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The IRQ is requested before the PM runtime cleanup action is registered, leading to a possible use-after-disable of the hardware clock in the ISR on driver removal.
- [Medium] The interrupt handler eic7700_pvt_hard_isr does not check the hardware interrupt status bit to verify if the device actually generated the interrupt. --

commit 0f4c8aefb83780ee09652639eb2843f01c2baf38
Author: Huan He <[email protected]>

hwmon: Add Eswin EIC7700 PVT sensor driver

Add support for ESWIN EIC7700 Voltage and Temperature sensor. The driver supports temperature and voltage monitoring with polynomial conversion, and provides sysfs interface for sensor data access.

Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +0 -0
new file mode 100644
index 0000000000000..3b3aed74c3941

[ ... ]

Quoted 9 lines
drivers/hwmon/eic7700-pvt.c new file +9 -0
+static irqreturn_t eic7700_pvt_hard_isr(int irq, void *data)
+{
+	struct pvt_hwmon *pvt = data;
+	int active;
+	u32 val;
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		active = pm_runtime_get_if_active(pvt->dev);
+		if (active <= 0)

drivers/hwmon/eic7700-pvt.c line 129

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+			return IRQ_NONE;
+	}
+
+	eic7700_pvt_update(pvt->regs + PVT_INT, PVT_INT_CLR, PVT_INT_CLR);
+	/*
+	 * Read the data, update the cache and notify a waiter of this event.
+	 */
+	val = readl(pvt->regs + PVT_DATA);
+	WRITE_ONCE(pvt->data_cache, FIELD_GET(PVT_DATA_OUT, val));
+	complete(&pvt->conversion);

[Severity: Medium]
Does this unconditionally process the interrupt without checking if the device actually generated it?

If a spurious interrupt occurs, the ISR will prematurely clear the interrupt, read whatever stale value is in PVT_DATA, and call complete(&pvt->conversion). This will cause the waiting thread in eic7700_pvt_read_data() to wake up early and return stale or garbage data to userspace.

Should the ISR read the status register and return IRQ_NONE if its device did not assert the interrupt?

[ ... ]

Quoted 4 lines
drivers/hwmon/eic7700-pvt.c new file +4 -0
+	ret = eic7700_pvt_request_irq(pvt);
+	if (ret) {
+		if (!IS_ENABLED(CONFIG_PM))
+			clk_disable_unprepare(pvt->clk);

drivers/hwmon/eic7700-pvt.c line 429

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 3000);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
+
+	ret = devm_add_action_or_reset(pvt->dev, eic7700_pvt_disable_pm_runtime,
+				       pvt);

[Severity: High]
Can this devres setup lead to accessing unclocked registers during device removal?

Because devres executes teardown callbacks in reverse order of their registration, eic7700_pvt_disable_pm_runtime() will run before the IRQ is freed by devm_request_threaded_irq()'s teardown.

During removal, eic7700_pvt_disable_pm_runtime() disables the clock:

eic7700_pvt_disable_pm_runtime() {
     ...
     if (!pm_runtime_status_suspended(pvt->dev)) {
         clk_disable_unprepare(pvt->clk);
         pm_runtime_set_suspended(pvt->dev);
     }
}

If an interrupt fires concurrently and the ISR executes past the pm_runtime_get_if_active() check before the clock is disabled, the ISR will attempt to access hardware registers while unclocked, which can lead to an external abort or kernel panic:

Quoted 7 lines
eic7700_pvt_hard_isr() {
     ...
     eic7700_pvt_update(pvt->regs + PVT_INT, ...);
}

Should the PM runtime cleanup action be registered before the IRQ is requested?

If not solved, these questions will at least have to be answered.

Thanks,
Guenter

Quoted 6 lines
Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +5 -0
+	if (ret) {
+		pm_runtime_put_noidle(&pdev->dev);
+		return dev_err_probe(&pdev->dev, ret,
+				     "Can't register PM cleanup\n");
+	}
author
#6 lore raw

Re: Re: [PATCH v7 2/2] hwmon: Add Eswin EIC7700 PVT sensor driver

Hi Sashiko, Guenter,

Thank you very much for your detailed review. We appreciate the feedback.

Quoted 48 lines · On 6/11/26 02:17, [email protected] wrote:
Quoted 46 lines

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The IRQ is requested before the PM runtime cleanup action is registered, leading to a possible use-after-disable of the hardware clock in the ISR on driver removal.
- [Medium] The interrupt handler eic7700_pvt_hard_isr does not check the hardware interrupt status bit to verify if the device actually generated the interrupt. --

commit 0f4c8aefb83780ee09652639eb2843f01c2baf38
Author: Huan He <[email protected]>

hwmon: Add Eswin EIC7700 PVT sensor driver

Add support for ESWIN EIC7700 Voltage and Temperature sensor. The driver supports temperature and voltage monitoring with polynomial conversion, and provides sysfs interface for sensor data access.

Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +0 -0
new file mode 100644
index 0000000000000..3b3aed74c3941

[ ... ]

Quoted 9 lines
drivers/hwmon/eic7700-pvt.c new file +9 -0
+static irqreturn_t eic7700_pvt_hard_isr(int irq, void *data)
+{
+	struct pvt_hwmon *pvt = data;
+	int active;
+	u32 val;
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		active = pm_runtime_get_if_active(pvt->dev);
+		if (active <= 0)

drivers/hwmon/eic7700-pvt.c line 129

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+			return IRQ_NONE;
+	}
+
+	eic7700_pvt_update(pvt->regs + PVT_INT, PVT_INT_CLR, PVT_INT_CLR);
+	/*
+	 * Read the data, update the cache and notify a waiter of this event.
+	 */
+	val = readl(pvt->regs + PVT_DATA);
+	WRITE_ONCE(pvt->data_cache, FIELD_GET(PVT_DATA_OUT, val));
+	complete(&pvt->conversion);

[Severity: Medium]
Does this unconditionally process the interrupt without checking if the device actually generated it?

Quoted 7 lines
Quoted 7 lines

If a spurious interrupt occurs, the ISR will prematurely clear the interrupt, read whatever stale value is in PVT_DATA, and call complete(&pvt->conversion). This will cause the waiting thread in eic7700_pvt_read_data() to wake up early and return stale or garbage data to userspace.

Should the ISR read the status register and return IRQ_NONE if its device did not assert the interrupt?

I will modify the ISR to read PVT_INT first and return IRQ_NONE when PVT_INT_STAT is not set.

Quoted 41 lines
Quoted 41 lines

[ ... ]

Quoted 4 lines
drivers/hwmon/eic7700-pvt.c new file +4 -0
+	ret = eic7700_pvt_request_irq(pvt);
+	if (ret) {
+		if (!IS_ENABLED(CONFIG_PM))
+			clk_disable_unprepare(pvt->clk);

drivers/hwmon/eic7700-pvt.c line 429

Quoted 10 lines
drivers/hwmon/eic7700-pvt.c new file +10 -0
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 3000);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
+
+	ret = devm_add_action_or_reset(pvt->dev, eic7700_pvt_disable_pm_runtime,
+				       pvt);

[Severity: High]
Can this devres setup lead to accessing unclocked registers during device removal?

Because devres executes teardown callbacks in reverse order of their registration, eic7700_pvt_disable_pm_runtime() will run before the IRQ is freed by devm_request_threaded_irq()'s teardown.

During removal, eic7700_pvt_disable_pm_runtime() disables the clock:

eic7700_pvt_disable_pm_runtime() {
     ...
     if (!pm_runtime_status_suspended(pvt->dev)) {
         clk_disable_unprepare(pvt->clk);
         pm_runtime_set_suspended(pvt->dev);
     }
}

If an interrupt fires concurrently and the ISR executes past the pm_runtime_get_if_active() check before the clock is disabled, the ISR will attempt to access hardware registers while unclocked, which can lead to an external abort or kernel panic:

Quoted 7 lines
Quoted 7 lines
eic7700_pvt_hard_isr() {
     ...
     eic7700_pvt_update(pvt->regs + PVT_INT, ...);
}

Should the PM runtime cleanup action be registered before the IRQ is requested?

I will modify the probe sequence to register the PM runtime cleanup action before requesting the IRQ.

Best regards,
Huan He

Quoted 12 lines

If not solved, these questions will at least have to be answered.

Thanks,
Guenter

Quoted 6 lines
Quoted 5 lines
drivers/hwmon/eic7700-pvt.c new file +5 -0
+	if (ret) {
+		pm_runtime_put_noidle(&pdev->dev);
+		return dev_err_probe(&pdev->dev, ret,
+				     "Can't register PM cleanup\n");
+	}