Devicetree
 help / color / mirror / Atom feed
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,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org,
	prabhakar.mahadev-lad.rj@bp.renesas.com, cjubran@nvidia.com,
	Oleg.Zadorozhnyi@devoxsoftware.com, devicetree@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v14 03/12] dpll: add basic SiTime SiT9531x support
Date: Tue, 20 Oct 2026 03:09:40 +0000	[thread overview]
Message-ID: <179246578013.3135.1593003347944416304@kernel.org> (raw)
In-Reply-To: <20261016005823.13690-4-arouhi@sitime.com>

Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 2 · Low: 1

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] The binding
  (Documentation/devicetree/bindings/dpll/sitime,sit95316.yaml)…
- [Medium] The page-selector cache recovery does not cover every case.
- [Low] In sit9531x_dev_probe(), the XIN/XO reference is enabled with
  devm_clk_get_optional_enabled() (line 227) before the reset GPIO is…

--

dpll: add basic SiTime SiT9531x support

This adds an I2C driver for the SiTime SiT9531x clock generator. It has a
paged regmap configuration and page:offset register accessors. Probe reads
the XO rate, releases the optional reset line and identifies the variant
from page 0 offset 0x02.

> diff --git a/drivers/dpll/sit9531x/core.c b/drivers/dpll/sit9531x/core.c
> new file mode 100644
> index 0000000000000..20ccf024077bc
> --- /dev/null
> +++ b/drivers/dpll/sit9531x/core.c
> @@ -0,0 +1,320 @@

[ ... ]

> +/*
> + * Everything the device holds can change without the driver writing it,
> + * so nothing here is cacheable except the page selector.  Caching that
> + * one spares a read of it before every access: the range code selects
> + * the page through a read-modify-write, and with no cache that read goes
> + * to the bus each time.
> + *
> + * The cached value is only as good as the last transfer, though.  A
> + * transfer that fails can leave the part on another page than the cache
> + * records, so every accessor drops the entry on an error and the next
> + * access reads the selector again.
> + */
> +static bool sit9531x_volatile_reg(struct device *dev __maybe_unused,
> +				  unsigned int reg)
> +{
> +	return reg != SIT9531X_PAGE_SEL;
> +}

[ ... ]

> +static void sit9531x_page_cache_drop(struct sit9531x_dev *sitdev)
> +{
> +	regcache_drop_region(sitdev->regmap, SIT9531X_PAGE_SEL,
> +			     SIT9531X_PAGE_SEL);
> +}

[ ... ]

