Linux clock framework development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Christian Marangi" <ansuelsmth@gmail.com>, linux-clk@vger.kernel.org
Subject: Re: [PATCH v4 2/2] clk: en7523: add support for .set_rate for en7581
Date: Fri, 06 Nov 2026 11:45:13 +0000	[thread overview]
Message-ID: <sashiko-outbox-201354@kernel.org> (raw)
In-Reply-To: <20261106113227.182324-3-ansuelsmth@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] clk: en7523: division by zero in divider_get_val() when rate
  is 0
- [Low] clk: en7523: misuse of dev_err_probe() in runtime
  en7581_set_rate()
--

commit 21c9a3ba438d14108d5599a5785e71997f1e9fbe
Author: Christian Marangi <ansuelsmth@gmail.com>

clk: en7523: add support for .set_rate for en7581

This commit adds clock divisor tables and implements .determine_rate and
.set_rate callbacks for the Airoha EN7581 SoC clocks.

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

[ ... ]

> @@ -775,11 +864,148 @@ 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;
> +}
> +
> +/*
> + * Simulate rate with every divisor supported
> + * 1. Search the divisor for the requested rate
> + * 2. Simulate the final rate with the new divisor
> + */
> +static unsigned long en7581_get_div_for_rate(struct clk_hw *hw,
> +					     unsigned long rate,
> +					     unsigned long parent_rate,
> +					     const struct en_clk_desc *desc,
> +					     int *div_val)
> +{
> +	*div_val = divider_get_val(rate, parent_rate, desc->div_table,
> +				   desc->div_bits, desc->div_flags);
> +	if (*div_val < 0)
> +		return 0;
> +
> +	return divider_recalc_rate(hw, parent_rate, *div_val,
> +				   desc->div_table, desc->div_flags,
> +				   desc->div_bits);
> +}
> +
> +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);
> +	unsigned long parent_rate, tmp_rate;
> +	int tmp_base_val = 0;
> +	int tmp_div_val = 0;
> +
> +	if (!desc->base_bits && !desc->div_bits)
> +		return -EINVAL;

[Severity: Medium]
Can en7581_get_vals_for_rate() pass rate == 0 into
en7581_get_div_for_rate() -> divider_get_val()?

Calling clk_round_rate(clk, 0) or clk_set_rate(clk, 0) forwards
req->rate == 0 to en7581_determine_rate(), and divider_get_val() divides
by rate without checking for zero:

drivers/clk/clk-divider.c:divider_get_val() {
	unsigned int div, value;

	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
    ...
}

Rejecting !rate at the start of en7581_get_vals_for_rate() would avoid a
division by zero.

[ ... ]

> +static int en7581_set_rate(struct clk_hw *hw, unsigned long rate,
> +			   unsigned long parent_rate)
> +{
> +	struct en_clk *en_clk = container_of(hw, struct en_clk, hw);
> +	const struct en_clk_desc *desc = en_clk->desc;
> +	struct device *dev = clk_hw_get_dev(hw);
> +	struct regmap *map = en_clk->map;
> +	u32 base_val, div_val;
> +	u32 reg, val, mask;
> +	int err;
> +
> +	err = en7581_get_vals_for_rate(hw, en_clk->desc, rate,
> +				       &base_val, &div_val);
> +	if (err)
> +		return err;
> +
> +	if (desc->div_bits) {
> +		reg = desc->div_reg ? desc->div_reg : desc->base_reg;
> +
> +		mask = (BIT(desc->div_bits) - 1) << desc->div_shift;
> +		val = div_val << desc->div_shift;
> +
> +		err = regmap_update_bits(map, reg, mask, val);
> +		if (err)
> +			return dev_err_probe(dev, err, "Failed to update div reg for clock %s\n",
> +					     desc->name);
> +	}
> +
> +	if (desc->base_bits) {
> +		mask = (BIT(desc->base_bits) - 1) << desc->base_shift;
> +		val = base_val << desc->base_shift;
> +
> +		err = regmap_update_bits(map, desc->base_reg, mask, val);
> +		if (err)
> +			return dev_err_probe(dev, err, "Failed to update reg for clock %s\n",
> +					     desc->name);
> +	}

[Severity: Low]
Should en7581_set_rate() use dev_err() instead of dev_err_probe() here?
en7581_set_rate() is a runtime clk_ops callback rather than a probe
function, and the sibling helpers en7581_recalc_rate() and
en7581_get_vals_for_rate() already use dev_err().

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

  reply	other threads:[~2026-11-06 11:45 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06 11:32 [PATCH v4 0/2] clk: en7523: full clk_hw + set_rate for en7581 Christian Marangi
2026-11-06 11:32 ` [PATCH v4 1/2] clk: en7523: convert to full clk_hw implementation " Christian Marangi
2026-11-06 11:32 ` [PATCH v4 2/2] clk: en7523: add support for .set_rate " Christian Marangi
2026-11-06 11:45   ` sashiko-bot [this message]
2026-11-06 12:03     ` Christian Marangi

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-201354@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox