All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.