From nobody Sat Apr 4 07:47:57 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4E5335DA6C for ; Fri, 20 Mar 2026 10:59:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004375; cv=none; b=TG5wLZjjEk5zfXbkEcYnMrbLQWXAn5pwAmiRAZCuUZPN60mLqeXMmFHVDxKcEW+N3FUgZl9iMemBsfdqBbvfxl5L4sic5wuWjVOVI8riH/eMVWuq5vgbuy3z3zHaErkIcCtP5De7U5Eyj1JDCSt+iPt8qBlHK2vqdlkLDTVSMpM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004375; c=relaxed/simple; bh=8XoXEOFnRFU+xTDSeilbgf+OIdxrhZOSKc9IPoSqbQc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tUijqOad9Ww/UmbVKvjnz1tv9uNXZES1jGOpirWjY7mIVoFmIsbbwlQYtNdU35j2Z1x7mP8iw4IMDlksZCt/yRgyWsnANnaPGlaQ7f6ykm40vB0gZiCLzRr5btJvxDqV989Z2MjMypmuReYeVoc3tD35YVo/q5ruK+QscLAxZGM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=KVR7K5OO; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="KVR7K5OO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774004370; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=liQz5OshvtXJy/w8Kf9VDPryfJ9WB7whqRNmekeRQHM=; b=KVR7K5OOC572YHKLCrA4EJ6CiiwanvvF3goC8s2Y4YLzJLc9ukiyBo0LpqeAGbuRQw0DhI IIx4qotRjoj6Z6JmeMwJjs//gr1BiURAz0CK3rmMDrQaDgKAJ6bIb22yLIIHH+G2dGkOAU 5D6j/72ieX4vp6AZurF8ikk/kMjduUs= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-53-i_bvTNvvM0y70qsV4neiFw-1; Fri, 20 Mar 2026 06:59:26 -0400 X-MC-Unique: i_bvTNvvM0y70qsV4neiFw-1 X-Mimecast-MFC-AGG-ID: i_bvTNvvM0y70qsV4neiFw_1774004365 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1ACDE1955EAC; Fri, 20 Mar 2026 10:59:25 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.20]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7A8C61955F21; Fri, 20 Mar 2026 10:59:21 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Arkadiusz Kubalewski , Guenter Roeck , Jiri Pirko , Prathosh Satish , Vadim Fedorenko , linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Michal Schmidt , Petr Oros , Simon Horman Subject: [PATCH net-next 1/3] dpll: zl3073x: add hwmon support for die temperature Date: Fri, 20 Mar 2026 11:59:13 +0100 Message-ID: <20260320105915.149068-2-ivecera@redhat.com> In-Reply-To: <20260320105915.149068-1-ivecera@redhat.com> References: <20260320105915.149068-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Register an hwmon device to expose the chip die temperature via the standard hwmon temperature interface. The temperature sensor is only available on chip variants that have the ZL3073X_FLAG_DIE_TEMP flag set and its visibility is controlled via the is_visible callback. The die temperature register provides a value in 0.1=C2=B0C units that is converted to millidegrees Celsius for the hwmon subsystem. Signed-off-by: Ivan Vecera --- drivers/dpll/zl3073x/Makefile | 1 + drivers/dpll/zl3073x/core.c | 7 ++++ drivers/dpll/zl3073x/hwmon.c | 67 +++++++++++++++++++++++++++++++++++ drivers/dpll/zl3073x/hwmon.h | 16 +++++++++ 4 files changed, 91 insertions(+) create mode 100644 drivers/dpll/zl3073x/hwmon.c create mode 100644 drivers/dpll/zl3073x/hwmon.h diff --git a/drivers/dpll/zl3073x/Makefile b/drivers/dpll/zl3073x/Makefile index 906ec3fbcc202..6930bf7867151 100644 --- a/drivers/dpll/zl3073x/Makefile +++ b/drivers/dpll/zl3073x/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ZL3073X) +=3D zl3073x.o zl3073x-objs :=3D chan.o core.o devlink.o dpll.o \ flash.o fw.o out.o prop.o ref.o synth.o +zl3073x-$(CONFIG_HWMON) +=3D hwmon.o =20 obj-$(CONFIG_ZL3073X_I2C) +=3D zl3073x_i2c.o zl3073x_i2c-objs :=3D i2c.o diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 7eebfc1ad1019..dcea98c31d694 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -18,6 +18,7 @@ #include "core.h" #include "devlink.h" #include "dpll.h" +#include "hwmon.h" #include "regs.h" =20 #define ZL_CHIP_INFO(_id, _nchannels, _flags) \ @@ -1038,6 +1039,12 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev) if (rc) return rc; =20 + /* Register hwmon interface */ + rc =3D zl3073x_hwmon_init(zldev); + if (rc) + return dev_err_probe(zldev->dev, rc, + "Failed to register hwmon device\n"); + /* Register the devlink instance and parameters */ rc =3D zl3073x_devlink_register(zldev); if (rc) diff --git a/drivers/dpll/zl3073x/hwmon.c b/drivers/dpll/zl3073x/hwmon.c new file mode 100644 index 0000000000000..4b44df4def820 --- /dev/null +++ b/drivers/dpll/zl3073x/hwmon.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +#include "core.h" +#include "hwmon.h" +#include "regs.h" + +static int zl3073x_hwmon_read(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct zl3073x_dev *zldev =3D dev_get_drvdata(dev); + u16 raw; + int rc; + + if (type !=3D hwmon_temp || attr !=3D hwmon_temp_input) + return -EOPNOTSUPP; + + rc =3D zl3073x_read_u16(zldev, ZL_REG_DIE_TEMP_STATUS, &raw); + if (rc) + return rc; + + /* Convert from 0.1=C2=B0C units to millidegrees Celsius */ + *val =3D (s16)raw * 100; + + return 0; +} + +static umode_t zl3073x_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct zl3073x_dev *zldev =3D data; + + if (type =3D=3D hwmon_temp && (zldev->info->flags & ZL3073X_FLAG_DIE_TEMP= )) + return 0444; + + return 0; +} + +static const struct hwmon_channel_info * const zl3073x_hwmon_info[] =3D { + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), + NULL, +}; + +static const struct hwmon_ops zl3073x_hwmon_ops =3D { + .is_visible =3D zl3073x_hwmon_is_visible, + .read =3D zl3073x_hwmon_read, +}; + +static const struct hwmon_chip_info zl3073x_hwmon_chip_info =3D { + .ops =3D &zl3073x_hwmon_ops, + .info =3D zl3073x_hwmon_info, +}; + +int zl3073x_hwmon_init(struct zl3073x_dev *zldev) +{ + struct device *hwmon; + + hwmon =3D devm_hwmon_device_register_with_info(zldev->dev, "zl3073x", + zldev, + &zl3073x_hwmon_chip_info, + NULL); + return PTR_ERR_OR_ZERO(hwmon); +} diff --git a/drivers/dpll/zl3073x/hwmon.h b/drivers/dpll/zl3073x/hwmon.h new file mode 100644 index 0000000000000..6048d596985ad --- /dev/null +++ b/drivers/dpll/zl3073x/hwmon.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ZL3073X_HWMON_H +#define _ZL3073X_HWMON_H + +#include + +struct zl3073x_dev; + +#if IS_REACHABLE(CONFIG_HWMON) +int zl3073x_hwmon_init(struct zl3073x_dev *zldev); +#else +static inline int zl3073x_hwmon_init(struct zl3073x_dev *zldev) { return 0= ; } +#endif + +#endif /* _ZL3073X_HWMON_H */ --=20 2.52.0 From nobody Sat Apr 4 07:47:57 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D20B39891B for ; Fri, 20 Mar 2026 10:59:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004380; cv=none; b=c2Ow963kdYwsAM+4f9IOGamiWlumxlVIhhtHk7GB7HTEks3DbsUgJmX6yZyGjSxKxNMhe/l33M2IBIVrQYOscRi+ABITgpHPTF2y/1NNWYWkLjzFo+r997xKBNX3+MlB1q2SRKuyI8rM3sQJ7eUhhtD+0Zfrsp/1MOWcS9/Dhng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004380; c=relaxed/simple; bh=pNNd3yDLO8AaMISPXCG2rf2X2lK823quU5OuYZsLynw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TOyw7LyJMnYolNvBUgBxSzCYZruUpQqVe5O8W1f2UnUt9337Iga3CVRyrnvll4jyTMuepoiTuqDRGptWEcZlpQCnBZkI+exJcCQNHt9xrIg1guq4nCVEN2GSvlXutlcK+bOwJdD1XXg3mTEfyc1Q3WEYUKnGXXsC9y86SJRug58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=i5p0lzwM; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="i5p0lzwM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774004376; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/9pGQPTg7QlYXRfZtWboLf1fefc5y2P3cHKkI2n6Tmw=; b=i5p0lzwMhuhfaWBQmg02UFPgk7NcxoBs4Nv8zkniSgycfeIX0KO17Tu3CSqu4RuFp+qHa7 QW6DG1w7IIFVOTUy5IGpG9RGvCtzeooof/Q6+aIh4eokEGLj+EwWQ4Q6C/sN0C3TClabq6 6SLCvkj6+u/ByrpONKvwPGX6KWP6LLg= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-561-5geZmHNxMgOGLW27tXzMHw-1; Fri, 20 Mar 2026 06:59:31 -0400 X-MC-Unique: 5geZmHNxMgOGLW27tXzMHw-1 X-Mimecast-MFC-AGG-ID: 5geZmHNxMgOGLW27tXzMHw_1774004369 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 70B43195608B; Fri, 20 Mar 2026 10:59:29 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.20]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DC7261955F21; Fri, 20 Mar 2026 10:59:25 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Arkadiusz Kubalewski , Guenter Roeck , Jiri Pirko , Prathosh Satish , Vadim Fedorenko , linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Michal Schmidt , Petr Oros , Simon Horman Subject: [PATCH net-next 2/3] dpll: zl3073x: add input reference frequency measurement Date: Fri, 20 Mar 2026 11:59:14 +0100 Message-ID: <20260320105915.149068-3-ivecera@redhat.com> In-Reply-To: <20260320105915.149068-1-ivecera@redhat.com> References: <20260320105915.149068-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Extract common measurement latch logic from zl3073x_ref_ffo_update() into a new zl3073x_ref_freq_meas_latch() helper and add zl3073x_ref_freq_meas_update() that uses it to latch and read absolute input reference frequencies in Hz. Add meas_freq field to struct zl3073x_ref and the corresponding zl3073x_ref_meas_freq_get() accessor. The measured frequencies are updated periodically alongside the existing FFO measurements. Signed-off-by: Ivan Vecera --- drivers/dpll/zl3073x/core.c | 80 +++++++++++++++++++++++++++++++------ drivers/dpll/zl3073x/ref.h | 14 +++++++ 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index dcea98c31d694..67e65f8e7e7d4 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -633,22 +633,21 @@ int zl3073x_ref_phase_offsets_update(struct zl3073x_d= ev *zldev, int channel) } =20 /** - * zl3073x_ref_ffo_update - update reference fractional frequency offsets + * zl3073x_ref_freq_meas_latch - latch reference frequency measurements * @zldev: pointer to zl3073x_dev structure + * @type: measurement type (ZL_REF_FREQ_MEAS_CTRL_*) * - * The function asks device to update fractional frequency offsets latch - * registers the latest measured values, reads and stores them into + * The function waits for the previous measurement to finish, selects all + * references and requests a new measurement of the given type. * * Return: 0 on success, <0 on error */ static int -zl3073x_ref_ffo_update(struct zl3073x_dev *zldev) +zl3073x_ref_freq_meas_latch(struct zl3073x_dev *zldev, u8 type) { - int i, rc; + int rc; =20 - /* Per datasheet we have to wait for 'ref_freq_meas_ctrl' to be zero - * to ensure that the measured data are coherent. - */ + /* Wait for previous measurement to finish */ rc =3D zl3073x_poll_zero_u8(zldev, ZL_REG_REF_FREQ_MEAS_CTRL, ZL_REF_FREQ_MEAS_CTRL); if (rc) @@ -664,15 +663,63 @@ zl3073x_ref_ffo_update(struct zl3073x_dev *zldev) if (rc) return rc; =20 - /* Request frequency offset measurement */ - rc =3D zl3073x_write_u8(zldev, ZL_REG_REF_FREQ_MEAS_CTRL, - ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_OFF); + /* Request measurement */ + rc =3D zl3073x_write_u8(zldev, ZL_REG_REF_FREQ_MEAS_CTRL, type); if (rc) return rc; =20 /* Wait for finish */ - rc =3D zl3073x_poll_zero_u8(zldev, ZL_REG_REF_FREQ_MEAS_CTRL, - ZL_REF_FREQ_MEAS_CTRL); + return zl3073x_poll_zero_u8(zldev, ZL_REG_REF_FREQ_MEAS_CTRL, + ZL_REF_FREQ_MEAS_CTRL); +} + +/** + * zl3073x_ref_freq_meas_update - update measured input reference frequenc= ies + * @zldev: pointer to zl3073x_dev structure + * + * The function asks device to latch measured input reference frequencies + * and stores the results in the ref state. + * + * Return: 0 on success, <0 on error + */ +static int +zl3073x_ref_freq_meas_update(struct zl3073x_dev *zldev) +{ + int i, rc; + + rc =3D zl3073x_ref_freq_meas_latch(zldev, ZL_REF_FREQ_MEAS_CTRL_REF_FREQ); + if (rc) + return rc; + + /* Read measured frequencies in Hz (unsigned 32-bit, LSB =3D 1 Hz) */ + for (i =3D 0; i < ZL3073X_NUM_REFS; i++) { + u32 value; + + rc =3D zl3073x_read_u32(zldev, ZL_REG_REF_FREQ(i), &value); + if (rc) + return rc; + + zldev->ref[i].meas_freq =3D value; + } + + return 0; +} + +/** + * zl3073x_ref_ffo_update - update reference fractional frequency offsets + * @zldev: pointer to zl3073x_dev structure + * + * The function asks device to update fractional frequency offsets latch + * registers the latest measured values, reads and stores them into + * + * Return: 0 on success, <0 on error + */ +static int +zl3073x_ref_ffo_update(struct zl3073x_dev *zldev) +{ + int i, rc; + + rc =3D zl3073x_ref_freq_meas_latch(zldev, ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_= OFF); if (rc) return rc; =20 @@ -715,6 +762,13 @@ zl3073x_dev_periodic_work(struct kthread_work *work) dev_warn(zldev->dev, "Failed to update phase offsets: %pe\n", ERR_PTR(rc)); =20 + /* Update measured input reference frequencies */ + rc =3D zl3073x_ref_freq_meas_update(zldev); + if (rc) + dev_warn(zldev->dev, + "Failed to update measured frequencies: %pe\n", + ERR_PTR(rc)); + /* Update references' fractional frequency offsets */ rc =3D zl3073x_ref_ffo_update(zldev); if (rc) diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h index 09fab97a71d7e..55e80e4f08734 100644 --- a/drivers/dpll/zl3073x/ref.h +++ b/drivers/dpll/zl3073x/ref.h @@ -23,6 +23,7 @@ struct zl3073x_dev; * @sync_ctrl: reference sync control * @config: reference config * @ffo: current fractional frequency offset + * @meas_freq: measured input frequency in Hz * @mon_status: reference monitor status */ struct zl3073x_ref { @@ -40,6 +41,7 @@ struct zl3073x_ref { ); struct_group(stat, /* Status */ s64 ffo; + u32 meas_freq; u8 mon_status; ); }; @@ -68,6 +70,18 @@ zl3073x_ref_ffo_get(const struct zl3073x_ref *ref) return ref->ffo; } =20 +/** + * zl3073x_ref_meas_freq_get - get measured input frequency + * @ref: pointer to ref state + * + * Return: measured input frequency in Hz + */ +static inline u32 +zl3073x_ref_meas_freq_get(const struct zl3073x_ref *ref) +{ + return ref->meas_freq; +} + /** * zl3073x_ref_freq_get - get given input reference frequency * @ref: pointer to ref state --=20 2.52.0 From nobody Sat Apr 4 07:47:57 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7996399353 for ; Fri, 20 Mar 2026 10:59:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004385; cv=none; b=Z1g/l3nTeZqeQxyxu5kGitHptYl0rNgaFni7w4BjaiwL+NejSmGfJQnuiBCjt6mX+vmh02ktHIQRwnP0vTpb80xAVxtFn4ggd3I/LJa9TrWbie9RFiIGCzcPFzY+OjkT0c9/H3qBq/UF2BklbhWoekMblQ5i0jXBHcAD52y1Ktg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774004385; c=relaxed/simple; bh=/16a2o1bBFBTamsyHlsUwOjXKdArI+HOsdPgs3rK50Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MvGQ1p6Z2zQTTSTyoECpBuG96b8aAzAggh+DOvwRG27gZbf1whn6/IftSReJWsPbmCp1qjiKLfL64Kj3pQBepXXrNCGmzX4000V5hdqUaarjL4DABspcj4CUlr9MXWC1CrpntVb2Hoa2eXGRcnukzS3gxbIwQU54+K6Q0sm0JsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Zp1BsE3z; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Zp1BsE3z" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774004377; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bZryKPp8MrEGbzSS3pHimlGo1YuKSVEx94HTQlVLP0M=; b=Zp1BsE3zstXrerCPujU1j4+ouabf2BvgRvbsYI9bLIJIAveUWx3uFuGBNsAQZJudeB4rHT 0ofjSDpCQqV8ywhMIZDr6RAsGpst8RWipuZDBYmpPFWVnhH3yLGrMt7//9ygO52Ygwhahj JhFrEdpkaBzItmhJ6rqt12o1+tbNyGg= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-301-3wzFLD_NPei-lMjld-VP-A-1; Fri, 20 Mar 2026 06:59:35 -0400 X-MC-Unique: 3wzFLD_NPei-lMjld-VP-A-1 X-Mimecast-MFC-AGG-ID: 3wzFLD_NPei-lMjld-VP-A_1774004373 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3AF2A19560B4; Fri, 20 Mar 2026 10:59:33 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.45.225.20]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D7F361955F21; Fri, 20 Mar 2026 10:59:29 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Arkadiusz Kubalewski , Guenter Roeck , Jiri Pirko , Prathosh Satish , Vadim Fedorenko , linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Michal Schmidt , Petr Oros , Simon Horman Subject: [PATCH net-next 3/3] dpll: zl3073x: add hwmon support for input reference frequencies Date: Fri, 20 Mar 2026 11:59:15 +0100 Message-ID: <20260320105915.149068-4-ivecera@redhat.com> In-Reply-To: <20260320105915.149068-1-ivecera@redhat.com> References: <20260320105915.149068-1-ivecera@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Expose measured input reference frequencies via the hwmon interface using custom sysfs attributes (freqN_input and freqN_label) since hwmon has no native frequency sensor type. The frequency values are read from the cached measurements updated by the periodic work thread. Cache the device ready state in struct zl3073x_dev so that freq_input_show() can return -ENODATA without an I2C access when the device firmware is not configured. Signed-off-by: Ivan Vecera --- drivers/dpll/zl3073x/core.c | 4 +- drivers/dpll/zl3073x/core.h | 2 + drivers/dpll/zl3073x/hwmon.c | 86 +++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 67e65f8e7e7d4..5805f87167c20 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -874,7 +874,9 @@ int zl3073x_dev_start(struct zl3073x_dev *zldev, bool f= ull) return rc; } =20 - if (!FIELD_GET(ZL_INFO_READY, info)) { + zldev->ready =3D !!FIELD_GET(ZL_INFO_READY, info); + + if (!zldev->ready) { /* The ready bit indicates that the firmware was successfully * configured and is ready for normal operation. If it is * cleared then the configuration stored in flash is wrong diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h index 99440620407da..a416b8a65f41b 100644 --- a/drivers/dpll/zl3073x/core.h +++ b/drivers/dpll/zl3073x/core.h @@ -48,6 +48,7 @@ struct zl3073x_chip_info { * @regmap: regmap to access device registers * @info: detected chip info * @multiop_lock: to serialize multiple register operations + * @ready: true if device firmware is configured and ready for normal oper= ation * @ref: array of input references' invariants * @out: array of outs' invariants * @synth: array of synths' invariants @@ -63,6 +64,7 @@ struct zl3073x_dev { struct regmap *regmap; const struct zl3073x_chip_info *info; struct mutex multiop_lock; + bool ready; =20 /* Invariants */ struct zl3073x_ref ref[ZL3073X_NUM_REFS]; diff --git a/drivers/dpll/zl3073x/hwmon.c b/drivers/dpll/zl3073x/hwmon.c index 4b44df4def820..96879609ce100 100644 --- a/drivers/dpll/zl3073x/hwmon.c +++ b/drivers/dpll/zl3073x/hwmon.c @@ -2,9 +2,11 @@ =20 #include #include +#include =20 #include "core.h" #include "hwmon.h" +#include "ref.h" #include "regs.h" =20 static int zl3073x_hwmon_read(struct device *dev, @@ -55,6 +57,88 @@ static const struct hwmon_chip_info zl3073x_hwmon_chip_i= nfo =3D { .info =3D zl3073x_hwmon_info, }; =20 +static ssize_t freq_input_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct zl3073x_dev *zldev =3D dev_get_drvdata(dev); + int index =3D to_sensor_dev_attr(devattr)->index; + const struct zl3073x_ref *ref; + + if (!zldev->ready) + return -ENODATA; + + ref =3D zl3073x_ref_state_get(zldev, index); + + return sysfs_emit(buf, "%u\n", zl3073x_ref_meas_freq_get(ref)); +} + +static ssize_t freq_label_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + static const char * const labels[] =3D { + "REF0P", "REF0N", "REF1P", "REF1N", "REF2P", + "REF2N", "REF3P", "REF3N", "REF4P", "REF4N", + }; + int index =3D to_sensor_dev_attr(devattr)->index; + + return sysfs_emit(buf, "%s\n", labels[index]); +} + +static SENSOR_DEVICE_ATTR_RO(freq0_input, freq_input, 0); +static SENSOR_DEVICE_ATTR_RO(freq1_input, freq_input, 1); +static SENSOR_DEVICE_ATTR_RO(freq2_input, freq_input, 2); +static SENSOR_DEVICE_ATTR_RO(freq3_input, freq_input, 3); +static SENSOR_DEVICE_ATTR_RO(freq4_input, freq_input, 4); +static SENSOR_DEVICE_ATTR_RO(freq5_input, freq_input, 5); +static SENSOR_DEVICE_ATTR_RO(freq6_input, freq_input, 6); +static SENSOR_DEVICE_ATTR_RO(freq7_input, freq_input, 7); +static SENSOR_DEVICE_ATTR_RO(freq8_input, freq_input, 8); +static SENSOR_DEVICE_ATTR_RO(freq9_input, freq_input, 9); + +static SENSOR_DEVICE_ATTR_RO(freq0_label, freq_label, 0); +static SENSOR_DEVICE_ATTR_RO(freq1_label, freq_label, 1); +static SENSOR_DEVICE_ATTR_RO(freq2_label, freq_label, 2); +static SENSOR_DEVICE_ATTR_RO(freq3_label, freq_label, 3); +static SENSOR_DEVICE_ATTR_RO(freq4_label, freq_label, 4); +static SENSOR_DEVICE_ATTR_RO(freq5_label, freq_label, 5); +static SENSOR_DEVICE_ATTR_RO(freq6_label, freq_label, 6); +static SENSOR_DEVICE_ATTR_RO(freq7_label, freq_label, 7); +static SENSOR_DEVICE_ATTR_RO(freq8_label, freq_label, 8); +static SENSOR_DEVICE_ATTR_RO(freq9_label, freq_label, 9); + +static struct attribute *zl3073x_freq_attrs[] =3D { + &sensor_dev_attr_freq0_input.dev_attr.attr, + &sensor_dev_attr_freq0_label.dev_attr.attr, + &sensor_dev_attr_freq1_input.dev_attr.attr, + &sensor_dev_attr_freq1_label.dev_attr.attr, + &sensor_dev_attr_freq2_input.dev_attr.attr, + &sensor_dev_attr_freq2_label.dev_attr.attr, + &sensor_dev_attr_freq3_input.dev_attr.attr, + &sensor_dev_attr_freq3_label.dev_attr.attr, + &sensor_dev_attr_freq4_input.dev_attr.attr, + &sensor_dev_attr_freq4_label.dev_attr.attr, + &sensor_dev_attr_freq5_input.dev_attr.attr, + &sensor_dev_attr_freq5_label.dev_attr.attr, + &sensor_dev_attr_freq6_input.dev_attr.attr, + &sensor_dev_attr_freq6_label.dev_attr.attr, + &sensor_dev_attr_freq7_input.dev_attr.attr, + &sensor_dev_attr_freq7_label.dev_attr.attr, + &sensor_dev_attr_freq8_input.dev_attr.attr, + &sensor_dev_attr_freq8_label.dev_attr.attr, + &sensor_dev_attr_freq9_input.dev_attr.attr, + &sensor_dev_attr_freq9_label.dev_attr.attr, + NULL, +}; + +static const struct attribute_group zl3073x_freq_group =3D { + .attrs =3D zl3073x_freq_attrs, +}; + +static const struct attribute_group *zl3073x_hwmon_groups[] =3D { + &zl3073x_freq_group, + NULL, +}; + int zl3073x_hwmon_init(struct zl3073x_dev *zldev) { struct device *hwmon; @@ -62,6 +146,6 @@ int zl3073x_hwmon_init(struct zl3073x_dev *zldev) hwmon =3D devm_hwmon_device_register_with_info(zldev->dev, "zl3073x", zldev, &zl3073x_hwmon_chip_info, - NULL); + zl3073x_hwmon_groups); return PTR_ERR_OR_ZERO(hwmon); } --=20 2.52.0