Devicetree
 help / color / mirror / Atom feed
* [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support
@ 2026-07-30 21:29 Luiz Angelo Daros de Luca
  2026-07-30 21:29 ` [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 Luiz Angelo Daros de Luca
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-30 21:29 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chris Packham, Andrew Morton, Darrick J. Wong,
	Uwe Kleine-König
  Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
	linux-pwm

The ADT7470 is a temperature monitor and PWM fan controller capable of
monitoring up to ten external temperature sensors and controlling up to
four PWM outputs.

Currently, the driver exposes these sensors and PWM controls only
through the hwmon sysfs interface. This patch series integrates the
ADT7470 driver with the kernel's thermal and PWM subsystems. This allows
temperature sensors to participate in Device Tree thermal zones while
exposing the PWM outputs as generic PWM providers for consumers such as
pwm-fan.

Patch 1 adds the YAML device tree binding documentation.
Patch 2 introduces the ADT7470_PWM_MAX macro.
Patch 3 registers the four PWM channels as a generic PWM provider.
Patch 4 registers the external temperature sensors with the thermal
framework.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

---
Changes in v5:
- Hide hwmon PWM sysfs attributes if "#pwm-cells" is present in DT.
- Register PWM chip before hwmon in probe() to correctly initialize 
  sysfs visibility.
- Fix waveform rounding math to strictly satisfying CONFIG_PWM_DEBUG
  expectations.
- Return 1 in round_waveform_tohw when the requested period is too 
  short for the hardware.
- Link to v4: https://patch.msgid.link/20260729-adt7470_thermalzone-v4-0-c14039dfa0e6@gmail.com

Changes in v4:
- dt-bindings: Dropped redundant descriptions for standard properties
  (#pwm-cells and #thermal-sensor-cells).
- dt-bindings: Conditionally referenced thermal-sensor.yaml to preserve
  ABI compatibility.
- dt-bindings: Switched to unevaluatedProperties due to the imported $ref.
- Link to v3: https://patch.msgid.link/20260728-adt7470_thermalzone-v3-0-d4586478cdba@gmail.com

Changes in v3:
- Migrated from the `.apply` callback to the PWM Waveform API.
- Moved fixes to another patch series:
  20260727-adt7470_thermalzone-v3-0-21424d550c3d@gmail.com
- Use guard(mutex) for simpler locking.
- Link to v2: https://patch.msgid.link/20260717-adt7470_thermalzone-v2-0-a55147958fad@gmail.com

Changes in v2:
- Fixed 2 previous bugs uncovered by Sashiko-bot during review.
- Dropped the thermal cooling device registration for the PWM channels.
- Implemented generic PWM provider support using the PWM subsystem.
- Updated Kconfig to safely handle the PWM subsystem dependency (depends on PWM || PWM=n).
- Updated Device Tree bindings to require #pwm-cells instead of #cooling-cells.
- Link to v1: https://patch.msgid.link/20260716-adt7470_thermalzone-v1-0-cc55ef35edde@gmail.com

To: Guenter Roeck <linux@roeck-us.net>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Luiz Angelo Daros de Luca <luizluca@gmail.com>
To: Chris Packham <chris.packham@alliedtelesis.co.nz>
To: Andrew Morton <akpm@linux-foundation.org>
To: "Darrick J. Wong" <djwong@us.ibm.com>
To: Uwe Kleine-König <ukleinek@kernel.org>
Cc: linux-hwmon@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pwm@vger.kernel.org

---
Luiz Angelo Daros de Luca (4):
      dt-bindings: hwmon: add adi,adt7470
      hwmon: (adt7470) Add ADT7470_PWM_MAX macro
      hwmon: (adt7470) Expose fan control via PWM framework
      hwmon: (adt7470) Add thermal zone sensor support

 .../devicetree/bindings/hwmon/adi,adt7470.yaml     |  58 ++++++
 drivers/hwmon/Kconfig                              |   1 +
 drivers/hwmon/adt7470.c                            | 203 ++++++++++++++++++++-
 3 files changed, 258 insertions(+), 4 deletions(-)
---
base-commit: 4c2e8c377915496fbe9cc1c9d91a7297aaa01783
change-id: 20260716-adt7470_thermalzone-59a102278d72

Best regards,
--  
Luiz Angelo Daros de Luca <luizluca@gmail.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470
  2026-07-30 21:29 [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support Luiz Angelo Daros de Luca
@ 2026-07-30 21:29 ` Luiz Angelo Daros de Luca
  2026-07-30 21:34   ` sashiko-bot
  2026-07-30 21:29 ` [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro Luiz Angelo Daros de Luca
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-30 21:29 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chris Packham, Andrew Morton, Darrick J. Wong,
	Uwe Kleine-König
  Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
	linux-pwm

The Analog Devices ADT7470 is a multichannel temperature sensor and
PWM fan controller. It supports monitoring up to 10 external
temperature sensors and controlling up to 4 fans.

Add the device tree binding documentation for it. This includes
support for the thermal framework by defining the "#thermal-sensor-cells"
property, and models the fan control lines as PWM channels by
defining the "#pwm-cells" property.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 .../devicetree/bindings/hwmon/adi,adt7470.yaml     | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml b/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml
new file mode 100644
index 000000000000..f653a06f241a
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/adi,adt7470.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices ADT7470 hwmon sensor
+
+maintainers:
+  - Luiz Angelo Daros de Luca <luizluca@gmail.com>
+
+description:
+  Multi-channel temperature monitor and PWM fan controller.
+  It supports monitoring up to 10 external temperature sensors and
+  controlling up to 4 fans. The fan control lines are modeled
+  as standard PWM channels.
+
+allOf:
+  - if:
+      required:
+        - "#thermal-sensor-cells"
+    then:
+      $ref: /schemas/thermal/thermal-sensor.yaml#
+
+properties:
+  compatible:
+    const: adi,adt7470
+
+  reg:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 3
+
+  "#thermal-sensor-cells":
+    const: 1
+    description:
+      Valid index values are 0 to 9, corresponding to temp1 through temp10.
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        hwmon@2f {
+            compatible = "adi,adt7470";
+            reg = <0x2f>;
+            #pwm-cells = <3>;
+            #thermal-sensor-cells = <1>;
+        };
+    };

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro
  2026-07-30 21:29 [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support Luiz Angelo Daros de Luca
  2026-07-30 21:29 ` [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 Luiz Angelo Daros de Luca
@ 2026-07-30 21:29 ` Luiz Angelo Daros de Luca
  2026-07-30 21:35   ` sashiko-bot
  2026-07-30 21:29 ` [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework Luiz Angelo Daros de Luca
  2026-07-30 21:29 ` [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support Luiz Angelo Daros de Luca
  3 siblings, 1 reply; 9+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-30 21:29 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chris Packham, Andrew Morton, Darrick J. Wong,
	Uwe Kleine-König
  Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
	linux-pwm

Instead of a magic 255, use a macro to refer to it.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/hwmon/adt7470.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index c45b984c02e6..87ddd7b8ddae 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -100,6 +100,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
 #define ADT7470_REG_FAN_MAX(x)	(ADT7470_REG_FAN_MAX_BASE_ADDR + ((x) * 2))
 
 #define ADT7470_PWM_COUNT	4
+#define ADT7470_PWM_MAX		255
 #define ADT7470_REG_PWM(x)	(ADT7470_REG_PWM_BASE_ADDR + (x))
 #define ADT7470_REG_PWM_MAX(x)	(ADT7470_REG_PWM_MAX_BASE_ADDR + (x))
 #define ADT7470_REG_PWM_MIN(x)	(ADT7470_REG_PWM_MIN_BASE_ADDR + (x))
@@ -850,7 +851,7 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
 
 	switch (attr) {
 	case hwmon_pwm_input:
-		val = clamp_val(val, 0, 255);
+		val = clamp_val(val, 0, ADT7470_PWM_MAX);
 		mutex_lock(&data->lock);
 		err = regmap_write(data->regmap, ADT7470_REG_PWM(channel),
 				   val);
@@ -910,7 +911,7 @@ static ssize_t pwm_max_store(struct device *dev,
 	if (kstrtol(buf, 10, &temp))
 		return -EINVAL;
 
-	temp = clamp_val(temp, 0, 255);
+	temp = clamp_val(temp, 0, ADT7470_PWM_MAX);
 
 	mutex_lock(&data->lock);
 	data->pwm_max[attr->index] = temp;
@@ -945,7 +946,7 @@ static ssize_t pwm_min_store(struct device *dev,
 	if (kstrtol(buf, 10, &temp))
 		return -EINVAL;
 
-	temp = clamp_val(temp, 0, 255);
+	temp = clamp_val(temp, 0, ADT7470_PWM_MAX);
 
 	mutex_lock(&data->lock);
 	data->pwm_min[attr->index] = temp;

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework
  2026-07-30 21:29 [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support Luiz Angelo Daros de Luca
  2026-07-30 21:29 ` [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 Luiz Angelo Daros de Luca
  2026-07-30 21:29 ` [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro Luiz Angelo Daros de Luca
@ 2026-07-30 21:29 ` Luiz Angelo Daros de Luca
  2026-07-30 21:39   ` sashiko-bot
  2026-07-30 21:29 ` [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support Luiz Angelo Daros de Luca
  3 siblings, 1 reply; 9+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-30 21:29 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chris Packham, Andrew Morton, Darrick J. Wong,
	Uwe Kleine-König
  Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
	linux-pwm

The ADT7470 features four PWM outputs designed to control fans.
Previously, these were only accessible through the legacy hwmon
sysfs interface.

Expose the ADT7470 fan control lines through the generic PWM framework.
This allows generic PWM consumers described in Device Tree, such as
"pwm-fan", to use the device through the "#pwm-cells" property.  This is
particularly necessary for boards where the ADT7470 external temperature
sensors are not populated and the chip is used strictly as a fan
controller (e.g., Edgecore ECS-2100-52T switches). In such setups,
delegating control to the generic PWM subsystem allows the kernel's
thermal framework to manage the fans based on unrelated temperature
zones, such as internal SoC sensors.

When a PWM consumer applies a new PWM state, the driver automatically
switches the corresponding PWM channel to manual mode so that the
requested duty cycle takes effect. The duty cycle specified by the PWM
framework is internally converted to the 0-255 scale expected by the
hardware registers.

To prevent conflicting access, the hwmon PWM sysfs attributes are hidden
when the device is registered with PWM framework support (i.e. when
"#pwm-cells" is present in DT and CONFIG_PWM is reachable).

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/hwmon/Kconfig   |   1 +
 drivers/hwmon/adt7470.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6b71e3304b4f..0d6bd117d14d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -224,6 +224,7 @@ config SENSORS_ADT7462
 config SENSORS_ADT7470
 	tristate "Analog Devices ADT7470"
 	depends on I2C
+	depends on PWM || PWM=n
 	select REGMAP_I2C
 	help
 	  If you say yes here you get support for the Analog Devices
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 87ddd7b8ddae..eeec3db0da88 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -22,6 +22,9 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/util_macros.h>
+#include <linux/pwm.h>
+#include <linux/cleanup.h>
+#include <linux/math64.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
@@ -164,6 +167,7 @@ struct adt7470_data {
 	char			limits_valid;
 	unsigned long		sensors_last_updated;	/* In jiffies */
 	unsigned long		limits_last_updated;	/* In jiffies */
+	bool			use_pwm_framework;
 
 	int			num_temp_sensors;	/* -1 = probe */
 	int			temperatures_probed;
@@ -887,6 +891,133 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
 	return err;
 }
 
+struct adt7470_pwm_wfhw {
+	u8 val;
+};
+
+static int adt7470_pwm_round_waveform_tohw(struct pwm_chip *chip,
+					   struct pwm_device *pwm,
+					   const struct pwm_waveform *wf,
+					   void *_wfhw)
+{
+	struct adt7470_data *data = pwmchip_get_drvdata(chip);
+	struct adt7470_pwm_wfhw *wfhw = _wfhw;
+	u64 actual_period;
+
+	if (wf->duty_length_ns == 0) {
+		wfhw->val = 0;
+		return 0;
+	}
+
+	/*
+	 * The PWM frequency (period) is a single chip-wide setting shared by
+	 * all 4 channels, so it cannot be changed on a per-pwm_device basis
+	 * through this API. The duty cycle is rounded against the currently
+	 * configured hardware period rather than the period requested in
+	 * @wf; round_waveform_fromhw() reports the actual resulting
+	 * waveform back so the core/consumer can detect a mismatch.
+	 */
+	actual_period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, data->pwm_freq);
+
+	if (actual_period > wf->period_length_ns)
+		/* period too short */
+		return 1;
+
+	if (wf->duty_length_ns >= actual_period) {
+		wfhw->val = ADT7470_PWM_MAX;
+	} else {
+		wfhw->val = mul_u64_u64_div_u64(wf->duty_length_ns,
+						ADT7470_PWM_MAX,
+						actual_period);
+	}
+
+	return 0;
+}
+
+static int adt7470_pwm_round_waveform_fromhw(struct pwm_chip *chip,
+					     struct pwm_device *pwm,
+					     const void *_wfhw,
+					     struct pwm_waveform *wf)
+{
+	struct adt7470_data *data = pwmchip_get_drvdata(chip);
+	const struct adt7470_pwm_wfhw *wfhw = _wfhw;
+
+	wf->period_length_ns = DIV_ROUND_UP_ULL(NSEC_PER_SEC, data->pwm_freq);
+	wf->duty_offset_ns = 0;
+	wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->val * wf->period_length_ns,
+					      ADT7470_PWM_MAX);
+	return 0;
+}
+
+static int adt7470_pwm_read_waveform(struct pwm_chip *chip,
+				     struct pwm_device *pwm,
+				     void *_wfhw)
+{
+	struct adt7470_data *data = pwmchip_get_drvdata(chip);
+	struct device *dev = regmap_get_device(data->regmap);
+	struct adt7470_pwm_wfhw *wfhw = _wfhw;
+
+	data = adt7470_update_device(dev);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	/*
+	 * No lock needed: like the other hwmon_ops read callbacks in this
+	 * driver (e.g. adt7470_pwm_read()), this only does a single byte
+	 * read from the cache populated by adt7470_update_device().
+	 */
+	wfhw->val = data->pwm[pwm->hwpwm];
+
+	return 0;
+}
+
+static int adt7470_pwm_write_waveform(struct pwm_chip *chip,
+				      struct pwm_device *pwm,
+				      const void *_wfhw)
+{
+	struct adt7470_data *data = pwmchip_get_drvdata(chip);
+	const struct adt7470_pwm_wfhw *wfhw = _wfhw;
+	unsigned int pwm_auto_reg_mask;
+	int err;
+
+	if (pwm->hwpwm % 2)
+		pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK;
+	else
+		pwm_auto_reg_mask = ADT7470_PWM1_AUTO_MASK;
+
+	guard(mutex)(&data->lock);
+
+	if (data->pwm[pwm->hwpwm] == wfhw->val &&
+	    data->pwm_automatic[pwm->hwpwm] == 0)
+		return 0;
+
+	/* Put the PWM channel in manual mode before updating it. */
+	err = regmap_update_bits(data->regmap,
+				 ADT7470_REG_PWM_CFG(pwm->hwpwm),
+				 pwm_auto_reg_mask, 0);
+	if (err < 0)
+		return err;
+
+	data->pwm_automatic[pwm->hwpwm] = 0;
+
+	err = regmap_write(data->regmap,
+			   ADT7470_REG_PWM(pwm->hwpwm), wfhw->val);
+	if (err < 0)
+		return err;
+
+	data->pwm[pwm->hwpwm] = wfhw->val;
+
+	return 0;
+}
+
+static const struct pwm_ops adt7470_pwm_ops = {
+	.sizeof_wfhw = sizeof(struct adt7470_pwm_wfhw),
+	.round_waveform_tohw = adt7470_pwm_round_waveform_tohw,
+	.round_waveform_fromhw = adt7470_pwm_round_waveform_fromhw,
+	.read_waveform = adt7470_pwm_read_waveform,
+	.write_waveform = adt7470_pwm_write_waveform,
+};
+
 static ssize_t pwm_max_show(struct device *dev,
 			    struct device_attribute *devattr, char *buf)
 {
@@ -1107,6 +1238,10 @@ static struct attribute *adt7470_attrs[] = {
 	&dev_attr_alarm_mask.attr,
 	&dev_attr_num_temp_sensors.attr,
 	&dev_attr_auto_update_interval.attr,
+	NULL
+};
+
+static struct attribute *adt7470_pwm_attrs[] = {
 	&sensor_dev_attr_force_pwm_max.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
@@ -1131,7 +1266,32 @@ static struct attribute *adt7470_attrs[] = {
 	NULL
 };
 
-ATTRIBUTE_GROUPS(adt7470);
+static const struct attribute_group adt7470_group = {
+	.attrs = adt7470_attrs,
+};
+
+static umode_t adt7470_pwm_is_visible(struct kobject *kobj,
+				      struct attribute *attr, int index)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+
+	if (data->use_pwm_framework)
+		return 0;
+
+	return attr->mode;
+}
+
+static const struct attribute_group adt7470_pwm_group = {
+		.attrs = adt7470_pwm_attrs,
+		.is_visible = adt7470_pwm_is_visible,
+};
+
+static const struct attribute_group *adt7470_groups[] = {
+		&adt7470_group,
+		&adt7470_pwm_group,
+		NULL,
+};
 
 static int adt7470_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 			int channel, long *val)
@@ -1166,6 +1326,7 @@ static int adt7470_write(struct device *dev, enum hwmon_sensor_types type, u32 a
 static umode_t adt7470_is_visible(const void *_data, enum hwmon_sensor_types type,
 				  u32 attr, int channel)
 {
+	const struct adt7470_data *data = _data;
 	umode_t mode = 0;
 
 	switch (type) {
@@ -1198,6 +1359,14 @@ static umode_t adt7470_is_visible(const void *_data, enum hwmon_sensor_types typ
 		}
 		break;
 	case hwmon_pwm:
+		/* Hide all pwm attributes if this device is exposed to the PWM
+		 * framework
+		 */
+		if (data->use_pwm_framework) {
+			mode = 0;
+			break;
+		}
+
 		switch (attr) {
 		case hwmon_pwm_input:
 		case hwmon_pwm_enable:
@@ -1328,6 +1497,29 @@ static int adt7470_probe(struct i2c_client *client)
 
 	data->pwm_freq = (u32)freq_val;
 
+	data->use_pwm_framework = false;
+
+	if (device_property_present(dev, "#pwm-cells")) {
+		if (IS_REACHABLE(CONFIG_PWM)) {
+			struct pwm_chip *chip;
+
+			chip = devm_pwmchip_alloc(dev, ADT7470_PWM_COUNT, 0);
+			if (IS_ERR(chip))
+				return PTR_ERR(chip);
+
+			chip->ops = &adt7470_pwm_ops;
+			pwmchip_set_drvdata(chip, data);
+
+			err = devm_pwmchip_add(dev, chip);
+			if (err)
+				return dev_err_probe(dev, err, "failed to register PWM chip\n");
+
+			data->use_pwm_framework = true;
+		} else {
+			dev_warn(dev, "#pwm-cells present but CONFIG_PWM disabled. HWMON PWM attributes not hidden.\n");
+		}
+	}
+
 	/* Register sysfs hooks */
 	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
 							 &adt7470_chip_info,

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support
  2026-07-30 21:29 [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support Luiz Angelo Daros de Luca
                   ` (2 preceding siblings ...)
  2026-07-30 21:29 ` [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework Luiz Angelo Daros de Luca
@ 2026-07-30 21:29 ` Luiz Angelo Daros de Luca
  2026-07-30 21:43   ` sashiko-bot
  3 siblings, 1 reply; 9+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-30 21:29 UTC (permalink / raw)
  To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chris Packham, Andrew Morton, Darrick J. Wong,
	Uwe Kleine-König
  Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
	linux-pwm

Register the ADT7470 temperature channels as thermal zone sensors.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/hwmon/adt7470.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index eeec3db0da88..f652532f2f32 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -1396,6 +1396,8 @@ static const struct hwmon_ops adt7470_hwmon_ops = {
 };
 
 static const struct hwmon_channel_info * const adt7470_info[] = {
+	HWMON_CHANNEL_INFO(chip,
+			   HWMON_C_REGISTER_TZ),
 	HWMON_CHANNEL_INFO(temp,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_ALARM,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_ALARM,

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470
  2026-07-30 21:29 ` [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 Luiz Angelo Daros de Luca
@ 2026-07-30 21:34   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-30 21:34 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca; +Cc: linux-hwmon, robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The provider capability property `#pwm-cells` is omitted from the `required` list despite the hardware functioning as a PWM provider.
--

--- Patch [1]: [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 ---
commit 5105b0d67f8fd87224b8f539a86af2d5d3710517
Author: Luiz Angelo Daros de Luca <luizluca@gmail.com>

dt-bindings: hwmon: add adi,adt7470

This commit adds device tree binding documentation for the Analog Devices
ADT7470 multichannel temperature sensor and PWM fan controller. It defines
properties for thermal sensors and models the fan control lines as PWM
channels.

> diff --git a/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml b/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml
> new file mode 100644
> index 0000000000000..f653a06f241aa
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/adi,adt7470.yaml
> @@ -0,0 +1,58 @@

[ ... ]

> +properties:
> +  compatible:
> +    const: adi,adt7470
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#pwm-cells":
> +    const: 3
> +
> +  "#thermal-sensor-cells":
> +    const: 1
> +    description:
> +      Valid index values are 0 to 9, corresponding to temp1 through temp10.
> +
> +required:
> +  - compatible
> +  - reg

[Severity: Medium]
Since the device acts as a PWM provider and defines #pwm-cells, should
#pwm-cells be added to this required list? 

The device tree bindings subsystem guidelines state that when a device adds
provider capabilities like PWM output, the corresponding standard properties
must appear in the required list. Without it, incomplete device tree nodes
that are missing #pwm-cells will pass schema validation, which could mask
configurations that will fail at runtime when dependent consumers attempt to
use the PWM capability.

> +
> +unevaluatedProperties: false

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-adt7470_thermalzone-v5-0-42995a6bb8c5@gmail.com?part=1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro
  2026-07-30 21:29 ` [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro Luiz Angelo Daros de Luca
@ 2026-07-30 21:35   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-30 21:35 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca; +Cc: robh, conor+dt, devicetree, linux-hwmon

> Instead of a magic 255, use a macro to refer to it.
> 
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

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

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-adt7470_thermalzone-v5-0-42995a6bb8c5@gmail.com?part=2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework
  2026-07-30 21:29 ` [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework Luiz Angelo Daros de Luca
@ 2026-07-30 21:39   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-30 21:39 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca; +Cc: linux-hwmon, robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The ADT7470 driver implements and registers secondary functionality (PWM) directly in the hwmon driver, violating subsystem layering guidelines.
--

--- Patch [3]: [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework ---
commit 8476b17bbf277543f8b1034721091c420371204b
Author: Luiz Angelo Daros de Luca <luizluca@gmail.com>

hwmon: (adt7470) Expose fan control via PWM framework

The ADT7470 features four PWM outputs designed to control fans. This commit
exposes the ADT7470 fan control lines through the generic PWM framework,
allowing generic PWM consumers described in Device Tree to manage the fans.

> diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
> index 87ddd7b8ddaea..eeec3db0da88d 100644
> --- a/drivers/hwmon/adt7470.c
> +++ b/drivers/hwmon/adt7470.c
[ ... ]
> @@ -1328,6 +1497,29 @@ static int adt7470_probe(struct i2c_client *client)
>  
>  	data->pwm_freq = (u32)freq_val;
>  
> +	data->use_pwm_framework = false;
> +
> +	if (device_property_present(dev, "#pwm-cells")) {
> +		if (IS_REACHABLE(CONFIG_PWM)) {
> +			struct pwm_chip *chip;
> +
> +			chip = devm_pwmchip_alloc(dev, ADT7470_PWM_COUNT, 0);
> +			if (IS_ERR(chip))
> +				return PTR_ERR(chip);
> +
> +			chip->ops = &adt7470_pwm_ops;
> +			pwmchip_set_drvdata(chip, data);
> +
> +			err = devm_pwmchip_add(dev, chip);

[Severity: Medium]
Does this violate the hardware monitoring subsystem guidelines?

The guidelines state that if a hardware monitoring device supports secondary
functionality (such as PWM in this case), the secondary functionality should
be implemented as an auxiliary device, with the driver residing in the
appropriate subsystem directory. 

Could this PWM functionality be split out into a separate driver under
drivers/pwm/ using the auxiliary bus, rather than implementing the PWM
operations and registration directly in the hwmon driver?

> +			if (err)
> +				return dev_err_probe(dev, err, "failed to register PWM chip\n");
> +
> +			data->use_pwm_framework = true;
> +		} else {
> +			dev_warn(dev, "#pwm-cells present but CONFIG_PWM disabled. HWMON PWM attributes not hidden.\n");
> +		}
> +	}
> +

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-adt7470_thermalzone-v5-0-42995a6bb8c5@gmail.com?part=3

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support
  2026-07-30 21:29 ` [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support Luiz Angelo Daros de Luca
@ 2026-07-30 21:43   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-30 21:43 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca; +Cc: robh, linux-hwmon, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Registering the device as a thermal zone exposes the thermal subsystem to severe latency stalls.
--

--- Patch [4]: [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support ---
commit ee08dfc4b8ac9e072681b3ebf92b63eb473bf1a7
Author: Luiz Angelo Daros de Luca <luizluca@gmail.com>

hwmon: (adt7470) Add thermal zone sensor support

This commit registers the ADT7470 temperature channels as thermal zone
sensors.

> diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
> index eeec3db0da88d..f652532f2f32e 100644
> --- a/drivers/hwmon/adt7470.c
> +++ b/drivers/hwmon/adt7470.c
> @@ -1396,6 +1396,8 @@ static const struct hwmon_ops adt7470_hwmon_ops = {
>  };
>  
>  static const struct hwmon_channel_info * const adt7470_info[] = {
> +	HWMON_CHANNEL_INFO(chip,
> +			   HWMON_C_REGISTER_TZ),

[Severity: High]
Will registering this device as a thermal zone cause severe latency stalls
for the thermal subsystem?

Looking at the background thread in the driver, it acquires the internal lock
before initiating a slow temperature read:

adt7470_update_thread() {
    ...
    mutex_lock(&data->lock);
    adt7470_read_temperatures(data);
    mutex_unlock(&data->lock);
    ...
}

Inside adt7470_read_temperatures(), the thread can sleep for up to 2 seconds
while still holding this lock:

adt7470_read_temperatures() {
    ...
    res = msleep_interruptible((data->num_temp_sensors >= 0 ?
                                data->num_temp_sensors * 200 :
                                TEMP_COLLECTION_TIME));
    ...
}

Since thermal zone registration causes the thermal core to automatically
and periodically poll the device, the thermal worker thread will attempt to
acquire data->lock. Because the lock is held for up to 2 seconds by the
background kthread, the thermal polling thread will be frequently delayed.

Additionally, while the thermal thread waits for data->lock, it also holds
the core hwdev->lock, which means any other userspace sysfs reads or writes
to this hwmon device will also stall.

Could this delay thermal mitigations for other devices on the system?

>  	HWMON_CHANNEL_INFO(temp,
>  			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_ALARM,
>  			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_ALARM,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-adt7470_thermalzone-v5-0-42995a6bb8c5@gmail.com?part=4

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-30 21:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 21:29 [hwmon-next PATCH v5 0/4] hwmon: (adt7470) Add PWM provider and thermal sensor support Luiz Angelo Daros de Luca
2026-07-30 21:29 ` [hwmon-next PATCH v5 1/4] dt-bindings: hwmon: add adi,adt7470 Luiz Angelo Daros de Luca
2026-07-30 21:34   ` sashiko-bot
2026-07-30 21:29 ` [hwmon-next PATCH v5 2/4] hwmon: (adt7470) Add ADT7470_PWM_MAX macro Luiz Angelo Daros de Luca
2026-07-30 21:35   ` sashiko-bot
2026-07-30 21:29 ` [hwmon-next PATCH v5 3/4] hwmon: (adt7470) Expose fan control via PWM framework Luiz Angelo Daros de Luca
2026-07-30 21:39   ` sashiko-bot
2026-07-30 21:29 ` [hwmon-next PATCH v5 4/4] hwmon: (adt7470) Add thermal zone sensor support Luiz Angelo Daros de Luca
2026-07-30 21:43   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox