All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jisheng Zhang" <jszhang@kernel.org>
Cc: devicetree@vger.kernel.org, linux-clk@vger.kernel.org,
	linux-gpio@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v2 09/13] clk: berlin: add Synaptics clock controller helpers
Date: Sun, 15 Nov 2026 11:05:28 +0000	[thread overview]
Message-ID: <sashiko-outbox-215437@kernel.org> (raw)
In-Reply-To: <20261115102401.3520-10-jszhang@kernel.org>

Thank you for your contribution! Sashiko AI review found 5 potential
issues to consider:
- [High] clk: berlin: non-irqsave spinlock in sl_sysmgr_gateclk_ops
- [Medium] clk: berlin: uninitialized clk_init_data in sl-sysmgr-clk.c
- [Medium] clk: berlin: sl_sysmgr_clk_setup() ignores descriptor flags
- [Medium] clk: berlin: missing .disable callbacks and duplicated gate
  clock in sl-sysmgr-clk
- [Low] clk: berlin: non-self-contained header sl-sysmgr-clk.h and
  unused macros
--

commit a40ea8003017371f6f9b098c53eae5c758e872e4
Author: Jisheng Zhang <jszhang@kernel.org>

clk: berlin: add Synaptics clock controller helpers

This commit adds configurable divider and gate clock helpers for Synaptics
system controllers along with an MCU system manager clock setup helper.

> diff --git a/drivers/clk/berlin/sl-sysmgr-clk.c b/drivers/clk/berlin/sl-sysmgr-clk.c
> new file mode 100644
> index 0000000000000..f3cf921fc3c1a
> --- /dev/null
> +++ b/drivers/clk/berlin/sl-sysmgr-clk.c
> @@ -0,0 +1,241 @@

[ ... ]

> +#include <linux/platform_device.h>
> +#include <linux/version.h>
> +
> +#include "sl-sysmgr-clk.h"
> +
> +#define CLK_EN		BIT(0)
> +#define DIV_CHNG_EN	BIT(1)

[ ... ]

> +static int sl_sysmgr_gateclk_enable(struct clk_hw *hw)
> +{
> +	u32 val;
> +	struct sl_sysmgr_gateclk *clk = to_sl_sysmgr_gateclk(hw);
> +
> +	guard(spinlock)(&sl_sysmgr_gateclk_lock);
> +
> +	val = readl_relaxed(clk->base);
> +	if (!(val & BIT(clk->bit_idx))) {
> +		val |= BIT(clk->bit_idx);
> +		writel_relaxed(val, clk->base);
> +	}
> +
> +	return 0;
> +}
> +
> +static int sl_sysmgr_gateclk_is_enabled(struct clk_hw *hw)
> +{
> +	u32 val;
> +	struct sl_sysmgr_gateclk *clk = to_sl_sysmgr_gateclk(hw);
> +
> +	guard(spinlock)(&sl_sysmgr_gateclk_lock);
> +
> +	val = readl_relaxed(clk->base);
> +	val &= BIT(clk->bit_idx);
> +
> +	return val ? 1 : 0;
> +}

[Severity: High]
Can taking sl_sysmgr_gateclk_lock with guard(spinlock) instead of
spinlock_irqsave deadlock?

clk_core_is_enabled() calls .is_enabled from process context without
holding enable_lock and with local interrupts enabled (for example via
clk_summary_show_one() or __clk_is_enabled()), while clk_enable() can be
called from hardirq context:

clk_summary_show_one()
  ...
    sl_sysmgr_gateclk_is_enabled()
      spin_lock(&sl_sysmgr_gateclk_lock)
      <hardirq>
        clk_enable()
          ...
            sl_sysmgr_gateclk_enable()
              spin_lock(&sl_sysmgr_gateclk_lock)  <-- spins forever

sl_sysmgr_gateclk_enable() needs guard(spinlock_irqsave), while
sl_sysmgr_gateclk_is_enabled() only performs a single readl_relaxed() and
does not need the lock.

