All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerome Brunet <jbrunet@baylibre.com>
To: Vyacheslav Yurkov via B4 Relay
	<devnull+V.Yurkov.EXT.bruker.com@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Brian Masney <bmasney@redhat.com>,
	Brian Masney <bmasney+clk@redhat.com>,
	Jerome Brunet <jbrunet+clk@baylibre.com>,
	Jyri Sarha <jsarha@ti.com>
Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	Vyacheslav Yurkov <uvv.mail@gmail.com>,
	Vyacheslav Yurkov <V.Yurkov.EXT@bruker.com>
Subject: Re: [PATCH v8 2/2] clk: Add gpio-locked clock driver
Date: Mon, 05 Oct 2026 16:27:18 +0200	[thread overview]
Message-ID: <1jcxto6x4p.fsf@starbuckisacylon.baylibre.com> (raw)
In-Reply-To: <20260927-feature-clock-guard-v8-2-630938e302a1@bruker.com>

On Sun 27 Sep 2026 at 14:59, Vyacheslav Yurkov via B4 Relay <devnull+V.Yurkov.EXT.bruker.com@kernel.org> wrote:

> From: Vyacheslav Yurkov <V.Yurkov.EXT@bruker.com>
>
> A gpio-locked clock exposes a clock, which status is determined by a
> GPIO signal. The common use-case is a FPGA-assisted clocking design
> where peripheral clocks are generated by FPGA PLLs that are outside
> CPU control, with clock-valid/PLL-lock status exposed through GPIO signals.
> Consumers can use the output clock to wait until the input clock is locked
> and only then initialize dependent peripherals.
>
> Signed-off-by: Vyacheslav Yurkov <V.Yurkov.EXT@bruker.com>
> ---
>  drivers/clk/clk-gpio.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
> index 9099c57e2715..db68b8bc44c5 100644
> --- a/drivers/clk/clk-gpio.c
> +++ b/drivers/clk/clk-gpio.c
> @@ -138,6 +138,25 @@ static const struct clk_ops clk_gpio_mux_ops = {
>  	.determine_rate = __clk_mux_determine_rate,
>  };
>  
> +/* We can't prepare the clock, but the Common Clock Framework calls only
> + * prepare() not is_prepared(), therefore we fallback on the actuall GPIO value.
> + * The function clk_sleeping_gpio_gate_is_prepared() returns the raw boolean
> + * GPIO status (1 if locked, 0 if unlocked), but the prepare callback
> + * clk_core_prepare() expects 0 for success and non-zero integer for failure.
> + */
> +static int clk_gpio_locked_prepare(struct clk_hw *hw)
> +{
> +	if (clk_sleeping_gpio_gate_is_prepared(hw))
> +		return 0;
> +
> +	return -EBUSY;
> +}

I was apparently not clear - probably my fault since I was initially
confused with what the driver was supposed to do.

Please do not modify the gate driver. Just provide gpio-enabled-clock
clock driver along the gate and mux in there.

> +
> +static const struct clk_ops clk_gpio_locked_ops = {
> +	.prepare =	clk_gpio_locked_prepare,
> +	.is_prepared =	clk_sleeping_gpio_gate_is_prepared,
> +};

Please implement the ops you've be testing, fast or slow (or both :D if
you can test both) 

