From: netdev-bot+sashiko@kernel.org
To: arouhi@sitime.com
Cc: jiri@resnulli.us, vadim.fedorenko@linux.dev,
arkadiusz.kubalewski@intel.com, ivecera@redhat.com,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
cjubran@nvidia.com, Oleg.Zadorozhnyi@devoxsoftware.com,
devicetree@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, kuba@kernel.org
Subject: Re: [PATCH net-next v8 04/15] dpll: sit9531x: read DPLL types and pin properties from system firmware
Date: Tue, 08 Sep 2026 12:45:12 +0000 [thread overview]
Message-ID: <178887151271.219967.11606732852756839857@kernel.org> (raw)
In-Reply-To: <20260902214030.20955-5-arouhi@sitime.com>
Thank you for your contribution! Sashiko AI review found 6 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 · Low: 5
- [Medium] sit9531x_pin_props_get() fabricates the pin's advertised
frequency capability set instead of deriving it from firmware: after…
- [Low] Concern (largely INVALID at the end of the series): the per-pin
'hardware state' (sitdev->ref[].freq / sitdev->out[].freq and the…
- [Low] sit9531x_pin_props_get() accepts two 'connection-type' spellings
that the device-tree binding forbids: it compares the property against…
- [Low] Concern (verified as practically unreachable): supported-
frequencies-hz is a 64-bit DT property and dpll_pin_frequency.min/max…
- [Low] The XO (crystal) input pin has two conflicting sources of truth
for its frequency.
- [Low] sit9531x_pin_props_get() ignores the return value of
fwnode_property_read_u64_array() for "supported-frequencies-hz": it…
--
dpll: sit9531x: read DPLL types and pin properties from system firmware
This patch adds drivers/dpll/sit9531x/prop.c, which builds the per-pin
dpll_pin_properties (package label, type, capabilities, supported
frequency list) and the per-channel dpll_type from the firmware node,
falling back to defaults when the node does not describe them. A few
questions below about the frequency list and the connection-type parsing.
> diff --git a/drivers/dpll/sit9531x/prop.c b/drivers/dpll/sit9531x/prop.c
> new file mode 100644
> index 000000000000..94f3da716297
> --- /dev/null
> +++ b/drivers/dpll/sit9531x/prop.c
> @@ -0,0 +1,406 @@
[ ... ]
> + } else if (dir == DPLL_PIN_DIRECTION_INPUT &&
> + index == SIT9531X_MAX_INPUTS) {
> + /* The XO reference is fixed: no state or priority control. */
> + props->dpll_props.type = DPLL_PIN_TYPE_INT_OSCILLATOR;
> + props->dpll_props.capabilities = 0;
> + sitdev->ref[index].freq = sitdev->xtal_freq;
> + curr_freq = sitdev->xtal_freq;
[Severity: Low]
Does the XO pin end up with two sources of truth for its frequency here?
The branch seeds sitdev->ref[SIT9531X_MAX_INPUTS].freq from
sitdev->xtal_freq (the clk_get_rate() value read at probe), but unlike the
two INTSYNC pins the XO index is not excluded from the firmware-node path
further down in sit9531x_pin_props_get().
dpll-device.yaml allows an input-pins child for this index:
patternProperties:
"^pin@[0-9a-f]+$":
$ref: /schemas/dpll/dpll-pin.yaml
so a schema-valid DT can supply supported-frequencies-hz for pin 8, and the
seeding block later overwrites ref[8].freq (and curr_freq) with freqs[0].
>From then on sit9531x_dpll_input_pin_frequency_get() reports one crystal
rate to userspace while all the divider and VCO math keeps using
sitdev->xtal_freq.
Would it be simpler to skip the frequency-seeding path for index
SIT9531X_MAX_INPUTS the same way both INTSYNC pins already are?
[ ... ]
> + /* Look for "connection-type" property -> pin type enum */
> + if (!fwnode_property_read_string(props->fwnode, "connection-type",
> + &type)) {
> + if (!strcmp(type, "ext"))
> + props->dpll_props.type = DPLL_PIN_TYPE_EXT;
> + else if (!strcmp(type, "gnss"))
> + props->dpll_props.type = DPLL_PIN_TYPE_GNSS;
> + else if (!strcmp(type, "int") ||
> + !strcmp(type, "int-oscillator"))
> + props->dpll_props.type = DPLL_PIN_TYPE_INT_OSCILLATOR;
> + else if (!strcmp(type, "synce") ||
> + !strcmp(type, "synce-eth-port"))
> + props->dpll_props.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
[Severity: Low]
Can the "int-oscillator" and "synce-eth-port" comparisons ever match?
Documentation/devicetree/bindings/dpll/dpll-pin.yaml restricts the property
to a closed set:
connection-type:
description: Connection type of the pin
$ref: /schemas/types.yaml#/definitions/string
enum: [ext, gnss, int, mux, synce]
and sitime,sit95316.yaml inherits that pin schema through dpll-device.yaml.
A DT using either alias fails dt_binding_check/dtbs_check, so those two
comparisons look like dead code for any schema-valid DT. Should they just
be dropped, or should the binding gain the aliases?
> + num_freqs = fwnode_property_count_u64(props->fwnode,
> + "supported-frequencies-hz");
> + if (num_freqs <= 0) {
> + num_freqs = 0;
> + goto skip_fwnode_props;
> + }
> +
> + freqs = kcalloc(num_freqs, sizeof(*freqs), GFP_KERNEL);
> + if (!freqs) {
> + rc = -ENOMEM;
> + goto err_alloc_freqs;
> + }
> +
> + fwnode_property_read_u64_array(props->fwnode,
> + "supported-frequencies-hz",
> + freqs, num_freqs);
[Severity: Low]
Should the return value of fwnode_property_read_u64_array() be checked
before freqs[] is consumed?
For device tree the element count and the array read parse the same
property length and cannot disagree. For an ACPI-described device (this
driver can still be instantiated through PRP0001, which matches on
of_match_table and takes properties from _DSD), acpi_data_prop_read()
returns the package element count without type-checking each element, while
acpi_copy_property_array_uint() fails with -EPROTO on the first
non-integer element.
Since the failure is discarded, the remaining kcalloc zeros are then used
as data: ref[index].freq / out[index].freq and curr_freq get freqs[0], and
every entry including the zeros is published as a supported range.
> + /*
> + * Seed the runtime ref->freq / out->freq with the first DT-listed
> + * supported frequency so the netlink frequency_get callback reports
> + * a sane initial value before any pin_set occurs. DT lists the
> + * physically-wired reference frequency for each input pin and the
> + * default output frequency for each output pin.
> + */
> + if (num_freqs > 0) {
> + if (dir == DPLL_PIN_DIRECTION_INPUT)
> + sitdev->ref[index].freq = (u32)freqs[0];
> + else
> + sitdev->out[index].freq = (u32)freqs[0];
> + curr_freq = (u32)freqs[0];
> + }
> +
> +skip_fwnode_props:
[ ... ]
> + /* Allocate frequency ranges list -- DT discrete entries + current
> + * freq + one catch-all wide range so the subsystem never pre-
> + * rejects a frequency_set call. The chip's real admissible set
> + * is bounded by VCO / divider math in sit9531x_output_freq_set().
> + */
> + ranges = kcalloc(num_freqs + 2, sizeof(*ranges), GFP_KERNEL);
> + if (!ranges) {
> + rc = -ENOMEM;
> + goto err_alloc_ranges;
> + }
> +
> + /* Current freq as first entry */
> + ranges[0] = (struct dpll_pin_frequency)DPLL_PIN_FREQUENCY(curr_freq);
> + j = 1;
[ ... ]
> + /* Always append a wide catch-all range */
> + ranges[j].min = 1;
> + ranges[j].max = 1000000000ULL; /* 1 GHz */
> + j++;
> +
> + props->dpll_props.freq_supported = ranges;
> + props->dpll_props.freq_supported_num = j;
[Severity: Medium]
Does the appended catch-all range make the firmware-declared frequency list
meaningless, and does it publish a capability set the driver cannot honour?
The core treats every advertised range as genuinely supported, both when
validating a set and when exporting the list to userspace:
drivers/dpll/dpll_netlink.c:dpll_pin_is_freq_supported() {
for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
if (freq >= pin->prop.freq_supported[fs].min &&
freq <= pin->prop.freq_supported[fs].max)
return true;
return false;
}
and it is the only generic pre-validation of a userspace request:
drivers/dpll/dpll_netlink.c:dpll_pin_freq_set() {
if (!dpll_pin_is_freq_supported(pin, freq)) {
NL_SET_ERR_MSG_ATTR(extack, a, "frequency is not supported by the device");
return -EINVAL;
}
With {1, 1000000000} counted in freq_supported_num for every non-INTSYNC
pin, the DT-listed entries never constrain anything, and the same range is
attached to the XO pin whose capabilities are deliberately 0 and to every
input pin, which has no .frequency_set at all.
The array is also copied into the pin by dpll_pin_prop_dup() and exported
through DPLL_A_PIN_FREQUENCY_SUPPORTED, so 1 Hz..1 GHz becomes what
userspace is told this device supports.
Separately, ranges[0] is always DPLL_PIN_FREQUENCY(curr_freq), and
curr_freq stays 0 for any pin with no firmware node or no
supported-frequencies-hz list (both permitted by dpll-device.yaml and
dpll-pin.yaml), so those pins advertise 0 Hz as a supported frequency.
The commit message says:
"which frequencies a board actually presents on a given input, and
whether an output's embedded sync is wired to be controllable, are
board facts -- so they come from the firmware node"
Is that consistent with the catch-all range, which overrides the board
facts for every pin?
For reference, Documentation/devicetree/bindings/dpll/dpll-pin.yaml
describes the property as the pin's supported set:
supported-frequencies-hz:
description: List of supported frequencies for this pin, expressed in Hz.
Would it work to advertise only the firmware-listed entries (plus the
current frequency) and let sit9531x_output_freq_set() reject the rest with
-EINVAL, rather than widening the advertised set?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260902214030.20955-1-arouhi%40sitime.com
next prev parent reply other threads:[~2026-09-08 12:45 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 21:40 [PATCH net-next v8 00/15] dpll: add SiTime SiT9531x DPLL clock driver Ali Rouhi
2026-09-02 21:40 ` [PATCH net-next v8 01/15] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-09-02 21:40 ` [PATCH net-next v8 03/15] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 02/15] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 04/15] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko [this message]
2026-09-02 21:40 ` [PATCH net-next v8 05/15] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 07/15] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 06/15] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 08/15] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 09/15] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 11/15] dpll: sit9531x: add support to get and set esync on pins Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 10/15] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 13/15] dpll: sit9531x: add support to get fractional frequency offset Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 12/15] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 14/15] dpll: sit9531x: model the inter-PLL sync net as a pair of pins Ali Rouhi
2026-09-03 21:41 ` sashiko-bot
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-02 21:40 ` [PATCH net-next v8 15/15] dpll: sit9531x: allow the device tree to override two board facts Ali Rouhi
2026-09-08 12:45 ` netdev-bot+sashiko
2026-09-08 12:57 ` [PATCH net-next v8 00/15] dpll: add SiTime SiT9531x DPLL clock driver Paolo Abeni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178887151271.219967.11606732852756839857@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=Oleg.Zadorozhnyi@devoxsoftware.com \
--cc=arkadiusz.kubalewski@intel.com \
--cc=arouhi@sitime.com \
--cc=cjubran@nvidia.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=ivecera@redhat.com \
--cc=jiri@resnulli.us \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=robh@kernel.org \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.