> +static const struct clk_ops sl_sysmgr_gateclk_ops = {
> +	.enable		= sl_sysmgr_gateclk_enable,
> +	.is_enabled	= sl_sysmgr_gateclk_is_enabled,
> +};
> +
> +static int
> +sl_sysmgr_gateclk_register(struct device *dev, struct sl_sysmgr_gateclk *gclk,
> +			   const char *name, const char *parent_names,
> +			   u8 bit_idx, void __iomem *base)
> +{
> +	struct clk_init_data init;
> +
> +	init.name = name;
> +	init.ops = &sl_sysmgr_gateclk_ops;
> +	init.parent_names = &parent_names;
> +	init.num_parents = 1;
> +	init.flags = 0;

[ ... ]

> +static const struct clk_ops sl_sysmgr_clk_ops = {
> +	.recalc_rate	= sl_sysmgr_clk_recalc_rate,
> +	.enable		= sl_sysmgr_clk_enable,
> +	.is_enabled	= sl_sysmgr_clk_is_enabled,
> +};

[Severity: Medium]
Should sl_sysmgr_gateclk_ops and sl_sysmgr_clk_ops implement .disable
callbacks?

Without .disable, consumer calls to clk_disable() and late boot's
clk_disable_unused() cannot gate these clocks in hardware, and
clk_is_enabled_when_prepared() treats them as enabled by .prepare even
though .prepare is not implemented.  In addition, struct sl_sysmgr_gateclk
and struct sl_sysmgr_gateclk_desc duplicate devm_clk_hw_register_gate()
and struct sl_gateclk_desc in drivers/clk/berlin/sl-clk.h.

> +static int
> +sl_sysmgr_clk_register(struct device *dev, struct sl_sysmgr_clk *sclk,
> +		       const char *name, const char *parent_names,
> +		       u8 div_bits, void __iomem *base)
> +{
> +	struct clk_init_data init;
> +
> +	init.name = name;
> +	init.ops = &sl_sysmgr_clk_ops;
> +	init.parent_names = &parent_names;
> +	init.num_parents = 1;
> +	init.flags = 0;

[Severity: Medium]
Does leaving struct clk_init_data init uninitialized on the stack in
sl_sysmgr_gateclk_register() and sl_sysmgr_clk_register() pass garbage
init.parent_data and init.parent_hws pointers into devm_clk_hw_register()?

clk_core_populate_parent_map() reads init->parent_hws and
init->parent_data unconditionally when registering the clock.

[ ... ]

> +	for (i = 0; i < gclk_n; i++) {
> +		ret = sl_sysmgr_gateclk_register(&pdev->dev, &priv->gclks[i],
> +						 gdescs[i].name, gdescs[i].parent_name,
> +						 gdescs[i].bit_idx, base + gclk_offset);
> +		if (ret)
> +			return ret;
> +
> +		id = gdescs[i].id;
> +		clk_data->hws[id] = &priv->gclks[i].hw;
> +	}
> +
> +	for (i = 0; i < clk_n; i++) {
> +		ret = sl_sysmgr_clk_register(&pdev->dev, &priv->clks[i],
> +					     descs[i].name, descs[i].parent_name,
> +					     descs[i].div_bits, base + descs[i].offset);
> +		if (ret)
> +			return ret;

[Severity: Medium]
Does sl_sysmgr_clk_setup() drop the flags field from gdescs[i] and
descs[i]?

struct sl_sysmgr_gateclk_desc and struct sl_sysmgr_clk_desc both define an
unsigned long flags member, but sl_sysmgr_clk_setup() never passes them to
sl_sysmgr_gateclk_register() or sl_sysmgr_clk_register(), which hardcode
init.flags = 0 and ignore flags such as CLK_IS_CRITICAL or
CLK_IGNORE_UNUSED.

[ ... ]

> diff --git a/drivers/clk/berlin/sl-sysmgr-clk.h b/drivers/clk/berlin/sl-sysmgr-clk.h
> new file mode 100644
> index 0000000000000..5ccf388bcccbd
> --- /dev/null
> +++ b/drivers/clk/berlin/sl-sysmgr-clk.h
> @@ -0,0 +1,44 @@

[ ... ]

> +#ifndef __SL_SYSMGR_CLK_H
> +#define __SL_SYSMGR_CLK_H
> +
> +struct sl_sysmgr_clk_desc {
> +	const char	*name;
> +	const char	*parent_name;
> +	u32		id;
> +	u32		offset;
> +	u8		div_bits;
> +	unsigned long	flags;
> +};

[ ... ]

> +int sl_sysmgr_clk_setup(struct platform_device *pdev,
> +			const struct sl_sysmgr_fixedclk_desc *fdescs,
> +			int fclk_n,
> +			const struct sl_sysmgr_gateclk_desc *gdescs,
> +			int gclk_n,
> +			u32 gclk_offset,
> +			const struct sl_sysmgr_clk_desc *descs,
> +			int clk_n);
> +
> +#endif

[Severity: Low]
Does sl-sysmgr-clk.h need #include <linux/types.h> and a forward
declaration of struct platform_device so it is self-contained when
included before other headers?  Also, <linux/version.h> and DIV_CHNG_EN in
sl-sysmgr-clk.c are unused, and sl-clk.h uses u32 and u8 without directly
including <linux/types.h>.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261115102401.3520-1-jszhang@kernel.org?part=9

  reply	other threads:[~2026-11-15 11:05 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-15 10:23 [PATCH v2 00/13] arm64: add Synaptics SL2610 SoCs and RDK boards Jisheng Zhang
2026-11-15 10:23 ` [PATCH v2 01/13] arm64: kconfig: let ARCH_BERLIN cover Synaptics arm64 SoCs Jisheng Zhang
2026-11-15 10:23 ` [PATCH v2 02/13] pinctrl: berlin: use u16 instead of u8 for the offset Jisheng Zhang
2026-11-15 10:23 ` [PATCH v2 03/13] pinctrl: berlin: enable module build support Jisheng Zhang
2026-11-15 10:58   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 04/13] pinctrl: berlin: add optional pinconf support Jisheng Zhang
2026-11-15 11:01   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 05/13] dt-bindings: soc: synaptics: add SL2610 system controllers Jisheng Zhang
2026-11-15 10:58   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 06/13] soc: synaptics: add SL2610 system controller support Jisheng Zhang
2026-11-15 10:56   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 07/13] reset: add Synaptics SL2610 reset " Jisheng Zhang
2026-11-15 11:12   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 08/13] pinctrl: berlin: add Synaptics SL2610 pin " Jisheng Zhang
2026-11-15 10:57   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 09/13] clk: berlin: add Synaptics clock controller helpers Jisheng Zhang
2026-11-15 11:05   ` sashiko-bot [this message]
2026-11-15 10:23 ` [PATCH v2 10/13] clk: berlin: add Synaptics SL2610 clocks and PLLs Jisheng Zhang
2026-11-15 11:04   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 11/13] dt-bindings: arm: berlin: add Synaptics SL2610 SoCs and RDK boards Jisheng Zhang
2026-11-15 10:23 ` [PATCH v2 12/13] arm64: dts: synaptics: add SL2610 family SoCs Jisheng Zhang
2026-11-15 11:13   ` sashiko-bot
2026-11-15 10:23 ` [PATCH v2 13/13] arm64: dts: synaptics: add SL2610 family RDK boards Jisheng Zhang
2026-11-15 11:05   ` sashiko-bot

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=sashiko-outbox-215437@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jszhang@kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.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.