[PATCH 1/1] clk: introduce of_clk_detect_critical helper
Christian Marangi
ansuelsmth at gmail.com
Tue Aug 12 18:41:27 CEST 2025
On Tue, Aug 12, 2025 at 07:29:46PM +0300, Maxim Kochetkov wrote:
> This helper find clock-critiacl property in dts and assign
clock-critiacl -> typo
> CLK_IS_CRITICAL flag to the clock.
>
> Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
> ---
> drivers/clk/clk-uclass.c | 17 +++++++++++++++++
> drivers/core/of_access.c | 22 ++++++++++++++++++++++
> include/clk.h | 28 ++++++++++++++++++++++++++++
> include/dm/of_access.h | 17 +++++++++++++++++
> 4 files changed, 84 insertions(+)
>
> diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
> index 7262e89b512..4f35b90382f 100644
> --- a/drivers/clk/clk-uclass.c
> +++ b/drivers/clk/clk-uclass.c
> @@ -835,6 +835,23 @@ struct clk *devm_clk_get(struct udevice *dev, const char *id)
> return clk;
> }
>
> +int of_clk_detect_critical(struct device_node *np, int index,
> + unsigned long *flags)
> +{
> + struct property *prop;
> + const __be32 *cur;
> + uint32_t idx;
> +
> + if (!np || !flags)
> + return -EINVAL;
> +
> + of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
> + if (index == idx)
> + *flags |= CLK_IS_CRITICAL;
> +
> + return 0;
> +}
> +
> int clk_uclass_post_probe(struct udevice *dev)
> {
> /*
> diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
> index b11e36202c1..59dda3ae152 100644
> --- a/drivers/core/of_access.c
> +++ b/drivers/core/of_access.c
> @@ -666,6 +666,28 @@ int of_property_read_string_helper(const struct device_node *np,
> return i <= 0 ? -ENODATA : i;
> }
>
> +const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
> + u32 *pu)
> +{
> + const void *curv = cur;
> +
> + if (!prop)
> + return NULL;
> +
> + if (!cur) {
> + curv = prop->value;
> + goto out_val;
> + }
> +
> + curv += sizeof(*cur);
> + if (curv >= prop->value + prop->length)
> + return NULL;
> +
> +out_val:
> + *pu = be32_to_cpup(curv);
> + return curv;
> +}
> +
> static int __of_root_parse_phandle_with_args(struct device_node *root,
> const struct device_node *np,
> const char *list_name,
> diff --git a/include/clk.h b/include/clk.h
> index f94135ff778..ea708f54fd5 100644
> --- a/include/clk.h
> +++ b/include/clk.h
> @@ -589,6 +589,27 @@ bool clk_dev_binded(struct clk *clk);
> */
> ulong clk_get_id(const struct clk *clk);
>
> +/**
> + * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
> + * @np: Device node pointer associated with clock provider
> + * @index: clock index
> + * @flags: pointer to top-level framework flags
> + *
> + * Detects if the clock-critical property exists and, if so, sets the
> + * corresponding CLK_IS_CRITICAL flag.
> + *
> + * Do not use this function. It exists only for legacy Device Tree
> + * bindings, such as the one-clock-per-node style that are outdated.
> + * Those bindings typically put all clock data into .dts and the Linux
> + * driver has no clock data, thus making it impossible to set this flag
> + * correctly from the driver. Only those drivers may call
> + * of_clk_detect_critical from their setup functions.
> + *
> + * Return: error code or zero on success
> + */
> +int of_clk_detect_critical(struct device_node *np, int index,
> + unsigned long *flags);
> +
> #else /* CONFIG_IS_ENABLED(CLK) */
>
> static inline int clk_request(struct udevice *dev, struct clk *clk)
> @@ -665,6 +686,13 @@ static inline ulong clk_get_id(const struct clk *clk)
> {
> return 0;
> }
> +
> +int of_clk_detect_critical(struct device_node *np, int index,
> + unsigned long *flags)
> +{
> + return 0;
> +}
> +
> #endif /* CONFIG_IS_ENABLED(CLK) */
>
> /**
> diff --git a/include/dm/of_access.h b/include/dm/of_access.h
> index 44143a5a391..dba725498f5 100644
> --- a/include/dm/of_access.h
> +++ b/include/dm/of_access.h
> @@ -405,6 +405,17 @@ int of_property_read_string_helper(const struct device_node *np,
> const char *propname, const char **out_strs,
> size_t sz, int index);
>
> +/*
> + * struct property *prop;
> + * const __be32 *p;
> + * u32 u;
> + *
> + * of_property_for_each_u32(np, "propname", prop, p, u)
> + * printk("U32 value: %x\n", u);
> + */
> +const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
> + u32 *pu);
> +
> /**
> * of_property_read_string_index() - Find and read a string from a multiple
> * strings property.
> @@ -701,4 +712,10 @@ int of_remove_property(struct device_node *np, struct property *prop);
> */
> int of_remove_node(struct device_node *to_remove);
>
> +#define of_property_for_each_u32(np, propname, prop, p, u) \
> + for (prop = of_find_property(np, propname, NULL), \
> + p = of_prop_next_u32(prop, NULL, &u); \
> + p; \
> + p = of_prop_next_u32(prop, p, &u))
> +
> #endif
> --
I would split these of additional function to a separate commit also
where they come from? They are ported from Linux Kernel?
Also would be ideal to have some scenario where it's needed to declare a
clock in DT that is critical. Isn't that handled directly by the clock
driver internally?
--
Ansuel
More information about the U-Boot
mailing list