All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Christian Marangi" <ansuelsmth@gmail.com>, linux-clk@vger.kernel.org
Subject: Re: [PATCH v3 2/2] clk: en7523: add support for .set_rate for en7581
Date: Thu, 05 Nov 2026 15:15:20 +0000	[thread overview]
Message-ID: <sashiko-outbox-199304@kernel.org> (raw)
In-Reply-To: <20261105150207.23023-3-ansuelsmth@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] clk: en7523: broken SPI rate lookup in en7581_get_vals_for_rate()
- [High] clk: en7523: unchecked divider_get_val() error in en7581_get_vals_for_rate()
--

commit 9938b50fa7a98aecdd2b2c8ce0469da6eedd9312
Author: Christian Marangi <ansuelsmth@gmail.com>

clk: en7523: add support for .set_rate for en7581

This commit adds .determine_rate and .set_rate callbacks for the Airoha
EN7581 clock controller using standard clock divider helpers and divider
tables for the BUS, SPI, and SLIC clocks.

> diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
> index 6640e814d36a4..cf0b6ccacede9 100644
> --- a/drivers/clk/clk-en7523.c
> +++ b/drivers/clk/clk-en7523.c

[ ... ]

> @@ -338,6 +426,7 @@ static const struct en_clk_desc en7581_base_clks[] = {
>  		.div_shift = 8,
>  		.div_val0 = 40,
>  		.div_step = 2,
> +		.div_table = spi_div,
>  	}, {
>  		.id = EN7523_CLK_NPU,
>  		.name = "npu",
> @@ -775,11 +864,127 @@ static unsigned long en7581_recalc_rate(struct clk_hw *hw,
>  		return 0;
>  	}
>  
> -	return rate / en7523_get_div(desc, val);
> +	if (desc->div_bits) {
> +		val >>= desc->div_shift;
> +		val &= (1 << desc->div_bits) - 1;
> +
> +		rate = divider_recalc_rate(hw, rate, val,
> +					   desc->div_table,
> +					   desc->div_flags,
> +					   desc->div_bits);
> +	}
> +
> +	return rate;
> +}
> +
> +static int en7581_get_vals_for_rate(struct clk_hw *hw,
> +				    const struct en_clk_desc *desc,
> +				    unsigned long rate,
> +				    u32 *base_val, u32 *div_val)
> +{
> +	struct device *dev = clk_hw_get_dev(hw);
> +	int tmp_base_val = 0;
> +	int tmp_div_val = 0;
> +
> +	if (!desc->base_bits && !desc->div_bits)
> +		return -EINVAL;
> +
> +	/* Search requested rate with every matching base rate + divisor */
> +	for (; tmp_base_val < desc->n_base_values; tmp_base_val++) {
> +		unsigned long parent_rate = desc->base_values[tmp_base_val];
> +		unsigned long tmp_rate = parent_rate;

[Severity: High]
Does en7581_get_vals_for_rate() in drivers/clk/clk-en7523.c always fail with
-EINVAL when called for EN7523_CLK_SPI via en7581_determine_rate() or
en7581_set_rate()?

In en7581_base_clks, EN7523_CLK_SPI defines a fixed .base_value = 400000000
and leaves .base_bits and .n_base_values as 0:

	{
		.id = EN7523_CLK_SPI,
		.name = "spi",

		.base_reg = REG_SPI_CLK_DIV_SEL,

		.base_value = 400000000,

		.div_bits = 5,
		.div_shift = 8,
		.div_val0 = 40,
		.div_step = 2,
		.div_table = spi_div,
	},

When en7581_get_vals_for_rate() is called for EN7523_CLK_SPI,
desc->n_base_values is 0, so the for loop never executes and the check
tmp_base_val >= desc->n_base_values is immediately true, returning -EINVAL
for every SPI clock rate.

Should en7581_get_vals_for_rate() handle clocks where desc->base_bits is 0
by testing a single iteration with parent_rate = desc->base_value (similar
to how en7523_get_base_rate() handles !desc->base_bits)?

> +
> +		/*
> +		 * Simulate rate with every divisor supported
> +		 * 1. Search the divisor for the requested rate
> +		 * 2. Simulate the final rate with the new divisor
> +		 */
> +		if (desc->div_bits) {
> +			tmp_div_val = divider_get_val(rate, parent_rate,
> +						      desc->div_table,
> +						      desc->div_bits,
> +						      desc->div_flags);
> +			tmp_rate = divider_recalc_rate(hw, parent_rate,
> +						       tmp_div_val,
> +						       desc->div_table,
> +						       desc->div_flags,
> +						       desc->div_bits);
> +		}

[Severity: High]
What happens in en7581_get_vals_for_rate() in drivers/clk/clk-en7523.c when
divider_get_val() returns -EINVAL because DIV_ROUND_UP_ULL(parent_rate, rate)
is not in desc->div_table?

Because tmp_div_val is passed to divider_recalc_rate() without checking for
a negative error code, _get_div() looks up (unsigned int)-EINVAL in
desc->div_table, fails to find a match, and returns 0. Since
CLK_DIVIDER_ALLOW_ZERO is not set in desc->div_flags, divider_recalc_rate()
triggers a WARN() and returns parent_rate:

drivers/clk/clk-divider.c:divider_recalc_rate() {
	div = _get_div(table, val, flags, width);
	if (!div) {
		WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
			"%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
			clk_hw_get_name(hw));
		return parent_rate;
	}
}

This causes two problems on clocks using a clk_div_table (EN7523_CLK_BUS,
EN7523_CLK_SLIC, and EN7523_CLK_SPI):

First, evaluating a valid rate that is derived from a subsequent entry in
desc->base_values[] (such as 67.5 MHz on EN7523_CLK_BUS from 540 MHz / 8, or
a rate on EN7523_CLK_SLIC derived from slic_base[1] = 3.125 MHz) will fail
divider_get_val() on the first base rate and trigger a kernel WARN() before
moving on to the next base rate.

Second, if a caller requests a rate equal to parent_rate on a clock where
divisor 1 is not supported (for example, 600 MHz or 540 MHz on EN7523_CLK_BUS
where divisor 1 is n/a in bus_div, or 100 MHz or 3.125 MHz on
EN7523_CLK_SLIC), divider_recalc_rate() returns parent_rate, which matches
tmp_rate == rate. en7581_get_vals_for_rate() then succeeds with *div_val set
to (u32)-EINVAL, and en7581_set_rate() writes the low bits of -EINVAL into
the hardware divider register via regmap_update_bits().

Should en7581_get_vals_for_rate() check if (tmp_div_val < 0) and continue to
the next base rate before calling divider_recalc_rate()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261105150207.23023-1-ansuelsmth@gmail.com?part=2

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

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 15:02 [PATCH v3 0/2] clk: en7523: full clk_hw + set_rate for en7581 Christian Marangi
2026-11-05 15:02 ` [PATCH v3 1/2] clk: en7523: convert to full clk_hw implementation " Christian Marangi
2026-11-05 15:02 ` [PATCH v3 2/2] clk: en7523: add support for .set_rate " Christian Marangi
2026-11-05 15:15   ` sashiko-bot [this message]

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-199304@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=ansuelsmth@gmail.com \
    --cc=linux-clk@vger.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.