From nobody Wed Apr 1 22:33:59 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 718AA39D6E3 for ; Wed, 1 Apr 2026 09:12:57 +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=1775034778; cv=none; b=ti3KJoROFoZ9Rc8WytEsXstJH4PVTUZDjz4yUO1ZeLwz52iFJi1foOvMwUiFrSGfBrrBMuqccu85FQbGoMcDuBsasV9ocLAPYlV3N2lo5sPrUhLijPUOyem8BCedRwf887roeNOPnpjcfZGkANb5RhR1d/azt/U8gRhpmTRq6AE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775034778; c=relaxed/simple; bh=sHAcPFkyNdUQAvbRPH/GfSpL3BzTk6+FQRRwQBXtC9g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Erxf3Tpmvh3OYozFFJl4ueoGOtDVf04ArayOQdYWGL6fQipmVUmCi3ZvOuPO9K7zVJ9ADPRIwxBD8So7gpnIegGeq54pKhqwAIjAFNMbg2mUKWzcuuFuk9KMRwqO2AiOuy1XQ5sEym+3A0mURE5/hEHhRuWt728tbwcj/hdRHkc= 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=N0fU+TNi; 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="N0fU+TNi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775034776; 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=EdjC/Gl7/ya5ZhOcMWaMy9PpFWCT86jKefTGUojJ/zQ=; b=N0fU+TNiacAz4M4Oos2zDxxWqjYsXh77e7tG96voAhxfpzTLfsHOHFCO92edSbvngy4/5n 5wGt8A2RcerUmTft+aD49EEmjZyHYZQqaoOBPzwKKUvsQWJdPBXOM/kZIUdltWoJY1sAIG 69VS/mQkioVvjfcX/ACE+0NVRdK7rpY= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-377--60d2waENkql_P-4X28cCA-1; Wed, 01 Apr 2026 05:12:52 -0400 X-MC-Unique: -60d2waENkql_P-4X28cCA-1 X-Mimecast-MFC-AGG-ID: -60d2waENkql_P-4X28cCA_1775034770 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4936318002D7; Wed, 1 Apr 2026 09:12:50 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.44.33.175]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 05D2B1955F2E; Wed, 1 Apr 2026 09:12:44 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Vadim Fedorenko , Arkadiusz Kubalewski , "David S. Miller" , Donald Hunter , Eric Dumazet , Jakub Kicinski , Jiri Pirko , Jonathan Corbet , Michal Schmidt , Paolo Abeni , Petr Oros , Prathosh Satish , Shuah Khan , Simon Horman , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 1/3] dpll: add frequency monitoring to netlink spec Date: Wed, 1 Apr 2026 11:12:35 +0200 Message-ID: <20260401091237.1071995-2-ivecera@redhat.com> In-Reply-To: <20260401091237.1071995-1-ivecera@redhat.com> References: <20260401091237.1071995-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" Add DPLL_A_FREQUENCY_MONITOR device attribute to allow control over the frequency monitor feature. The attribute uses the existing dpll_feature_state enum (enable/disable) and is present in both device-get reply and device-set request. Add DPLL_A_PIN_MEASURED_FREQUENCY pin attribute to expose the measured input frequency in millihertz (mHz). The attribute is present in the pin-get reply. Add DPLL_PIN_MEASURED_FREQUENCY_DIVIDER constant to allow userspace to extract integer and fractional parts. Reviewed-by: Vadim Fedorenko Signed-off-by: Ivan Vecera --- Changes v2 -> v3: - Improved frequency-monitor doc wording (Jakub) - Changed measured-frequency to mHz with divider constant (Jakub) Changes v1 -> v2: - Renamed actual-frequency to measured-frequency (Vadim) --- Documentation/driver-api/dpll.rst | 20 +++++++++++++++ Documentation/netlink/specs/dpll.yaml | 35 +++++++++++++++++++++++++++ drivers/dpll/dpll_nl.c | 5 ++-- include/uapi/linux/dpll.h | 5 +++- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/d= pll.rst index 83118c728ed90..93c191b2d0898 100644 --- a/Documentation/driver-api/dpll.rst +++ b/Documentation/driver-api/dpll.rst @@ -250,6 +250,24 @@ in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute. ``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D =20 +Frequency monitor +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Some DPLL devices may offer the capability to measure the actual +frequency of all available input pins. The attribute and current feature s= tate +shall be included in the response message of the ``DPLL_CMD_DEVICE_GET`` +command for supported DPLL devices. In such cases, users can also control +the feature using the ``DPLL_CMD_DEVICE_SET`` command by setting the +``enum dpll_feature_state`` values for the attribute. +Once enabled the measured input frequency for each input pin shall be +returned in the ``DPLL_A_PIN_MEASURED_FREQUENCY`` attribute. The value +is in millihertz (mHz), using ``DPLL_PIN_MEASURED_FREQUENCY_DIVIDER`` +as the divider. + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D + ``DPLL_A_FREQUENCY_MONITOR`` attr state of a feature + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D + Embedded SYNC =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -411,6 +429,8 @@ according to attribute purpose. ``DPLL_A_PIN_STATE`` attr state of pin on the parent pin ``DPLL_A_PIN_CAPABILITIES`` attr bitmask of pin capabilities + ``DPLL_A_PIN_MEASURED_FREQUENCY`` attr measured frequency of + an input pin in mHz =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/= specs/dpll.yaml index 3dd48a32f7837..40465a3d7fc20 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -240,6 +240,20 @@ definitions: integer part of a measured phase offset value. Value of (DPLL_A_PHASE_OFFSET % DPLL_PHASE_OFFSET_DIVIDER) is a fractional part of a measured phase offset value. + - + type: const + name: pin-measured-frequency-divider + value: 1000 + doc: | + pin measured frequency divider allows userspace to calculate + a value of measured input frequency as a fractional value with + three digit decimal precision (millihertz). + Value of (DPLL_A_PIN_MEASURED_FREQUENCY / + DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is an integer part of + a measured frequency value. + Value of (DPLL_A_PIN_MEASURED_FREQUENCY % + DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is a fractional part of + a measured frequency value. - type: enum name: feature-state @@ -319,6 +333,13 @@ attribute-sets: name: phase-offset-avg-factor type: u32 doc: Averaging factor applied to calculation of reported phase off= set. + - + name: frequency-monitor + type: u32 + enum: feature-state + doc: Current or desired state of the frequency monitor feature. + If enabled, dpll device shall measure all currently available + inputs for their actual input frequency. - name: pin enum-name: dpll_a_pin @@ -456,6 +477,17 @@ attribute-sets: Value is in PPT (parts per trillion, 10^-12). Note: This attribute provides higher resolution than the standard fractional-frequency-offset (which is in PPM). + - + name: measured-frequency + type: u64 + doc: | + The measured frequency of the input pin in millihertz (mHz). + Value of (DPLL_A_PIN_MEASURED_FREQUENCY / + DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is an integer part (Hz) + of a measured frequency value. + Value of (DPLL_A_PIN_MEASURED_FREQUENCY % + DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is a fractional part + of a measured frequency value. =20 - name: pin-parent-device @@ -544,6 +576,7 @@ operations: - type - phase-offset-monitor - phase-offset-avg-factor + - frequency-monitor =20 dump: reply: *dev-attrs @@ -563,6 +596,7 @@ operations: - mode - phase-offset-monitor - phase-offset-avg-factor + - frequency-monitor - name: device-create-ntf doc: Notification about device appearing @@ -643,6 +677,7 @@ operations: - esync-frequency-supported - esync-pulse - reference-sync + - measured-frequency =20 dump: request: diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index a2b22d4921142..1e652340a5d73 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -43,11 +43,12 @@ static const struct nla_policy dpll_device_get_nl_polic= y[DPLL_A_ID + 1] =3D { }; =20 /* DPLL_CMD_DEVICE_SET - do */ -static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_PHASE_OFFS= ET_AVG_FACTOR + 1] =3D { +static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_FREQUENCY_= MONITOR + 1] =3D { [DPLL_A_ID] =3D { .type =3D NLA_U32, }, [DPLL_A_MODE] =3D NLA_POLICY_RANGE(NLA_U32, 1, 2), [DPLL_A_PHASE_OFFSET_MONITOR] =3D NLA_POLICY_MAX(NLA_U32, 1), [DPLL_A_PHASE_OFFSET_AVG_FACTOR] =3D { .type =3D NLA_U32, }, + [DPLL_A_FREQUENCY_MONITOR] =3D NLA_POLICY_MAX(NLA_U32, 1), }; =20 /* DPLL_CMD_PIN_ID_GET - do */ @@ -115,7 +116,7 @@ static const struct genl_split_ops dpll_nl_ops[] =3D { .doit =3D dpll_nl_device_set_doit, .post_doit =3D dpll_post_doit, .policy =3D dpll_device_set_nl_policy, - .maxattr =3D DPLL_A_PHASE_OFFSET_AVG_FACTOR, + .maxattr =3D DPLL_A_FREQUENCY_MONITOR, .flags =3D GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index de0005f28e5c5..871685f7c353b 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -191,7 +191,8 @@ enum dpll_pin_capabilities { DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE =3D 4, }; =20 -#define DPLL_PHASE_OFFSET_DIVIDER 1000 +#define DPLL_PHASE_OFFSET_DIVIDER 1000 +#define DPLL_PIN_MEASURED_FREQUENCY_DIVIDER 1000 =20 /** * enum dpll_feature_state - Allow control (enable/disable) and status che= cking @@ -218,6 +219,7 @@ enum dpll_a { DPLL_A_CLOCK_QUALITY_LEVEL, DPLL_A_PHASE_OFFSET_MONITOR, DPLL_A_PHASE_OFFSET_AVG_FACTOR, + DPLL_A_FREQUENCY_MONITOR, =20 __DPLL_A_MAX, DPLL_A_MAX =3D (__DPLL_A_MAX - 1) @@ -254,6 +256,7 @@ enum dpll_a_pin { DPLL_A_PIN_REFERENCE_SYNC, DPLL_A_PIN_PHASE_ADJUST_GRAN, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT, + DPLL_A_PIN_MEASURED_FREQUENCY, =20 __DPLL_A_PIN_MAX, DPLL_A_PIN_MAX =3D (__DPLL_A_PIN_MAX - 1) --=20 2.52.0 From nobody Wed Apr 1 22:33:59 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.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 D55343A8746 for ; Wed, 1 Apr 2026 09:13:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775034783; cv=none; b=oIJ86GmKx1/3SKpX/IqnmWelNH9lGphWuCitq2LMyXID0Z4SByC8UROzHpjyteQerxcVCII0dqe1s5/LNsmW6qp1aoYN7YdCA3UkACRlwksvi5YzCrhKP08Efthe9O3PXo3nvWIn6sG5neaR/03n5oj5+20dbw5RQT3IvtQC0oQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775034783; c=relaxed/simple; bh=FfmH3dxHcLfYRPYmUEYCmSB3fNGK4nNnH0WPIv/V50c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ouMvvmL/TW3CsvLecEEGeJbZeKirCD4mhu+e81oQb3+SzofB3Pxlx1Hcf5H8cNzbLwNnrA6xemMLdORF2ic9+j6gHT0hhlMlLBVGzifsrklaPDzzW+412LGzF27Fgk6K/DtxjZLvY5BujjbTwTPDxaYjZ7MD5CL57uKIkKBcd+c= 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=igMggy2d; arc=none smtp.client-ip=170.10.133.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="igMggy2d" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775034781; 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=jhekxNKPnvZH9+6ShSlDYmZ7VsVsnq78Ozj5baBPZ8w=; b=igMggy2dBp4p5XQ+FY0wDf8ciSj1Nwj2zmMQojqEiAJ1xEvFSM6uBh6/WXiGxh/z6Wxss4 yO9vc2fkAFmyGIMHsEzdwc86hU6OrkVzXE0k2I8e3z5afEgZWmEG0BxZMsBEzFWmpDRjtW laVvw9vDbWBdNAY8t/lSLg/gH0GOkn0= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-404-inGLJeptNme__U-FMVB4JA-1; Wed, 01 Apr 2026 05:12:57 -0400 X-MC-Unique: inGLJeptNme__U-FMVB4JA-1 X-Mimecast-MFC-AGG-ID: inGLJeptNme__U-FMVB4JA_1775034776 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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 94FD818005B3; Wed, 1 Apr 2026 09:12:55 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.44.33.175]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B50C819560AB; Wed, 1 Apr 2026 09:12:50 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Vadim Fedorenko , Arkadiusz Kubalewski , "David S. Miller" , Donald Hunter , Eric Dumazet , Jakub Kicinski , Jiri Pirko , Jonathan Corbet , Michal Schmidt , Paolo Abeni , Petr Oros , Prathosh Satish , Shuah Khan , Simon Horman , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 2/3] dpll: add frequency monitoring callback ops Date: Wed, 1 Apr 2026 11:12:36 +0200 Message-ID: <20260401091237.1071995-3-ivecera@redhat.com> In-Reply-To: <20260401091237.1071995-1-ivecera@redhat.com> References: <20260401091237.1071995-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" Add new callback operations for a dpll device: - freq_monitor_get(..) - to obtain current state of frequency monitor feature from dpll device, - freq_monitor_set(..) - to allow feature configuration. Add new callback operation for a dpll pin: - measured_freq_get(..) - to obtain the measured frequency in mHz. Obtain the feature state value using the get callback and provide it to the user if the device driver implements callbacks. The measured_freq_get pin callback is only invoked when the frequency monitor is enabled. The freq_monitor_get device callback is required when measured_freq_get is provided by the driver. Execute the set callback upon user requests. Reviewed-by: Vadim Fedorenko Signed-off-by: Ivan Vecera --- Changes v2 -> v3: - Made freq_monitor_get required when measured_freq_get is present (Jakub) Changes v1 -> v2: - Renamed actual-frequency to measured-frequency (Vadim) --- drivers/dpll/dpll_netlink.c | 92 +++++++++++++++++++++++++++++++++++++ include/linux/dpll.h | 10 ++++ 2 files changed, 102 insertions(+) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 83cbd64abf5a4..576d0cd074bd4 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -175,6 +175,26 @@ dpll_msg_add_phase_offset_monitor(struct sk_buff *msg,= struct dpll_device *dpll, return 0; } =20 +static int +dpll_msg_add_freq_monitor(struct sk_buff *msg, struct dpll_device *dpll, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *ops =3D dpll_device_ops(dpll); + enum dpll_feature_state state; + int ret; + + if (ops->freq_monitor_set && ops->freq_monitor_get) { + ret =3D ops->freq_monitor_get(dpll, dpll_priv(dpll), + &state, extack); + if (ret) + return ret; + if (nla_put_u32(msg, DPLL_A_FREQUENCY_MONITOR, state)) + return -EMSGSIZE; + } + + return 0; +} + static int dpll_msg_add_phase_offset_avg_factor(struct sk_buff *msg, struct dpll_device *dpll, @@ -400,6 +420,40 @@ static int dpll_msg_add_ffo(struct sk_buff *msg, struc= t dpll_pin *pin, ffo); } =20 +static int dpll_msg_add_measured_freq(struct sk_buff *msg, struct dpll_pin= *pin, + struct dpll_pin_ref *ref, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *dev_ops =3D dpll_device_ops(ref->dpll); + const struct dpll_pin_ops *ops =3D dpll_pin_ops(ref); + struct dpll_device *dpll =3D ref->dpll; + enum dpll_feature_state state; + u64 measured_freq; + int ret; + + if (!ops->measured_freq_get) + return 0; + if (WARN_ON(!dev_ops->freq_monitor_get)) + return -EINVAL; + ret =3D dev_ops->freq_monitor_get(dpll, dpll_priv(dpll), + &state, extack); + if (ret) + return ret; + if (state =3D=3D DPLL_FEATURE_STATE_DISABLE) + return 0; + ret =3D ops->measured_freq_get(pin, dpll_pin_on_dpll_priv(dpll, pin), + dpll, dpll_priv(dpll), &measured_freq, + extack); + if (ret) + return ret; + if (nla_put_64bit(msg, DPLL_A_PIN_MEASURED_FREQUENCY, + sizeof(measured_freq), &measured_freq, + DPLL_A_PIN_PAD)) + return -EMSGSIZE; + + return 0; +} + static int dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) @@ -670,6 +724,9 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_p= in *pin, if (ret) return ret; ret =3D dpll_msg_add_ffo(msg, pin, ref, extack); + if (ret) + return ret; + ret =3D dpll_msg_add_measured_freq(msg, pin, ref, extack); if (ret) return ret; ret =3D dpll_msg_add_pin_esync(msg, pin, ref, extack); @@ -722,6 +779,9 @@ dpll_device_get_one(struct dpll_device *dpll, struct sk= _buff *msg, if (ret) return ret; ret =3D dpll_msg_add_phase_offset_avg_factor(msg, dpll, extack); + if (ret) + return ret; + ret =3D dpll_msg_add_freq_monitor(msg, dpll, extack); if (ret) return ret; =20 @@ -948,6 +1008,32 @@ dpll_phase_offset_avg_factor_set(struct dpll_device *= dpll, struct nlattr *a, extack); } =20 +static int +dpll_freq_monitor_set(struct dpll_device *dpll, struct nlattr *a, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *ops =3D dpll_device_ops(dpll); + enum dpll_feature_state state =3D nla_get_u32(a), old_state; + int ret; + + if (!(ops->freq_monitor_set && ops->freq_monitor_get)) { + NL_SET_ERR_MSG_ATTR(extack, a, + "dpll device not capable of frequency monitor"); + return -EOPNOTSUPP; + } + ret =3D ops->freq_monitor_get(dpll, dpll_priv(dpll), &old_state, + extack); + if (ret) { + NL_SET_ERR_MSG(extack, + "unable to get current state of frequency monitor"); + return ret; + } + if (state =3D=3D old_state) + return 0; + + return ops->freq_monitor_set(dpll, dpll_priv(dpll), state, extack); +} + static int dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a, struct netlink_ext_ack *extack) @@ -1878,6 +1964,12 @@ dpll_set_from_nlattr(struct dpll_device *dpll, struc= t genl_info *info) if (ret) return ret; break; + case DPLL_A_FREQUENCY_MONITOR: + ret =3D dpll_freq_monitor_set(dpll, a, + info->extack); + if (ret) + return ret; + break; } } =20 diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 2ce295b46b8cd..b7277a8b484d2 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -52,6 +52,12 @@ struct dpll_device_ops { int (*phase_offset_avg_factor_get)(const struct dpll_device *dpll, void *dpll_priv, u32 *factor, struct netlink_ext_ack *extack); + int (*freq_monitor_set)(const struct dpll_device *dpll, void *dpll_priv, + enum dpll_feature_state state, + struct netlink_ext_ack *extack); + int (*freq_monitor_get)(const struct dpll_device *dpll, void *dpll_priv, + enum dpll_feature_state *state, + struct netlink_ext_ack *extack); }; =20 struct dpll_pin_ops { @@ -110,6 +116,10 @@ struct dpll_pin_ops { int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_device *dpll, void *dpll_priv, s64 *ffo, struct netlink_ext_ack *extack); + int (*measured_freq_get)(const struct dpll_pin *pin, void *pin_priv, + const struct dpll_device *dpll, + void *dpll_priv, u64 *measured_freq, + struct netlink_ext_ack *extack); int (*esync_set)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_device *dpll, void *dpll_priv, u64 freq, struct netlink_ext_ack *extack); --=20 2.52.0 From nobody Wed Apr 1 22:33:59 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 7B9753C5DD6 for ; Wed, 1 Apr 2026 09:13:08 +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=1775034790; cv=none; b=bsENZ5RqqE6keHkOp4juejg+/5dokTdC5ExY+Ia/jQXryY5+Sag8LX84AR3jiAN6LqCOKEbDNEHYIePeEPA+ouI4jl9art3RKf6Hmmfd4by8zFGRnmwSeFWw7bnPuKvBH3KyOlMeCp5oS4Nn67cE4cfhXFz3dAR6YHkl9qMTIrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775034790; c=relaxed/simple; bh=mhuTpIbfyq3SIzgk0CJMINKU5CuIKzC3LnXUSUFv45M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZmdrjxNfOKAo/isa21JWEBZBKoc82vZRyd3dUO2w1/MXBXfLvs0eA7cmzM+I9qX2On6XGsHAAZZtEMmCqhoZ0WgeABIoZ6PNpjxSx77x+l3DW9jlF/DlmF0BdkuDC3wybswul7rfUTGDWL5OTP2fVEAm/yPgriPKTia2Ur0oPcM= 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=FTFtTWLL; 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="FTFtTWLL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775034787; 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=6AFoE+BHETSvnDnn6Q4Tz2Gj1izB0cSeVWxhoo852x4=; b=FTFtTWLLyTo1DSIs3A4ojyZndoZmQbLEJ6BN/YyUv23Qc3KqfLrXdwy4qv5ckX5AbzXprJ R2UPI7QC000F7rN997m9JEPcqdhnzbhm+NvZh2ALOc829smW5q1dDevwv9tP6HIDK62Kem SaiDkvMYq1hh5hiwraUrdua3xyFG3Yo= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-27-5A_U-xVaMj2K6bVLX-KRfg-1; Wed, 01 Apr 2026 05:13:03 -0400 X-MC-Unique: 5A_U-xVaMj2K6bVLX-KRfg-1 X-Mimecast-MFC-AGG-ID: 5A_U-xVaMj2K6bVLX-KRfg_1775034781 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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1E8DE1800371; Wed, 1 Apr 2026 09:13:01 +0000 (UTC) Received: from p16v.redhat.com (unknown [10.44.33.175]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1A5F119560AB; Wed, 1 Apr 2026 09:12:55 +0000 (UTC) From: Ivan Vecera To: netdev@vger.kernel.org Cc: Petr Oros , Arkadiusz Kubalewski , "David S. Miller" , Donald Hunter , Eric Dumazet , Jakub Kicinski , Jiri Pirko , Jonathan Corbet , Michal Schmidt , Paolo Abeni , Prathosh Satish , Shuah Khan , Simon Horman , Vadim Fedorenko , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 3/3] dpll: zl3073x: implement frequency monitoring Date: Wed, 1 Apr 2026 11:12:37 +0200 Message-ID: <20260401091237.1071995-4-ivecera@redhat.com> In-Reply-To: <20260401091237.1071995-1-ivecera@redhat.com> References: <20260401091237.1071995-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. Add freq_monitor boolean to struct zl3073x_dpll and implement the freq_monitor_set/get device callbacks to enable/disable frequency monitoring via the DPLL netlink interface. Implement measured_freq_get pin callback for input pins that returns the measured input frequency in mHz. Reviewed-by: Petr Oros Signed-off-by: Ivan Vecera --- Changes v2 -> v3: - Changed measured_freq_get to return value in mHz Changes v1 -> v2: - Renamed actual-frequency to measured-frequency (Vadim) --- drivers/dpll/zl3073x/core.c | 88 ++++++++++++++++++++++++++----- drivers/dpll/zl3073x/dpll.c | 100 ++++++++++++++++++++++++++++++++++-- drivers/dpll/zl3073x/dpll.h | 2 + drivers/dpll/zl3073x/ref.h | 14 +++++ 4 files changed, 187 insertions(+), 17 deletions(-) diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 6363002d48d46..cb47a5db061aa 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -632,22 +632,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) @@ -663,15 +662,64 @@ 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 latch the latest measured fractional + * frequency offset values, reads and stores them into the ref state. + * + * 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 @@ -714,6 +762,20 @@ 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 if any DPLL has + * frequency monitoring enabled. + */ + list_for_each_entry(zldpll, &zldev->dplls, list) { + if (zldpll->freq_monitor) { + rc =3D zl3073x_ref_freq_meas_update(zldev); + if (rc) + dev_warn(zldev->dev, + "Failed to update measured frequencies: %pe\n", + ERR_PTR(rc)); + break; + } + } + /* Update references' fractional frequency offsets */ rc =3D zl3073x_ref_ffo_update(zldev); if (rc) diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index a29f606318f6d..d788ca45a17e5 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -39,6 +39,7 @@ * @pin_state: last saved pin state * @phase_offset: last saved pin phase offset * @freq_offset: last saved fractional frequency offset + * @measured_freq: last saved measured frequency */ struct zl3073x_dpll_pin { struct list_head list; @@ -54,6 +55,7 @@ struct zl3073x_dpll_pin { enum dpll_pin_state pin_state; s64 phase_offset; s64 freq_offset; + u32 measured_freq; }; =20 /* @@ -202,6 +204,21 @@ zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *= dpll_pin, void *pin_priv, return 0; } =20 +static int +zl3073x_dpll_input_pin_measured_freq_get(const struct dpll_pin *dpll_pin, + void *pin_priv, + const struct dpll_device *dpll, + void *dpll_priv, u64 *measured_freq, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll_pin *pin =3D pin_priv; + + *measured_freq =3D pin->measured_freq; + *measured_freq *=3D DPLL_PIN_MEASURED_FREQUENCY_DIVIDER; + + return 0; +} + static int zl3073x_dpll_input_pin_frequency_get(const struct dpll_pin *dpll_pin, void *pin_priv, @@ -1116,6 +1133,35 @@ zl3073x_dpll_phase_offset_monitor_set(const struct d= pll_device *dpll, return 0; } =20 +static int +zl3073x_dpll_freq_monitor_get(const struct dpll_device *dpll, + void *dpll_priv, + enum dpll_feature_state *state, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *zldpll =3D dpll_priv; + + if (zldpll->freq_monitor) + *state =3D DPLL_FEATURE_STATE_ENABLE; + else + *state =3D DPLL_FEATURE_STATE_DISABLE; + + return 0; +} + +static int +zl3073x_dpll_freq_monitor_set(const struct dpll_device *dpll, + void *dpll_priv, + enum dpll_feature_state state, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *zldpll =3D dpll_priv; + + zldpll->freq_monitor =3D (state =3D=3D DPLL_FEATURE_STATE_ENABLE); + + return 0; +} + static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops =3D { .direction_get =3D zl3073x_dpll_pin_direction_get, .esync_get =3D zl3073x_dpll_input_pin_esync_get, @@ -1123,6 +1169,7 @@ static const struct dpll_pin_ops zl3073x_dpll_input_p= in_ops =3D { .ffo_get =3D zl3073x_dpll_input_pin_ffo_get, .frequency_get =3D zl3073x_dpll_input_pin_frequency_get, .frequency_set =3D zl3073x_dpll_input_pin_frequency_set, + .measured_freq_get =3D zl3073x_dpll_input_pin_measured_freq_get, .phase_offset_get =3D zl3073x_dpll_input_pin_phase_offset_get, .phase_adjust_get =3D zl3073x_dpll_input_pin_phase_adjust_get, .phase_adjust_set =3D zl3073x_dpll_input_pin_phase_adjust_set, @@ -1151,6 +1198,8 @@ static const struct dpll_device_ops zl3073x_dpll_devi= ce_ops =3D { .phase_offset_avg_factor_set =3D zl3073x_dpll_phase_offset_avg_factor_set, .phase_offset_monitor_get =3D zl3073x_dpll_phase_offset_monitor_get, .phase_offset_monitor_set =3D zl3073x_dpll_phase_offset_monitor_set, + .freq_monitor_get =3D zl3073x_dpll_freq_monitor_get, + .freq_monitor_set =3D zl3073x_dpll_freq_monitor_set, .supported_modes_get =3D zl3073x_dpll_supported_modes_get, }; =20 @@ -1572,6 +1621,7 @@ zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *p= in) struct zl3073x_dev *zldev =3D zldpll->dev; const struct zl3073x_ref *ref; u8 ref_id; + s64 ffo; =20 /* Get reference monitor status */ ref_id =3D zl3073x_input_pin_ref_get(pin->id); @@ -1582,10 +1632,47 @@ zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin = *pin) return false; =20 /* Compare with previous value */ - if (pin->freq_offset !=3D ref->ffo) { + ffo =3D zl3073x_ref_ffo_get(ref); + if (pin->freq_offset !=3D ffo) { dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n", - pin->label, pin->freq_offset, ref->ffo); - pin->freq_offset =3D ref->ffo; + pin->label, pin->freq_offset, ffo); + pin->freq_offset =3D ffo; + + return true; + } + + return false; +} + +/** + * zl3073x_dpll_pin_measured_freq_check - check for pin measured frequency + * change + * @pin: pin to check + * + * Check for the given pin's measured frequency change. + * + * Return: true on measured frequency change, false otherwise + */ +static bool +zl3073x_dpll_pin_measured_freq_check(struct zl3073x_dpll_pin *pin) +{ + struct zl3073x_dpll *zldpll =3D pin->dpll; + struct zl3073x_dev *zldev =3D zldpll->dev; + const struct zl3073x_ref *ref; + u8 ref_id; + u32 freq; + + if (!zldpll->freq_monitor) + return false; + + ref_id =3D zl3073x_input_pin_ref_get(pin->id); + ref =3D zl3073x_ref_state_get(zldev, ref_id); + + freq =3D zl3073x_ref_meas_freq_get(ref); + if (pin->measured_freq !=3D freq) { + dev_dbg(zldev->dev, "%s measured freq changed: %u -> %u\n", + pin->label, pin->measured_freq, freq); + pin->measured_freq =3D freq; =20 return true; } @@ -1677,13 +1764,18 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zld= pll) pin_changed =3D true; } =20 - /* Check for phase offset and ffo change once per second */ + /* Check for phase offset, ffo, and measured freq change + * once per second. + */ if (zldpll->check_count % 2 =3D=3D 0) { if (zl3073x_dpll_pin_phase_offset_check(pin)) pin_changed =3D true; =20 if (zl3073x_dpll_pin_ffo_check(pin)) pin_changed =3D true; + + if (zl3073x_dpll_pin_measured_freq_check(pin)) + pin_changed =3D true; } =20 if (pin_changed) diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h index 115ee4f67e7ab..434c32a7db123 100644 --- a/drivers/dpll/zl3073x/dpll.h +++ b/drivers/dpll/zl3073x/dpll.h @@ -15,6 +15,7 @@ * @id: DPLL index * @check_count: periodic check counter * @phase_monitor: is phase offset monitor enabled + * @freq_monitor: is frequency monitor enabled * @ops: DPLL device operations for this instance * @dpll_dev: pointer to registered DPLL device * @tracker: tracking object for the acquired reference @@ -28,6 +29,7 @@ struct zl3073x_dpll { u8 id; u8 check_count; bool phase_monitor; + bool freq_monitor; struct dpll_device_ops ops; struct dpll_device *dpll_dev; dpll_tracker tracker; diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h index 06d8d4d97ea26..be16be20dbc7e 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