> +
>  static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
>  					struct gpio_desc *gpiod,
>  					const struct clk_ops *clk_gpio_ops)
> @@ -146,6 +165,7 @@ static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
>  	struct clk_hw *hw;
>  	struct clk_init_data init = {};
>  	int err;
> +	const char *clk_name;
>  	const struct clk_parent_data gpio_parent_data[] = {
>  		{ .index = 0 },
>  		{ .index = 1 },
> @@ -155,7 +175,11 @@ static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
>  	if (!clk_gpio)
>  		return ERR_PTR(-ENOMEM);
>  
> -	init.name = dev->of_node->name;
> +	err = device_property_read_string(dev, "clock-output-names", &clk_name);
> +	if (err)
> +		clk_name = fwnode_get_name(dev->fwnode);
> +
> +	init.name = clk_name;
>  	init.ops = clk_gpio_ops;
>  	init.parent_data = gpio_parent_data;
>  	init.num_parents = num_parents;
> @@ -192,6 +216,12 @@ static struct clk_hw *clk_hw_register_gpio_mux(struct device *dev,
>  	return clk_register_gpio(dev, 2, gpiod, &clk_gpio_mux_ops);
>  }
>  
> +static struct clk_hw *clk_hw_register_gpio_locked(struct device *dev,
> +						  struct gpio_desc *gpiod)
> +{
> +	return clk_register_gpio(dev, 1, gpiod, &clk_gpio_locked_ops);
> +}
> +
>  static int gpio_clk_driver_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -201,8 +231,11 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
>  	struct gpio_desc *gpiod;
>  	struct clk_hw *hw;
>  	bool is_mux;
> +	bool is_gpio_locked;
> +	enum gpiod_flags gpio_flags;
>  
>  	is_mux = of_device_is_compatible(node, "gpio-mux-clock");
> +	is_gpio_locked = of_device_is_compatible(node, "gpio-locked-clock");
>  
>  	num_parents = of_clk_get_parent_count(node);
>  	if (is_mux && num_parents != 2) {
> @@ -210,14 +243,24 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> -	gpio_name = is_mux ? "select" : "enable";
> -	gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
> +	if (is_mux)
> +		gpio_name = "select";
> +	else if (is_gpio_locked)
> +		gpio_name = "enabled";
> +	else
> +		gpio_name = "enable";
> +
> +	gpio_flags = is_gpio_locked ? GPIOD_IN : GPIOD_OUT_LOW;
> +
> +	gpiod = devm_gpiod_get(dev, gpio_name, gpio_flags);
>  	if (IS_ERR(gpiod))
>  		return dev_err_probe(dev, PTR_ERR(gpiod),
>  				     "Can't get '%s' named GPIO property\n", gpio_name);
>  
>  	if (is_mux)
>  		hw = clk_hw_register_gpio_mux(dev, gpiod);
> +	else if (is_gpio_locked)
> +		hw = clk_hw_register_gpio_locked(dev, gpiod);
>  	else
>  		hw = clk_hw_register_gpio_gate(dev, num_parents, gpiod);
>  	if (IS_ERR(hw))
> @@ -229,6 +272,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
>  static const struct of_device_id gpio_clk_match_table[] = {
>  	{ .compatible = "gpio-mux-clock" },
>  	{ .compatible = "gpio-gate-clock" },
> +	{ .compatible = "gpio-locked-clock" },
>  	{ }
>  };
>  
>
> -- 
> 2.34.1
>
>

-- 
Jerome

      parent reply	other threads:[~2026-10-05 14:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-27 14:59 [PATCH v8 0/2] A proposal to add a gpio-locked clock driver Vyacheslav Yurkov
2026-09-27 14:59 ` Vyacheslav Yurkov via B4 Relay
2026-09-27 14:59 ` [PATCH v8 1/2] dt-bindings: clock: gpio-gate-clock: Add a new compatible string Vyacheslav Yurkov
2026-09-27 14:59   ` Vyacheslav Yurkov via B4 Relay
2026-09-27 15:08   ` sashiko-bot
2026-10-05 14:27   ` Jerome Brunet
2026-09-27 14:59 ` [PATCH v8 2/2] clk: Add gpio-locked clock driver Vyacheslav Yurkov
2026-09-27 14:59   ` Vyacheslav Yurkov via B4 Relay
2026-09-27 15:09   ` sashiko-bot
2026-10-05 14:27   ` Jerome Brunet [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=1jcxto6x4p.fsf@starbuckisacylon.baylibre.com \
    --to=jbrunet@baylibre.com \
    --cc=V.Yurkov.EXT@bruker.com \
    --cc=bmasney+clk@redhat.com \
    --cc=bmasney@redhat.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=devnull+V.Yurkov.EXT.bruker.com@kernel.org \
    --cc=jbrunet+clk@baylibre.com \
    --cc=jsarha@ti.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=uvv.mail@gmail.com \
    /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.