* [PATCH 1/1] clk: introduce of_clk_detect_critical helper @ 2025-08-12 16:29 Maxim Kochetkov 2025-08-12 16:41 ` Christian Marangi 0 siblings, 1 reply; 5+ messages in thread From: Maxim Kochetkov @ 2025-08-12 16:29 UTC (permalink / raw) To: u-boot Cc: quentin.schulz, jonas, ansuelsmth, marex, semen.protsenko, miquel.raynal, patrice.chotard, patrick.delaunay, sjg, trini, seanga2, lukma, Maxim Kochetkov This helper find clock-critiacl property in dts and assign CLK_IS_CRITICAL flag to the clock. Signed-off-by: Maxim Kochetkov <fido_max@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 -- 2.50.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] clk: introduce of_clk_detect_critical helper 2025-08-12 16:29 [PATCH 1/1] clk: introduce of_clk_detect_critical helper Maxim Kochetkov @ 2025-08-12 16:41 ` Christian Marangi 2025-08-12 18:56 ` Maxim Kochetkov 0 siblings, 1 reply; 5+ messages in thread From: Christian Marangi @ 2025-08-12 16:41 UTC (permalink / raw) To: Maxim Kochetkov Cc: u-boot, quentin.schulz, jonas, marex, semen.protsenko, miquel.raynal, patrice.chotard, patrick.delaunay, sjg, trini, seanga2, lukma 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@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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] clk: introduce of_clk_detect_critical helper 2025-08-12 16:41 ` Christian Marangi @ 2025-08-12 18:56 ` Maxim Kochetkov 2025-08-19 7:41 ` Quentin Schulz 0 siblings, 1 reply; 5+ messages in thread From: Maxim Kochetkov @ 2025-08-12 18:56 UTC (permalink / raw) To: Christian Marangi Cc: u-boot, quentin.schulz, jonas, marex, semen.protsenko, miquel.raynal, patrice.chotard, patrick.delaunay, sjg, trini, seanga2, lukma 12.08.2025 19:41, Christian Marangi wrote: > 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 Thanks. Will fix it in v2 > >> CLK_IS_CRITICAL flag to the clock. >> >> Signed-off-by: Maxim Kochetkov <fido_max@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? Ok, I will split it. Yes these function 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? > Yes. Now we can use this property from DT by custom drivers to mark critical clocks. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] clk: introduce of_clk_detect_critical helper 2025-08-12 18:56 ` Maxim Kochetkov @ 2025-08-19 7:41 ` Quentin Schulz 2025-08-27 17:08 ` Patrick DELAUNAY 0 siblings, 1 reply; 5+ messages in thread From: Quentin Schulz @ 2025-08-19 7:41 UTC (permalink / raw) To: Maxim Kochetkov, Christian Marangi Cc: u-boot, jonas, marex, semen.protsenko, miquel.raynal, patrice.chotard, patrick.delaunay, sjg, trini, seanga2, lukma Hi Maxim, On 8/12/25 8:56 PM, Maxim Kochetkov wrote: > [You don't often get email from fido_max@inbox.ru. Learn why this is > important at https://aka.ms/LearnAboutSenderIdentification ] > > 12.08.2025 19:41, Christian Marangi wrote: >> 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 > > > Thanks. Will fix it in v2 > >> >>> CLK_IS_CRITICAL flag to the clock. >>> >>> Signed-off-by: Maxim Kochetkov <fido_max@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? > > Ok, I will split it. > Yes these function 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? >> > > Yes. Now we can use this property from DT by custom drivers to mark > critical clocks. > How this is typically handled today is by hardcoding the clock that is critical in the SoC clock controller driver directly, c.f. https://lore.kernel.org/linux-rockchip/20241214224820.200665-1-heiko@sntech.de/ This is of course then forced-enabled for all boards based on this SoC. If that is something that isn't desirable, then we need to properly need to represent this clock in the Device Tree. You haven't really explained the real life example that would benefit from this. Is there one? What is it? Finally, we do not accept Device Tree properties anymore if they aren't part of the Device Tree binding coming from the kernel, the Device Tree specification or the dt-schema. So it needs to go through those channels first before we can make use of this property here in U-Boot. Our ultimate goal is to have the exact same Device Tree for U-Boot than in the Linux kernel (and I assume even further than that, anything that requires DT use the same one across all SW stack). Cheers, Quentin ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] clk: introduce of_clk_detect_critical helper 2025-08-19 7:41 ` Quentin Schulz @ 2025-08-27 17:08 ` Patrick DELAUNAY 0 siblings, 0 replies; 5+ messages in thread From: Patrick DELAUNAY @ 2025-08-27 17:08 UTC (permalink / raw) To: Quentin Schulz, Maxim Kochetkov, Christian Marangi Cc: u-boot, jonas, marex, semen.protsenko, miquel.raynal, patrice.chotard, sjg, trini, seanga2, lukma Hi, On 8/19/25 09:41, Quentin Schulz wrote: > Hi Maxim, > > On 8/12/25 8:56 PM, Maxim Kochetkov wrote: >> [You don't often get email from fido_max@inbox.ru. Learn why this is >> important at https://aka.ms/LearnAboutSenderIdentification ] >> >> 12.08.2025 19:41, Christian Marangi wrote: >>> 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 >> >> >> Thanks. Will fix it in v2 >> >>> >>>> CLK_IS_CRITICAL flag to the clock. >>>> >>>> Signed-off-by: Maxim Kochetkov <fido_max@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? >> >> Ok, I will split it. >> Yes these function 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? >>> >> >> Yes. Now we can use this property from DT by custom drivers to mark >> critical clocks. >> > > How this is typically handled today is by hardcoding the clock that is > critical in the SoC clock controller driver directly, c.f. > https://lore.kernel.org/linux-rockchip/20241214224820.200665-1-heiko@sntech.de/ > > > This is of course then forced-enabled for all boards based on this > SoC. If that is something that isn't desirable, then we need to > properly need to represent this clock in the Device Tree. You haven't > really explained the real life example that would benefit from this. > Is there one? What is it? > > Finally, we do not accept Device Tree properties anymore if they > aren't part of the Device Tree binding coming from the kernel, the > Device Tree specification or the dt-schema. So it needs to go through > those channels first before we can make use of this property here in > U-Boot. Our ultimate goal is to have the exact same Device Tree for > U-Boot than in the Linux kernel (and I assume even further than that, > anything that requires DT use the same one across all SW stack). > > Cheers, > Quentin See Linux commit d56f8994b6fb it is a legacy feature for Linux side, not part of generic clock binding and no used in Linux's device tree ----------------------------------------------------------- Author: Lee Jones <lee@kernel.org> Date: Thu Feb 11 13:19:11 2016 -0800 clk: Provide OF helper to mark clocks as CRITICAL This call matches clocks which have been marked as critical in DT and sets the appropriate flag. These flags can then be used to mark the clock core flags appropriately prior to registration. Legacy bindings requiring this feature must add the clock-critical property to their binding descriptions, as it is not a part of common-clock binding. Cc: devicetree@vger.kernel.org Signed-off-by: Lee Jones <lee.jones@linaro.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Michael Turquette <mturquette@baylibre.com> Link: lkml.kernel.org/r/1455225554-13267-4-git-send-email-mturquette@baylibre.com Regards. --------------------------------------------------------- => custom drivers never mark a clock critical ... is a is a clock driver decision (common for all board, for mandatory clock in SoC, root clock or CPU clock for example = no need to be cutomized in DT for each board) for information: with CLK_CCF, this custom driver (device or board) can enable a clock found in the device tree, and its user counter become >1 (@enable_count), the clock is always enable for your use case (if enable/disabled are correctly paired in other drivers and with activate CCF) .... and you have no need to set it critical at SoC / Clock driver level Regards Patrick ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-08-27 17:10 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-12 16:29 [PATCH 1/1] clk: introduce of_clk_detect_critical helper Maxim Kochetkov 2025-08-12 16:41 ` Christian Marangi 2025-08-12 18:56 ` Maxim Kochetkov 2025-08-19 7:41 ` Quentin Schulz 2025-08-27 17:08 ` Patrick DELAUNAY
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.