> +int sit9531x_read_u8(struct sit9531x_dev *sitdev, unsigned int reg,
> +		     u8 *val)
> +{

[ ... ]

> +	rc = regmap_read(sitdev->regmap, vreg, &tmp);
> +	if (rc) {
> +		sit9531x_page_cache_drop(sitdev);

[Severity: Medium]
Does this recovery still work when something other than these accessors
uses the map?

The selector is the only cached register, so _regmap_select_page() skips
the selector write when the cached page already matches. _regmap_write()
also updates the cache before the bus write and does not roll it back on
failure:

drivers/base/regmap/regmap.c:_regmap_write() {
    ...
	if (!map->cache_bypass && !map->defer_caching) {
		ret = regcache_write(map, reg, val);
    ...
	ret = map->reg_write(context, reg, val);
    ...
}

So a failed selector write leaves the cache at page P while the chip
stays on page Q.

sit9531x_page_cache_drop() only runs after regmap_read() has released
map->lock, and regcache_drop_region() then takes the lock again. Could
another map user take map->lock in that window, trust the stale page P,
and access page Q?

Map users that bypass sit9531x_read_u8(), sit9531x_write_u8() and
sit9531x_update_pll_u8() never drop the entry. For example,
regmap_read_debugfs() calls regmap_read() directly and only prints 'X'
on error:

drivers/base/regmap/regmap-debugfs.c:regmap_read_debugfs() {
    ...
			ret = regmap_read(map, i, &val);
			if (ret == 0)
				snprintf(buf + buf_pos, count - buf_pos,
					 "%.*x", map->debugfs_val_len, val);
			else
				memset(buf + buf_pos, 'X',
				       map->debugfs_val_len);
    ...
}

Suppose a selector write fails while the debugfs registers file is being
dumped, and the dump stops before the next page switch. Would the
driver's next access to page P then skip the selector write and silently
read or write the same offset on page Q?

The comment above sit9531x_volatile_reg() says "every accessor drops the
entry on an error". That seems to hold only while the driver's accessors
are the only users of the map.

[ ... ]

> +static int sit9531x_dev_probe(struct sit9531x_dev *sitdev)
> +{

[ ... ]

> +	xtal_clk = devm_clk_get_optional_enabled(sitdev->dev, "xtal");
> +	if (IS_ERR(xtal_clk))
> +		return dev_err_probe(sitdev->dev, PTR_ERR(xtal_clk),
> +				     "Failed to get xtal clock\n");

[Severity: Low]
The XO is enabled here, before the steps that can defer or fail. These
include devm_gpiod_get_optional() for the reset line, which returns
-EPROBE_DEFER if RESETB sits on a GPIO expander that has not probed yet,
and the variant ID read and match.

On those paths devres calls clk_disable_unprepare() on the xtal clock.
If the XO is a gateable clock that the bootloader left running, with a
CCF enable_count of 0 before probe, does this gate the reference of a
chip that is already running from efuse or a pre-probe blob?

The PLLs would then lose lock, and the outputs would glitch or stop on
every deferral cycle until probe succeeds.

Could the resources that can defer be looked up before the clock is
enabled and reset is deasserted? For example, the reset GPIO could be
requested with GPIOD_ASIS.

[ ... ]

> +	sitdev->reset_gpio = devm_gpiod_get_optional(sitdev->dev, "reset",
> +						     GPIOD_OUT_LOW);
> +	if (IS_ERR(sitdev->reset_gpio))
> +		return dev_err_probe(sitdev->dev, PTR_ERR(sitdev->reset_gpio),
> +				     "Failed to request reset gpio\n");
> +	if (sitdev->reset_gpio)
> +		fsleep(10000);	/* internal boot after release */
> +
> +	rc = sit9531x_read_variant_id(sitdev, &variant_id);
> +	if (rc)
> +		return rc;

[Severity: Medium]
The binding in sitime,sit95316.yaml documents vdd-supply, vddin-supply,
vdds-supply and the vddo*-supply rails, and its example wires several of
them. The driver never gets or enables any regulator, and that is still
true at the end of the series.

If one of these rails is a switchable regulator that is off at boot,
sit9531x_dev_probe() releases reset and reads the variant ID over I2C
from an unpowered part. Wouldn't probe then fail?

A rail might instead be left on by the bootloader or regulator-boot-on,
without being always-on and with no other consumer. Nothing holds a
reference to it, so regulator_late_cleanup() would switch it off:

drivers/regulator/core.c:regulator_late_cleanup() {
    ...
	if (rdev->use_count)
		goto unlock;
    ...
		ret = _regulator_do_disable(rdev);
    ...
}

Would that cut power to the running clock generator? It would lose the
efuse or pre-probe configuration that the driver avoids resetting for,
and downstream consumers would lose their reference clocks.

Should probe get and enable the documented supplies before releasing
reset?

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261016005823.13690-1-arouhi%40sitime.com

  reply	other threads:[~2026-10-20  3:09 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16  0:58 [PATCH net-next v14 00/12] dpll: add SiTime SiT9531x DPLL clock driver Ali Rouhi
2026-10-16  0:58 ` [PATCH net-next v14 01/12] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-10-16  0:58 ` [PATCH net-next v14 03/12] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko [this message]
2026-10-16  0:58 ` [PATCH net-next v14 02/12] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-10-16 13:53   ` Rob Herring (Arm)
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 04/12] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 06/12] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 05/12] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 07/12] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 08/12] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-10-17  1:00   ` sashiko-bot
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 09/12] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 10/12] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-10-17  1:00   ` sashiko-bot
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 11/12] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko
2026-10-16  0:58 ` [PATCH net-next v14 12/12] dpll: sit9531x: model the inter-PLL sync net as a pair of pins Ali Rouhi
2026-10-20  3:09   ` netdev-bot+sashiko

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=179246578013.3135.1593003347944416304@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=pabeni@redhat.com \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox