* [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 3:49 ` Trilok Soni
2025-05-02 5:37 ` Viresh Kumar
2025-05-02 3:10 ` [PATCH v3 2/9] dt-bindings: serial: describe SA8255p Praveen Talari
` (7 subsequent siblings)
8 siblings, 2 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
To configure a device to a specific performance level, consumer drivers
currently need to determine the OPP based on the exact level and then
set it, resulting in code duplication across drivers.
The new helper API, dev_pm_opp_set_level(), addresses this issue by
providing a streamlined method for consumer drivers to find and set the
OPP based on the desired performance level, thereby eliminating
redundancy.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v2 -> v3
- moved function defination to pm_opp.h from core.c with inline
- updated return value with IS_ERR(opp)
v1 -> v2
- reorder sequence of tags in commit text
---
include/linux/pm_opp.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index e7b5c602c92f..31ed8a7b554e 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -197,6 +197,28 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
void dev_pm_opp_remove_table(struct device *dev);
void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
int dev_pm_opp_sync_regulators(struct device *dev);
+
+/*
+ * dev_pm_opp_set_level() - Configure device for a level
+ * @dev: device for which we do this operation
+ * @level: level to set to
+ *
+ * Return: 0 on success, a non-zero value if there is an error otherwise.
+ */
+static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
+{
+ struct dev_pm_opp *opp = dev_pm_opp_find_level_exact(dev, level);
+ int ret;
+
+ if (IS_ERR(opp))
+ return IS_ERR(opp);
+
+ ret = dev_pm_opp_set_opp(dev, opp);
+ dev_pm_opp_put(opp);
+
+ return ret;
+}
+
#else
static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
{
@@ -461,6 +483,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
return -EOPNOTSUPP;
}
+static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
+{
+ return -EOPNOTSUPP;
+}
+
#endif /* CONFIG_PM_OPP */
#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 3:10 ` [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level() Praveen Talari
@ 2025-05-02 3:49 ` Trilok Soni
2025-05-02 5:37 ` Viresh Kumar
1 sibling, 0 replies; 27+ messages in thread
From: Trilok Soni @ 2025-05-02 3:49 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
On 5/1/2025 8:10 PM, Praveen Talari wrote:
> To configure a device to a specific performance level, consumer drivers
> currently need to determine the OPP based on the exact level and then
> set it, resulting in code duplication across drivers.
>
> The new helper API, dev_pm_opp_set_level(), addresses this issue by
> providing a streamlined method for consumer drivers to find and set the
> OPP based on the desired performance level, thereby eliminating
> redundancy.
>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v2 -> v3
> - moved function defination to pm_opp.h from core.c with inline
> - updated return value with IS_ERR(opp)
>
> v1 -> v2
> - reorder sequence of tags in commit text
The version log above will go into the commit text. Please keep it after
---.
> ---
> include/linux/pm_opp.h | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
> index e7b5c602c92f..31ed8a7b554e 100644
> --- a/include/linux/pm_opp.h
> +++ b/include/linux/pm_opp.h
> @@ -197,6 +197,28 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
> void dev_pm_opp_remove_table(struct device *dev);
> void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
> int dev_pm_opp_sync_regulators(struct device *dev);
> +
> +/*
> + * dev_pm_opp_set_level() - Configure device for a level
> + * @dev: device for which we do this operation
> + * @level: level to set to
> + *
> + * Return: 0 on success, a non-zero value if there is an error otherwise.
> + */
> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
> +{
> + struct dev_pm_opp *opp = dev_pm_opp_find_level_exact(dev, level);
> + int ret;
> +
> + if (IS_ERR(opp))
> + return IS_ERR(opp);
> +
> + ret = dev_pm_opp_set_opp(dev, opp);
> + dev_pm_opp_put(opp);
> +
> + return ret;
> +}
> +
> #else
> static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
> {
> @@ -461,6 +483,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
> return -EOPNOTSUPP;
> }
>
> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> #endif /* CONFIG_PM_OPP */
>
> #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
--
---Trilok Soni
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 3:10 ` [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level() Praveen Talari
2025-05-02 3:49 ` Trilok Soni
@ 2025-05-02 5:37 ` Viresh Kumar
2025-05-02 7:37 ` Praveen Talari
2025-05-02 8:01 ` Praveen Talari
1 sibling, 2 replies; 27+ messages in thread
From: Viresh Kumar @ 2025-05-02 5:37 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
On 02-05-25, 08:40, Praveen Talari wrote:
> To configure a device to a specific performance level, consumer drivers
> currently need to determine the OPP based on the exact level and then
> set it, resulting in code duplication across drivers.
>
> The new helper API, dev_pm_opp_set_level(), addresses this issue by
> providing a streamlined method for consumer drivers to find and set the
> OPP based on the desired performance level, thereby eliminating
> redundancy.
>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v2 -> v3
> - moved function defination to pm_opp.h from core.c with inline
> - updated return value with IS_ERR(opp)
>
> v1 -> v2
> - reorder sequence of tags in commit text
As Trilok mentioned, this is not the right place for this.
> ---
> include/linux/pm_opp.h | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
> index e7b5c602c92f..31ed8a7b554e 100644
> --- a/include/linux/pm_opp.h
> +++ b/include/linux/pm_opp.h
> @@ -197,6 +197,28 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
> void dev_pm_opp_remove_table(struct device *dev);
> void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
> int dev_pm_opp_sync_regulators(struct device *dev);
> +
> +/*
> + * dev_pm_opp_set_level() - Configure device for a level
> + * @dev: device for which we do this operation
> + * @level: level to set to
> + *
> + * Return: 0 on success, a non-zero value if there is an error otherwise.
> + */
No need of these for simple wrappers.
> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
> +{
> + struct dev_pm_opp *opp = dev_pm_opp_find_level_exact(dev, level);
> + int ret;
> +
> + if (IS_ERR(opp))
> + return IS_ERR(opp);
IS_ERR is wrong here, should be PTR_ERR.
> +
> + ret = dev_pm_opp_set_opp(dev, opp);
> + dev_pm_opp_put(opp);
> +
> + return ret;
> +}
> +
> #else
> static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
> {
> @@ -461,6 +483,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
> return -EOPNOTSUPP;
> }
>
> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
> +{
> + return -EOPNOTSUPP;
> +}
> +
No need of these too for such wrappers. And then this isn't rebased
over latest changes in the OPP core.
I modified it and applied the below version to my tree now.
--
viresh
Author: Praveen Talari <quic_ptalari@quicinc.com>
Date: Fri May 2 10:58:22 2025 +0530
OPP: Add dev_pm_opp_set_level()
To configure a device to a specific performance level, consumer drivers
currently need to determine the OPP based on the exact level and then
set it, resulting in code duplication across drivers.
The new helper API, dev_pm_opp_set_level(), addresses this issue by
providing a streamlined method for consumer drivers to find and set the
OPP based on the desired performance level, thereby eliminating
redundancy.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
[ Viresh: Lot of fixes in the code, and rebased over latest changes.
Fixed commit log too. ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
include/linux/pm_opp.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 8313ed981535..cf477beae4bb 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -197,6 +197,7 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
void dev_pm_opp_remove_table(struct device *dev);
void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
int dev_pm_opp_sync_regulators(struct device *dev);
+
#else
static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
{
@@ -717,4 +718,14 @@ static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
return dev_pm_opp_get_freq_indexed(opp, 0);
}
+static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
+{
+ struct dev_pm_opp *opp __free(put_opp) = dev_pm_opp_find_level_exact(dev, level);
+
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
+
+ return dev_pm_opp_set_opp(dev, opp);
+}
+
#endif /* __LINUX_OPP_H__ */
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 5:37 ` Viresh Kumar
@ 2025-05-02 7:37 ` Praveen Talari
2025-05-02 7:45 ` Viresh Kumar
2025-05-02 8:01 ` Praveen Talari
1 sibling, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 7:37 UTC (permalink / raw)
To: Viresh Kumar
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
Hi Viresh
Thank you for review.
On 5/2/2025 11:07 AM, Viresh Kumar wrote:
> On 02-05-25, 08:40, Praveen Talari wrote:
>> To configure a device to a specific performance level, consumer drivers
>> currently need to determine the OPP based on the exact level and then
>> set it, resulting in code duplication across drivers.
>>
>> The new helper API, dev_pm_opp_set_level(), addresses this issue by
>> providing a streamlined method for consumer drivers to find and set the
>> OPP based on the desired performance level, thereby eliminating
>> redundancy.
>>
>> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>>
>> v2 -> v3
>> - moved function defination to pm_opp.h from core.c with inline
>> - updated return value with IS_ERR(opp)
>>
>> v1 -> v2
>> - reorder sequence of tags in commit text
> As Trilok mentioned, this is not the right place for this.
>
>> ---
>> include/linux/pm_opp.h | 27 +++++++++++++++++++++++++++
>> 1 file changed, 27 insertions(+)
>>
>> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
>> index e7b5c602c92f..31ed8a7b554e 100644
>> --- a/include/linux/pm_opp.h
>> +++ b/include/linux/pm_opp.h
>> @@ -197,6 +197,28 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
>> void dev_pm_opp_remove_table(struct device *dev);
>> void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
>> int dev_pm_opp_sync_regulators(struct device *dev);
>> +
>> +/*
>> + * dev_pm_opp_set_level() - Configure device for a level
>> + * @dev: device for which we do this operation
>> + * @level: level to set to
>> + *
>> + * Return: 0 on success, a non-zero value if there is an error otherwise.
>> + */
> No need of these for simple wrappers.
>
>> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
>> +{
>> + struct dev_pm_opp *opp = dev_pm_opp_find_level_exact(dev, level);
>> + int ret;
>> +
>> + if (IS_ERR(opp))
>> + return IS_ERR(opp);
> IS_ERR is wrong here, should be PTR_ERR.
>
>> +
>> + ret = dev_pm_opp_set_opp(dev, opp);
>> + dev_pm_opp_put(opp);
>> +
>> + return ret;
>> +}
>> +
>> #else
>> static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
>> {
>> @@ -461,6 +483,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
>> return -EOPNOTSUPP;
>> }
>>
>> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
> No need of these too for such wrappers. And then this isn't rebased
How come? i have synced linux-next today itself and pushed from it,
even i didn't face any issue.
Let me know how/where rebased i.e linux-next or linux?
> over latest changes in the OPP core.
>
> I modified it and applied the below version to my tree now.
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 7:37 ` Praveen Talari
@ 2025-05-02 7:45 ` Viresh Kumar
0 siblings, 0 replies; 27+ messages in thread
From: Viresh Kumar @ 2025-05-02 7:45 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
On 02-05-25, 13:07, Praveen Talari wrote:
> How come? i have synced linux-next today itself and pushed from it, even i
> didn't face any issue.
Yeah, you won't face any issues, but scope-based cleanup helpers were
added recently and should have been used here, though it wasn't
obvious, so its fine.
> Let me know how/where rebased i.e linux-next or linux?
linux-next should be fine normally.
--
viresh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 5:37 ` Viresh Kumar
2025-05-02 7:37 ` Praveen Talari
@ 2025-05-02 8:01 ` Praveen Talari
2025-05-02 8:14 ` Viresh Kumar
1 sibling, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 8:01 UTC (permalink / raw)
To: Viresh Kumar
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
HI Viresh
On 5/2/2025 11:07 AM, Viresh Kumar wrote:
> On 02-05-25, 08:40, Praveen Talari wrote:
>> To configure a device to a specific performance level, consumer drivers
>> currently need to determine the OPP based on the exact level and then
>> set it, resulting in code duplication across drivers.
>>
>> The new helper API, dev_pm_opp_set_level(), addresses this issue by
>> providing a streamlined method for consumer drivers to find and set the
>> OPP based on the desired performance level, thereby eliminating
>> redundancy.
>>
>> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>>
>> v2 -> v3
>> - moved function defination to pm_opp.h from core.c with inline
>> - updated return value with IS_ERR(opp)
>>
>> v1 -> v2
>> - reorder sequence of tags in commit text
> As Trilok mentioned, this is not the right place for this.
>
>> ---
>> include/linux/pm_opp.h | 27 +++++++++++++++++++++++++++
>> 1 file changed, 27 insertions(+)
>>
>> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
>> index e7b5c602c92f..31ed8a7b554e 100644
>> --- a/include/linux/pm_opp.h
>> +++ b/include/linux/pm_opp.h
>> @@ -197,6 +197,28 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
>> void dev_pm_opp_remove_table(struct device *dev);
>> void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
>> int dev_pm_opp_sync_regulators(struct device *dev);
>> +
>> +/*
>> + * dev_pm_opp_set_level() - Configure device for a level
>> + * @dev: device for which we do this operation
>> + * @level: level to set to
>> + *
>> + * Return: 0 on success, a non-zero value if there is an error otherwise.
>> + */
> No need of these for simple wrappers.
>
>> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
>> +{
>> + struct dev_pm_opp *opp = dev_pm_opp_find_level_exact(dev, level);
>> + int ret;
>> +
>> + if (IS_ERR(opp))
>> + return IS_ERR(opp);
> IS_ERR is wrong here, should be PTR_ERR.
>
>> +
>> + ret = dev_pm_opp_set_opp(dev, opp);
>> + dev_pm_opp_put(opp);
>> +
>> + return ret;
>> +}
>> +
>> #else
>> static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
>> {
>> @@ -461,6 +483,11 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
>> return -EOPNOTSUPP;
>> }
>>
>> +static inline int dev_pm_opp_set_level(struct device *dev, unsigned int level)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
> No need of these too for such wrappers. And then this isn't rebased
> over latest changes in the OPP core.
>
> I modified it and applied the below version to my tree now.
Shall i keep commit as you suggested with your SIB.
Thanks,
Praveen
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 8:01 ` Praveen Talari
@ 2025-05-02 8:14 ` Viresh Kumar
2025-05-02 14:01 ` Praveen Talari
0 siblings, 1 reply; 27+ messages in thread
From: Viresh Kumar @ 2025-05-02 8:14 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
On 02-05-25, 13:31, Praveen Talari wrote:
> Shall i keep commit as you suggested with your SIB.
I already applied it to my tree. You can drop it from your series now.
--
viresh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 8:14 ` Viresh Kumar
@ 2025-05-02 14:01 ` Praveen Talari
2025-05-02 14:11 ` Viresh Kumar
0 siblings, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 14:01 UTC (permalink / raw)
To: Viresh Kumar
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
Hi Viresh
On 5/2/2025 1:44 PM, Viresh Kumar wrote:
> On 02-05-25, 13:31, Praveen Talari wrote:
>> Shall i keep commit as you suggested with your SIB.
> I already applied it to my tree. You can drop it from your series now.
now i can push V4 right and will not face errors on my series w.r.t this
API.
Thanks,
Praveen
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 14:01 ` Praveen Talari
@ 2025-05-02 14:11 ` Viresh Kumar
2025-05-02 14:39 ` Praveen Talari
0 siblings, 1 reply; 27+ messages in thread
From: Viresh Kumar @ 2025-05-02 14:11 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
On Fri, 2 May 2025 at 19:32, Praveen Talari <quic_ptalari@quicinc.com> wrote:
> now i can push V4 right and will not face errors on my series w.r.t this
> API.
Not fully sure what you meant, but you can send a V4 of the series,
without the first patch. Please mention it as an dependency in the
cover letter and that it is applied in the OPP tree's linux-next branch.
The one who applies your series needs to apply the series over the commit
in my branch to avoid breakage (if your series is going in 6.16-rc1).
--
Viresh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level()
2025-05-02 14:11 ` Viresh Kumar
@ 2025-05-02 14:39 ` Praveen Talari
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 14:39 UTC (permalink / raw)
To: Viresh Kumar
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss
Hi
On 5/2/2025 7:41 PM, Viresh Kumar wrote:
> On Fri, 2 May 2025 at 19:32, Praveen Talari <quic_ptalari@quicinc.com> wrote:
>> now i can push V4 right and will not face errors on my series w.r.t this
>> API.
> Not fully sure what you meant, but you can send a V4 of the series,
i mean one of the patch from series is depended on patch-1, that i have
removed from series now
so will i face any issue like kernel bot
Thanks,
Praveen Talari
> without the first patch. Please mention it as an dependency in the
> cover letter and that it is applied in the OPP tree's linux-next branch.
>
> The one who applies your series needs to apply the series over the commit
> in my branch to avoid breakage (if your series is going in 6.16-rc1).
>
> --
> Viresh
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 2/9] dt-bindings: serial: describe SA8255p
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
2025-05-02 3:10 ` [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level() Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 3:49 ` Trilok Soni
2025-05-02 6:36 ` Krzysztof Kozlowski
2025-05-02 3:10 ` [PATCH v3 3/9] dt-bindings: qcom: geni-se: " Praveen Talari
` (6 subsequent siblings)
8 siblings, 2 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss, Nikunj Kela
From: Nikunj Kela <quic_nkela@quicinc.com>
SA8255p platform abstracts resources such as clocks, interconnect and
GPIO pins configuration in Firmware. SCMI power and perf protocols are
used to send request for resource configurations.
Add DT bindings for the QUP GENI UART controller on sa8255p platform.
Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v2 -> v3
- dropped description for interrupt-names
- rebased reg property order in required option
v1 -> v2
- reorder sequence of tags in commit text
- moved reg property after compatible field
- added interrupt-names property
---
.../serial/qcom,sa8255p-geni-uart.yaml | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
diff --git a/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml b/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
new file mode 100644
index 000000000000..85b1d7c05079
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/qcom,sa8255p-geni-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Geni based QUP UART interface
+
+maintainers:
+ - Praveen Talari <quic_ptalari@quicinc.com>
+
+allOf:
+ - $ref: /schemas/serial/serial.yaml#
+
+properties:
+ compatible:
+ enum:
+ - qcom,sa8255p-geni-uart
+ - qcom,sa8255p-geni-debug-uart
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ minItems: 1
+ items:
+ - description: UART core irq
+ - description: Wakeup irq (RX GPIO)
+
+ interrupt-names:
+ items:
+ - const: uart
+ - const: wakeup
+
+ power-domains:
+ minItems: 2
+ maxItems: 2
+
+ power-domain-names:
+ items:
+ - const: power
+ - const: perf
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - power-domain-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ serial@990000 {
+ compatible = "qcom,sa8255p-geni-uart";
+ reg = <0x990000 0x4000>;
+ interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&scmi0_pd 0>, <&scmi0_dvfs 0>;
+ power-domain-names = "power", "perf";
+ };
+...
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 2/9] dt-bindings: serial: describe SA8255p
2025-05-02 3:10 ` [PATCH v3 2/9] dt-bindings: serial: describe SA8255p Praveen Talari
@ 2025-05-02 3:49 ` Trilok Soni
2025-05-02 6:36 ` Krzysztof Kozlowski
1 sibling, 0 replies; 27+ messages in thread
From: Trilok Soni @ 2025-05-02 3:49 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss, Nikunj Kela
On 5/1/2025 8:10 PM, Praveen Talari wrote:
> From: Nikunj Kela <quic_nkela@quicinc.com>
>
> SA8255p platform abstracts resources such as clocks, interconnect and
> GPIO pins configuration in Firmware. SCMI power and perf protocols are
> used to send request for resource configurations.
>
> Add DT bindings for the QUP GENI UART controller on sa8255p platform.
>
> Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
> Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v2 -> v3
> - dropped description for interrupt-names
> - rebased reg property order in required option
>
> v1 -> v2
> - reorder sequence of tags in commit text
> - moved reg property after compatible field
> - added interrupt-names property
Please fix all the patches.
> ---
> .../serial/qcom,sa8255p-geni-uart.yaml | 64 +++++++++++++++++++
> 1 file changed, 64 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
>
> diff --git a/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml b/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
> new file mode 100644
> index 000000000000..85b1d7c05079
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/qcom,sa8255p-geni-uart.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/serial/qcom,sa8255p-geni-uart.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Geni based QUP UART interface
> +
> +maintainers:
> + - Praveen Talari <quic_ptalari@quicinc.com>
> +
> +allOf:
> + - $ref: /schemas/serial/serial.yaml#
> +
> +properties:
> + compatible:
> + enum:
> + - qcom,sa8255p-geni-uart
> + - qcom,sa8255p-geni-debug-uart
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + minItems: 1
> + items:
> + - description: UART core irq
> + - description: Wakeup irq (RX GPIO)
> +
> + interrupt-names:
> + items:
> + - const: uart
> + - const: wakeup
> +
> + power-domains:
> + minItems: 2
> + maxItems: 2
> +
> + power-domain-names:
> + items:
> + - const: power
> + - const: perf
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - power-domains
> + - power-domain-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> + serial@990000 {
> + compatible = "qcom,sa8255p-geni-uart";
> + reg = <0x990000 0x4000>;
> + interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
> + power-domains = <&scmi0_pd 0>, <&scmi0_dvfs 0>;
> + power-domain-names = "power", "perf";
> + };
> +...
--
---Trilok Soni
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v3 2/9] dt-bindings: serial: describe SA8255p
2025-05-02 3:10 ` [PATCH v3 2/9] dt-bindings: serial: describe SA8255p Praveen Talari
2025-05-02 3:49 ` Trilok Soni
@ 2025-05-02 6:36 ` Krzysztof Kozlowski
1 sibling, 0 replies; 27+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-02 6:36 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss, Nikunj Kela
On Fri, May 02, 2025 at 08:40:11AM GMT, Praveen Talari wrote:
> From: Nikunj Kela <quic_nkela@quicinc.com>
>
> SA8255p platform abstracts resources such as clocks, interconnect and
> GPIO pins configuration in Firmware. SCMI power and perf protocols are
> used to send request for resource configurations.
>
> Add DT bindings for the QUP GENI UART controller on sa8255p platform.
>
> Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
> Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v2 -> v3
> - dropped description for interrupt-names
> - rebased reg property order in required option
>
> v1 -> v2
> - reorder sequence of tags in commit text
> - moved reg property after compatible field
> - added interrupt-names property
That's not part of the commit. Look at other people's work for example
how to send patches.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 3/9] dt-bindings: qcom: geni-se: describe SA8255p
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
2025-05-02 3:10 ` [PATCH v3 1/9] opp: add new helper API dev_pm_opp_set_level() Praveen Talari
2025-05-02 3:10 ` [PATCH v3 2/9] dt-bindings: serial: describe SA8255p Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 6:37 ` Krzysztof Kozlowski
2025-05-02 3:10 ` [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms Praveen Talari
` (5 subsequent siblings)
8 siblings, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss, Nikunj Kela
From: Nikunj Kela <quic_nkela@quicinc.com>
SA8255p platform abstracts resources such as clocks, interconnect
configuration in Firmware.
Add DT bindings for the QUP Wrapper on sa8255p platform.
Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v2 -> v3
- reordered required option
v1 -> v2
- reorder sequence of tags in commit text
- resolved waring errors while encountered in dt binding and dtb check.
---
.../soc/qcom/qcom,sa8255p-geni-se-qup.yaml | 107 ++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,sa8255p-geni-se-qup.yaml
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,sa8255p-geni-se-qup.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,sa8255p-geni-se-qup.yaml
new file mode 100644
index 000000000000..b66c7c45a6ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,sa8255p-geni-se-qup.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/qcom/qcom,sa8255p-geni-se-qup.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GENI Serial Engine QUP Wrapper Controller
+
+maintainers:
+ - Praveen Talari <quic_ptalari@quicinc.com>
+
+description:
+ Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) wrapper
+ is a programmable module for supporting a wide range of serial interfaces
+ like UART, SPI, I2C, I3C, etc. A single QUP module can provide up to 8 Serial
+ Interfaces, using its internal Serial Engines. The GENI Serial Engine QUP
+ Wrapper controller is modeled as a node with zero or more child nodes each
+ representing a serial engine.
+
+properties:
+ compatible:
+ const: qcom,sa8255p-geni-se-qup
+
+ reg:
+ description: QUP wrapper common register address and length.
+ maxItems: 1
+
+ "#address-cells":
+ const: 2
+
+ "#size-cells":
+ const: 2
+
+ ranges: true
+
+ iommus:
+ maxItems: 1
+
+ dma-coherent: true
+
+patternProperties:
+ "spi@[0-9a-f]+$":
+ type: object
+ description: GENI serial engine based SPI controller. SPI in master mode
+ supports up to 50MHz, up to four chip selects, programmable
+ data path from 4 bits to 32 bits and numerous protocol
+ variants.
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: qcom,sa8255p-geni-spi
+
+ "i2c@[0-9a-f]+$":
+ type: object
+ description: GENI serial engine based I2C controller.
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: qcom,sa8255p-geni-i2c
+
+ "serial@[0-9a-f]+$":
+ type: object
+ description: GENI Serial Engine based UART Controller.
+ additionalProperties: true
+
+ properties:
+ compatible:
+ enum:
+ - qcom,sa8255p-geni-uart
+ - qcom,sa8255p-geni-debug-uart
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - "#address-cells"
+ - "#size-cells"
+ - ranges
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ geniqup@9c0000 {
+ compatible = "qcom,sa8255p-geni-se-qup";
+ reg = <0 0x9c0000 0 0x6000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ serial@990000 {
+ compatible = "qcom,sa8255p-geni-uart";
+ reg = <0 0x990000 0 0x4000>;
+ interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&scmi0_pd 0>, <&scmi0_dvfs 0>;
+ power-domain-names = "power", "perf";
+ };
+ };
+ };
+...
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 3/9] dt-bindings: qcom: geni-se: describe SA8255p
2025-05-02 3:10 ` [PATCH v3 3/9] dt-bindings: qcom: geni-se: " Praveen Talari
@ 2025-05-02 6:37 ` Krzysztof Kozlowski
2025-05-02 8:07 ` Praveen Talari
0 siblings, 1 reply; 27+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-02 6:37 UTC (permalink / raw)
To: Praveen Talari
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss, Nikunj Kela
On Fri, May 02, 2025 at 08:40:12AM GMT, Praveen Talari wrote:
> From: Nikunj Kela <quic_nkela@quicinc.com>
>
> SA8255p platform abstracts resources such as clocks, interconnect
> configuration in Firmware.
>
> Add DT bindings for the QUP Wrapper on sa8255p platform.
>
> Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
> Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v2 -> v3
> - reordered required option
...
> +additionalProperties: false
> +
> +required:
Which part of "required: block goes after properties and
patternproperties." is unclear?
Look at example schema.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v3 3/9] dt-bindings: qcom: geni-se: describe SA8255p
2025-05-02 6:37 ` Krzysztof Kozlowski
@ 2025-05-02 8:07 ` Praveen Talari
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 8:07 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, linux-arm-msm,
linux-kernel, linux-serial, devicetree, linux-pm, psodagud,
djaggi, quic_msavaliy, quic_vtanuku, quic_arandive, quic_mnaresh,
quic_shazhuss, Nikunj Kela
HI Krzysztof
Thank you for review
On 5/2/2025 12:07 PM, Krzysztof Kozlowski wrote:
> On Fri, May 02, 2025 at 08:40:12AM GMT, Praveen Talari wrote:
>> From: Nikunj Kela <quic_nkela@quicinc.com>
>>
>> SA8255p platform abstracts resources such as clocks, interconnect
>> configuration in Firmware.
>>
>> Add DT bindings for the QUP Wrapper on sa8255p platform.
>>
>> Signed-off-by: Nikunj Kela <quic_nkela@quicinc.com>
>> Co-developed-by: Praveen Talari <quic_ptalari@quicinc.com>
>> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>>
>> v2 -> v3
>> - reordered required option
>
> ...
>
>
>> +additionalProperties: false
>> +
>> +required:
> Which part of "required: block goes after properties and
> patternproperties." is unclear?
Yup I understood. it is like
properties:
-
patternproperties:
-
required:
Thanks,
Praveen Talari
>
> Look at example schema.
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (2 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 3/9] dt-bindings: qcom: geni-se: " Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 9:28 ` neil.armstrong
2025-05-07 5:49 ` kernel test robot
2025-05-02 3:10 ` [PATCH v3 5/9] serial: qcom-geni: move resource initialization to separate function Praveen Talari
` (4 subsequent siblings)
8 siblings, 2 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
On the sa8255p platform, resources such as clocks,interconnects
and TLMM (GPIO) configurations are managed by firmware.
Introduce a platform data function callback to distinguish whether
resource control is performed by firmware or directly by the driver
in linux.
The refactor ensures clear differentiation of resource
management mechanisms, improving maintainability and flexibility
in handling platform-specific configurations.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v1 -> v2
- changed datatype of i from int to unsigned int as per comment.
---
drivers/soc/qcom/qcom-geni-se.c | 77 +++++++++++++++++++++------------
1 file changed, 49 insertions(+), 28 deletions(-)
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 4cb959106efa..0e3658b09603 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -105,6 +105,8 @@ struct geni_wrapper {
struct geni_se_desc {
unsigned int num_clks;
const char * const *clks;
+ int (*geni_se_rsc_init)(struct geni_wrapper *wrapper,
+ const struct geni_se_desc *desc);
};
static const char * const icc_path_names[] = {"qup-core", "qup-config",
@@ -891,10 +893,44 @@ int geni_icc_disable(struct geni_se *se)
}
EXPORT_SYMBOL_GPL(geni_icc_disable);
+static int geni_se_resource_init(struct geni_wrapper *wrapper,
+ const struct geni_se_desc *desc)
+{
+ struct device *dev = wrapper->dev;
+ int ret;
+ unsigned int i;
+
+ wrapper->num_clks = min_t(unsigned int, desc->num_clks, MAX_CLKS);
+
+ for (i = 0; i < wrapper->num_clks; ++i)
+ wrapper->clks[i].id = desc->clks[i];
+
+ ret = of_count_phandle_with_args(dev->of_node, "clocks", "#clock-cells");
+ if (ret < 0) {
+ dev_err(dev, "invalid clocks property at %pOF\n", dev->of_node);
+ return ret;
+ }
+
+ if (ret < wrapper->num_clks) {
+ dev_err(dev, "invalid clocks count at %pOF, expected %d entries\n",
+ dev->of_node, wrapper->num_clks);
+ return -EINVAL;
+ }
+
+ ret = devm_clk_bulk_get(dev, wrapper->num_clks, wrapper->clks);
+ if (ret) {
+ dev_err(dev, "Err getting clks %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
static int geni_se_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct geni_wrapper *wrapper;
+ const struct geni_se_desc *desc;
int ret;
wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
@@ -906,36 +942,12 @@ static int geni_se_probe(struct platform_device *pdev)
if (IS_ERR(wrapper->base))
return PTR_ERR(wrapper->base);
- if (!has_acpi_companion(&pdev->dev)) {
- const struct geni_se_desc *desc;
- int i;
-
- desc = device_get_match_data(&pdev->dev);
- if (!desc)
- return -EINVAL;
-
- wrapper->num_clks = min_t(unsigned int, desc->num_clks, MAX_CLKS);
-
- for (i = 0; i < wrapper->num_clks; ++i)
- wrapper->clks[i].id = desc->clks[i];
-
- ret = of_count_phandle_with_args(dev->of_node, "clocks", "#clock-cells");
- if (ret < 0) {
- dev_err(dev, "invalid clocks property at %pOF\n", dev->of_node);
- return ret;
- }
+ desc = device_get_match_data(&pdev->dev);
- if (ret < wrapper->num_clks) {
- dev_err(dev, "invalid clocks count at %pOF, expected %d entries\n",
- dev->of_node, wrapper->num_clks);
+ if (!has_acpi_companion(&pdev->dev) && desc->geni_se_rsc_init) {
+ ret = desc->geni_se_rsc_init(wrapper, desc);
+ if (ret)
return -EINVAL;
- }
-
- ret = devm_clk_bulk_get(dev, wrapper->num_clks, wrapper->clks);
- if (ret) {
- dev_err(dev, "Err getting clks %d\n", ret);
- return ret;
- }
}
dev_set_drvdata(dev, wrapper);
@@ -951,6 +963,13 @@ static const char * const qup_clks[] = {
static const struct geni_se_desc qup_desc = {
.clks = qup_clks,
.num_clks = ARRAY_SIZE(qup_clks),
+ .geni_se_rsc_init = geni_se_resource_init,
+};
+
+static const struct geni_se_desc sa8255p_qup_desc = {
+ .clks = NULL,
+ .num_clks = 0,
+ .geni_se_rsc_init = NULL,
};
static const char * const i2c_master_hub_clks[] = {
@@ -960,11 +979,13 @@ static const char * const i2c_master_hub_clks[] = {
static const struct geni_se_desc i2c_master_hub_desc = {
.clks = i2c_master_hub_clks,
.num_clks = ARRAY_SIZE(i2c_master_hub_clks),
+ .geni_se_rsc_init = geni_se_resource_init,
};
static const struct of_device_id geni_se_dt_match[] = {
{ .compatible = "qcom,geni-se-qup", .data = &qup_desc },
{ .compatible = "qcom,geni-se-i2c-master-hub", .data = &i2c_master_hub_desc },
+ { .compatible = "qcom,sa8255p-geni-se-qup", .data = &sa8255p_qup_desc },
{}
};
MODULE_DEVICE_TABLE(of, geni_se_dt_match);
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms
2025-05-02 3:10 ` [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms Praveen Talari
@ 2025-05-02 9:28 ` neil.armstrong
2025-05-07 5:49 ` kernel test robot
1 sibling, 0 replies; 27+ messages in thread
From: neil.armstrong @ 2025-05-02 9:28 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
On 02/05/2025 05:10, Praveen Talari wrote:
> On the sa8255p platform, resources such as clocks,interconnects
> and TLMM (GPIO) configurations are managed by firmware.
>
> Introduce a platform data function callback to distinguish whether
> resource control is performed by firmware or directly by the driver
> in linux.
>
> The refactor ensures clear differentiation of resource
> management mechanisms, improving maintainability and flexibility
> in handling platform-specific configurations.
>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
>
> v1 -> v2
> - changed datatype of i from int to unsigned int as per comment.
> ---
> drivers/soc/qcom/qcom-geni-se.c | 77 +++++++++++++++++++++------------
> 1 file changed, 49 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> index 4cb959106efa..0e3658b09603 100644
> --- a/drivers/soc/qcom/qcom-geni-se.c
> +++ b/drivers/soc/qcom/qcom-geni-se.c
> @@ -105,6 +105,8 @@ struct geni_wrapper {
> struct geni_se_desc {
> unsigned int num_clks;
> const char * const *clks;
> + int (*geni_se_rsc_init)(struct geni_wrapper *wrapper,
> + const struct geni_se_desc *desc);
> };
>
> static const char * const icc_path_names[] = {"qup-core", "qup-config",
> @@ -891,10 +893,44 @@ int geni_icc_disable(struct geni_se *se)
> }
> EXPORT_SYMBOL_GPL(geni_icc_disable);
>
> +static int geni_se_resource_init(struct geni_wrapper *wrapper,
> + const struct geni_se_desc *desc)
> +{
> + struct device *dev = wrapper->dev;
> + int ret;
> + unsigned int i;
> +
> + wrapper->num_clks = min_t(unsigned int, desc->num_clks, MAX_CLKS);
> +
> + for (i = 0; i < wrapper->num_clks; ++i)
> + wrapper->clks[i].id = desc->clks[i];
> +
> + ret = of_count_phandle_with_args(dev->of_node, "clocks", "#clock-cells");
> + if (ret < 0) {
> + dev_err(dev, "invalid clocks property at %pOF\n", dev->of_node);
> + return ret;
> + }
> +
> + if (ret < wrapper->num_clks) {
> + dev_err(dev, "invalid clocks count at %pOF, expected %d entries\n",
> + dev->of_node, wrapper->num_clks);
> + return -EINVAL;
> + }
> +
> + ret = devm_clk_bulk_get(dev, wrapper->num_clks, wrapper->clks);
> + if (ret) {
> + dev_err(dev, "Err getting clks %d\n", ret);
> + return ret;
> + }
> +
> + return ret;
> +}
> +
> static int geni_se_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> struct geni_wrapper *wrapper;
> + const struct geni_se_desc *desc;
> int ret;
>
> wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
> @@ -906,36 +942,12 @@ static int geni_se_probe(struct platform_device *pdev)
> if (IS_ERR(wrapper->base))
> return PTR_ERR(wrapper->base);
>
> - if (!has_acpi_companion(&pdev->dev)) {
> - const struct geni_se_desc *desc;
> - int i;
> -
> - desc = device_get_match_data(&pdev->dev);
> - if (!desc)
> - return -EINVAL;
> -
> - wrapper->num_clks = min_t(unsigned int, desc->num_clks, MAX_CLKS);
> -
> - for (i = 0; i < wrapper->num_clks; ++i)
> - wrapper->clks[i].id = desc->clks[i];
> -
> - ret = of_count_phandle_with_args(dev->of_node, "clocks", "#clock-cells");
> - if (ret < 0) {
> - dev_err(dev, "invalid clocks property at %pOF\n", dev->of_node);
> - return ret;
> - }
> + desc = device_get_match_data(&pdev->dev);
>
> - if (ret < wrapper->num_clks) {
> - dev_err(dev, "invalid clocks count at %pOF, expected %d entries\n",
> - dev->of_node, wrapper->num_clks);
> + if (!has_acpi_companion(&pdev->dev) && desc->geni_se_rsc_init) {
> + ret = desc->geni_se_rsc_init(wrapper, desc);
> + if (ret)
> return -EINVAL;
> - }
> -
> - ret = devm_clk_bulk_get(dev, wrapper->num_clks, wrapper->clks);
> - if (ret) {
> - dev_err(dev, "Err getting clks %d\n", ret);
> - return ret;
> - }
> }
>
> dev_set_drvdata(dev, wrapper);
> @@ -951,6 +963,13 @@ static const char * const qup_clks[] = {
> static const struct geni_se_desc qup_desc = {
> .clks = qup_clks,
> .num_clks = ARRAY_SIZE(qup_clks),
> + .geni_se_rsc_init = geni_se_resource_init,
> +};
> +
> +static const struct geni_se_desc sa8255p_qup_desc = {
> + .clks = NULL,
> + .num_clks = 0,
> + .geni_se_rsc_init = NULL,
Just don't specify it, it will be NULL by default, same for the other fields aswell.
Just declare an empty struct instead, maybe add a comment if you want the reader
to understand there's no clocks for this instance type.
Another much simpler way to implement this would be to just check for num_clks
along !has_acpi_companion(&pdev->dev) like:
if (!has_acpi_companion(&pdev->dev) && desc->num_clks) {
}
And you're done.
Neil
> };
>
> static const char * const i2c_master_hub_clks[] = {
> @@ -960,11 +979,13 @@ static const char * const i2c_master_hub_clks[] = {
> static const struct geni_se_desc i2c_master_hub_desc = {
> .clks = i2c_master_hub_clks,
> .num_clks = ARRAY_SIZE(i2c_master_hub_clks),
> + .geni_se_rsc_init = geni_se_resource_init,
> };
>
> static const struct of_device_id geni_se_dt_match[] = {
> { .compatible = "qcom,geni-se-qup", .data = &qup_desc },
> { .compatible = "qcom,geni-se-i2c-master-hub", .data = &i2c_master_hub_desc },
> + { .compatible = "qcom,sa8255p-geni-se-qup", .data = &sa8255p_qup_desc },
> {}
> };
> MODULE_DEVICE_TABLE(of, geni_se_dt_match);
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms
2025-05-02 3:10 ` [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms Praveen Talari
2025-05-02 9:28 ` neil.armstrong
@ 2025-05-07 5:49 ` kernel test robot
1 sibling, 0 replies; 27+ messages in thread
From: kernel test robot @ 2025-05-07 5:49 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: oe-kbuild-all, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_mnaresh, quic_shazhuss
Hi Praveen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 3e039dcc9c1320c0d33ddd51c372dcc91d3ea3c7]
url: https://github.com/intel-lab-lkp/linux/commits/Praveen-Talari/opp-add-new-helper-API-dev_pm_opp_set_level/20250502-111540
base: 3e039dcc9c1320c0d33ddd51c372dcc91d3ea3c7
patch link: https://lore.kernel.org/r/20250502031018.1292-5-quic_ptalari%40quicinc.com
patch subject: [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms
config: arc-randconfig-002-20250502 (https://download.01.org/0day-ci/archive/20250507/202505071326.jjvv4tTv-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 12.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250507/202505071326.jjvv4tTv-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505071326.jjvv4tTv-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> Warning: drivers/soc/qcom/qcom-geni-se.c:109 struct member 'geni_se_rsc_init' not described in 'geni_se_desc'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 5/9] serial: qcom-geni: move resource initialization to separate function
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (3 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 4/9] soc: qcom: geni-se: Enable QUPs on SA8255p Qualcomm platforms Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 3:10 ` [PATCH v3 6/9] serial: qcom-geni: move resource control logic to separate functions Praveen Talari
` (3 subsequent siblings)
8 siblings, 0 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
Enhances code readability and future modifications within the new API.
Move the code that handles the actual initialization of resources
like clock and ICC paths to a separate function, making the
probe function cleaner.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v1 -> v2
- updated subject description.
- added a new line after function end
---
drivers/tty/serial/qcom_geni_serial.c | 66 ++++++++++++++++-----------
1 file changed, 40 insertions(+), 26 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 0293b6210aa6..6ad759146f71 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1588,6 +1588,43 @@ static struct uart_driver qcom_geni_uart_driver = {
.nr = GENI_UART_PORTS,
};
+static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
+{
+ int ret;
+
+ port->se.clk = devm_clk_get(port->se.dev, "se");
+ if (IS_ERR(port->se.clk)) {
+ ret = PTR_ERR(port->se.clk);
+ dev_err(port->se.dev, "Err getting SE Core clk %d\n", ret);
+ return ret;
+ }
+
+ ret = geni_icc_get(&port->se, NULL);
+ if (ret)
+ return ret;
+
+ port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
+ port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
+
+ /* Set BW for register access */
+ ret = geni_icc_set_bw(&port->se);
+ if (ret)
+ return ret;
+
+ ret = devm_pm_opp_set_clkname(port->se.dev, "se");
+ if (ret)
+ return ret;
+
+ /* OPP table is optional */
+ ret = devm_pm_opp_of_add_table(port->se.dev);
+ if (ret && ret != -ENODEV) {
+ dev_err(port->se.dev, "invalid OPP table in device tree\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static void qcom_geni_serial_pm(struct uart_port *uport,
unsigned int new_state, unsigned int old_state)
{
@@ -1690,12 +1727,10 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->dev_data = data;
port->se.dev = &pdev->dev;
port->se.wrapper = dev_get_drvdata(pdev->dev.parent);
- port->se.clk = devm_clk_get(&pdev->dev, "se");
- if (IS_ERR(port->se.clk)) {
- ret = PTR_ERR(port->se.clk);
- dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret);
+
+ ret = geni_serial_resource_init(port);
+ if (ret)
return ret;
- }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -1713,17 +1748,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
return -ENOMEM;
}
- ret = geni_icc_get(&port->se, NULL);
- if (ret)
- return ret;
- port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
- port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
-
- /* Set BW for register access */
- ret = geni_icc_set_bw(&port->se);
- if (ret)
- return ret;
-
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
"qcom_geni_serial_%s%d",
uart_console(uport) ? "console" : "uart", uport->line);
@@ -1745,16 +1769,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap"))
port->cts_rts_swap = true;
- ret = devm_pm_opp_set_clkname(&pdev->dev, "se");
- if (ret)
- return ret;
- /* OPP table is optional */
- ret = devm_pm_opp_of_add_table(&pdev->dev);
- if (ret && ret != -ENODEV) {
- dev_err(&pdev->dev, "invalid OPP table in device tree\n");
- return ret;
- }
-
port->private_data.drv = drv;
uport->private_data = &port->private_data;
platform_set_drvdata(pdev, port);
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v3 6/9] serial: qcom-geni: move resource control logic to separate functions
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (4 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 5/9] serial: qcom-geni: move resource initialization to separate function Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 3:10 ` [PATCH v3 7/9] serial: qcom-geni: move clock-rate logic to separate function Praveen Talari
` (2 subsequent siblings)
8 siblings, 0 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
Supports use in PM system/runtime frameworks, helping to
distinguish new resource control mechanisms and facilitate
future modifications within the new API.
The code that handles the actual enable or disable of resources
like clock and ICC paths to a separate function
(geni_serial_resources_on() and geni_serial_resources_off()) which
enhances code readability.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v1 -> v2
- returned 0 instead of ret variable
---
drivers/tty/serial/qcom_geni_serial.c | 54 +++++++++++++++++++++------
1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 6ad759146f71..2cd2085473f3 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1588,6 +1588,42 @@ static struct uart_driver qcom_geni_uart_driver = {
.nr = GENI_UART_PORTS,
};
+static int geni_serial_resources_off(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ int ret;
+
+ dev_pm_opp_set_rate(uport->dev, 0);
+ ret = geni_se_resources_off(&port->se);
+ if (ret)
+ return ret;
+
+ geni_icc_disable(&port->se);
+
+ return 0;
+}
+
+static int geni_serial_resources_on(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ int ret;
+
+ ret = geni_icc_enable(&port->se);
+ if (ret)
+ return ret;
+
+ ret = geni_se_resources_on(&port->se);
+ if (ret) {
+ geni_icc_disable(&port->se);
+ return ret;
+ }
+
+ if (port->clk_rate)
+ dev_pm_opp_set_rate(uport->dev, port->clk_rate);
+
+ return 0;
+}
+
static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
{
int ret;
@@ -1628,23 +1664,17 @@ static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
static void qcom_geni_serial_pm(struct uart_port *uport,
unsigned int new_state, unsigned int old_state)
{
- struct qcom_geni_serial_port *port = to_dev_port(uport);
/* If we've never been called, treat it as off */
if (old_state == UART_PM_STATE_UNDEFINED)
old_state = UART_PM_STATE_OFF;
- if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) {
- geni_icc_enable(&port->se);
- if (port->clk_rate)
- dev_pm_opp_set_rate(uport->dev, port->clk_rate);
- geni_se_resources_on(&port->se);
- } else if (new_state == UART_PM_STATE_OFF &&
- old_state == UART_PM_STATE_ON) {
- geni_se_resources_off(&port->se);
- dev_pm_opp_set_rate(uport->dev, 0);
- geni_icc_disable(&port->se);
- }
+ if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
+ geni_serial_resources_on(uport);
+ else if (new_state == UART_PM_STATE_OFF &&
+ old_state == UART_PM_STATE_ON)
+ geni_serial_resources_off(uport);
+
}
static const struct uart_ops qcom_geni_console_pops = {
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v3 7/9] serial: qcom-geni: move clock-rate logic to separate function
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (5 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 6/9] serial: qcom-geni: move resource control logic to separate functions Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 3:10 ` [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
2025-05-02 3:10 ` [PATCH v3 9/9] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
8 siblings, 0 replies; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
Facilitates future modifications within the new function,
leading to better readability and maintainability of the code.
Move the code that handles the actual logic of clock-rate
calculations to a separate function geni_serial_set_rate()
which enhances code readability.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
v1 -> v2
- resolved build warnings for datatype format specifiers
- removed double spaces in log
---
drivers/tty/serial/qcom_geni_serial.c | 62 +++++++++++++++++----------
1 file changed, 39 insertions(+), 23 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 2cd2085473f3..60afee3884a6 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1283,27 +1283,14 @@ static unsigned long get_clk_div_rate(struct clk *clk, unsigned int baud,
return ser_clk;
}
-static void qcom_geni_serial_set_termios(struct uart_port *uport,
- struct ktermios *termios,
- const struct ktermios *old)
+static int geni_serial_set_rate(struct uart_port *uport, unsigned long baud)
{
- unsigned int baud;
- u32 bits_per_char;
- u32 tx_trans_cfg;
- u32 tx_parity_cfg;
- u32 rx_trans_cfg;
- u32 rx_parity_cfg;
- u32 stop_bit_len;
- unsigned int clk_div;
- u32 ser_clk_cfg;
struct qcom_geni_serial_port *port = to_dev_port(uport);
unsigned long clk_rate;
- u32 ver, sampling_rate;
unsigned int avg_bw_core;
- unsigned long timeout;
-
- /* baud rate */
- baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
+ unsigned int clk_div;
+ u32 ver, sampling_rate;
+ u32 ser_clk_cfg;
sampling_rate = UART_OVERSAMPLING;
/* Sampling rate is halved for IP versions >= 2.5 */
@@ -1315,13 +1302,13 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
sampling_rate, &clk_div);
if (!clk_rate) {
dev_err(port->se.dev,
- "Couldn't find suitable clock rate for %u\n",
+ "Couldn't find suitable clock rate for %lu\n",
baud * sampling_rate);
- return;
+ return -EINVAL;
}
- dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n",
- baud * sampling_rate, clk_rate, clk_div);
+ dev_dbg(port->se.dev, "desired_rate = %lu, clk_rate = %lu, clk_div = %u\n",
+ baud * sampling_rate, clk_rate, clk_div);
uport->uartclk = clk_rate;
port->clk_rate = clk_rate;
@@ -1339,6 +1326,37 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud);
geni_icc_set_bw(&port->se);
+ writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
+ writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
+ return 0;
+}
+
+static void qcom_geni_serial_set_termios(struct uart_port *uport,
+ struct ktermios *termios,
+ const struct ktermios *old)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ unsigned int baud;
+ unsigned long timeout;
+ u32 bits_per_char;
+ u32 tx_trans_cfg;
+ u32 tx_parity_cfg;
+ u32 rx_trans_cfg;
+ u32 rx_parity_cfg;
+ u32 stop_bit_len;
+ int ret = 0;
+
+ /* baud rate */
+ baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
+
+ ret = geni_serial_set_rate(uport, baud);
+ if (ret) {
+ dev_err(port->se.dev,
+ "%s: Failed to set baud:%u ret:%d\n",
+ __func__, baud, ret);
+ return;
+ }
+
/* parity */
tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
@@ -1406,8 +1424,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
- writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
- writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
}
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (6 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 7/9] serial: qcom-geni: move clock-rate logic to separate function Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-07 7:58 ` kernel test robot
2025-05-02 3:10 ` [PATCH v3 9/9] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
8 siblings, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
Add Power Management (PM) runtime support to Qualcomm GENI
serial driver.
Introduce necessary callbacks and updates to ensure seamless
transitions between power states, enhancing overall power
efficiency.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
---
drivers/tty/serial/qcom_geni_serial.c | 33 +++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 60afee3884a6..9d698c354510 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1686,10 +1686,10 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
old_state = UART_PM_STATE_OFF;
if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
- geni_serial_resources_on(uport);
+ pm_runtime_resume_and_get(uport->dev);
else if (new_state == UART_PM_STATE_OFF &&
old_state == UART_PM_STATE_ON)
- geni_serial_resources_off(uport);
+ pm_runtime_put_sync(uport->dev);
}
@@ -1827,9 +1827,11 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
return ret;
}
+ pm_runtime_enable(port->se.dev);
+
ret = uart_add_one_port(drv, uport);
if (ret)
- return ret;
+ goto error;
if (port->wakeup_irq > 0) {
device_init_wakeup(&pdev->dev, true);
@@ -1839,11 +1841,15 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, false);
ida_free(&port_ida, uport->line);
uart_remove_one_port(drv, uport);
- return ret;
+ goto error;
}
}
return 0;
+
+error:
+ pm_runtime_disable(port->se.dev);
+ return ret;
}
static void qcom_geni_serial_remove(struct platform_device *pdev)
@@ -1855,9 +1861,26 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
ida_free(&port_ida, uport->line);
+ pm_runtime_disable(port->se.dev);
uart_remove_one_port(drv, &port->uport);
}
+static int qcom_geni_serial_runtime_suspend(struct device *dev)
+{
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
+ struct uart_port *uport = &port->uport;
+
+ return geni_serial_resources_off(uport);
+};
+
+static int qcom_geni_serial_runtime_resume(struct device *dev)
+{
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
+ struct uart_port *uport = &port->uport;
+
+ return geni_serial_resources_on(uport);
+};
+
static int qcom_geni_serial_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
@@ -1901,6 +1924,8 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
};
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
+ SET_RUNTIME_PM_OPS(qcom_geni_serial_runtime_suspend,
+ qcom_geni_serial_runtime_resume, NULL)
SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
};
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver
2025-05-02 3:10 ` [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
@ 2025-05-07 7:58 ` kernel test robot
0 siblings, 0 replies; 27+ messages in thread
From: kernel test robot @ 2025-05-07 7:58 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: oe-kbuild-all, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_mnaresh, quic_shazhuss
Hi Praveen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 3e039dcc9c1320c0d33ddd51c372dcc91d3ea3c7]
url: https://github.com/intel-lab-lkp/linux/commits/Praveen-Talari/opp-add-new-helper-API-dev_pm_opp_set_level/20250502-111540
base: 3e039dcc9c1320c0d33ddd51c372dcc91d3ea3c7
patch link: https://lore.kernel.org/r/20250502031018.1292-9-quic_ptalari%40quicinc.com
patch subject: [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20250507/202505071523.FhPMXslL-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250507/202505071523.FhPMXslL-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505071523.FhPMXslL-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/tty/serial/qcom_geni_serial.c:1876:12: warning: 'qcom_geni_serial_runtime_resume' defined but not used [-Wunused-function]
1876 | static int qcom_geni_serial_runtime_resume(struct device *dev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/tty/serial/qcom_geni_serial.c:1868:12: warning: 'qcom_geni_serial_runtime_suspend' defined but not used [-Wunused-function]
1868 | static int qcom_geni_serial_runtime_suspend(struct device *dev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/qcom_geni_serial_runtime_resume +1876 drivers/tty/serial/qcom_geni_serial.c
1867
> 1868 static int qcom_geni_serial_runtime_suspend(struct device *dev)
1869 {
1870 struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
1871 struct uart_port *uport = &port->uport;
1872
1873 return geni_serial_resources_off(uport);
1874 };
1875
> 1876 static int qcom_geni_serial_runtime_resume(struct device *dev)
1877 {
1878 struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
1879 struct uart_port *uport = &port->uport;
1880
1881 return geni_serial_resources_on(uport);
1882 };
1883
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 9/9] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms
2025-05-02 3:10 [PATCH v3 0/9] Enable QUPs and Serial on SA8255p Qualcomm platforms Praveen Talari
` (7 preceding siblings ...)
2025-05-02 3:10 ` [PATCH v3 8/9] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
@ 2025-05-02 3:10 ` Praveen Talari
2025-05-02 9:24 ` neil.armstrong
8 siblings, 1 reply; 27+ messages in thread
From: Praveen Talari @ 2025-05-02 3:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Praveen Talari,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
The Qualcomm automotive SA8255p SoC relies on firmware to configure
platform resources, including clocks, interconnects and TLMM.
The driver requests resources operations over SCMI using power
and performance protocols.
The SCMI power protocol enables or disables resources like clocks,
interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs,
such as resume/suspend, to control power states(on/off).
The SCMI performance protocol manages UART baud rates, with each baud
rate represented by a performance level. The driver uses the
dev_pm_opp_set_level() API to request the desired baud rate by
specifying the performance level.
Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
---
drivers/tty/serial/qcom_geni_serial.c | 150 +++++++++++++++++++++++---
1 file changed, 135 insertions(+), 15 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 9d698c354510..51036d5c8ea1 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -11,6 +11,7 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -99,10 +100,16 @@
#define DMA_RX_BUF_SIZE 2048
static DEFINE_IDA(port_ida);
+#define DOMAIN_IDX_POWER 0
+#define DOMAIN_IDX_PERF 1
struct qcom_geni_device_data {
bool console;
enum geni_se_xfer_mode mode;
+ struct dev_pm_domain_attach_data pd_data;
+ int (*geni_serial_pwr_rsc_init)(struct uart_port *uport);
+ int (*geni_serial_set_rate)(struct uart_port *uport, unsigned long clk_freq);
+ int (*geni_serial_switch_power_state)(struct uart_port *uport, bool state);
};
struct qcom_geni_private_data {
@@ -140,6 +147,7 @@ struct qcom_geni_serial_port {
struct qcom_geni_private_data private_data;
const struct qcom_geni_device_data *dev_data;
+ struct dev_pm_domain_list *pd_list;
};
static const struct uart_ops qcom_geni_console_pops;
@@ -1331,6 +1339,42 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned long baud)
return 0;
}
+static int geni_serial_set_level(struct uart_port *uport, unsigned long baud)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF];
+
+ /*
+ * The performance protocol sets UART communication
+ * speeds by selecting different performance levels
+ * through the OPP framework.
+ *
+ * Supported perf levels for baudrates in firmware are below
+ * +---------------------+--------------------+
+ * | Perf level value | Baudrate values |
+ * +---------------------+--------------------+
+ * | 300 | 300 |
+ * | 1200 | 1200 |
+ * | 2400 | 2400 |
+ * | 4800 | 4800 |
+ * | 9600 | 9600 |
+ * | 19200 | 19200 |
+ * | 38400 | 38400 |
+ * | 57600 | 57600 |
+ * | 115200 | 115200 |
+ * | 230400 | 230400 |
+ * | 460800 | 460800 |
+ * | 921600 | 921600 |
+ * | 2000000 | 2000000 |
+ * | 3000000 | 3000000 |
+ * | 3200000 | 3200000 |
+ * | 4000000 | 4000000 |
+ * +---------------------+--------------------+
+ */
+
+ return dev_pm_opp_set_level(perf_dev, baud);
+}
+
static void qcom_geni_serial_set_termios(struct uart_port *uport,
struct ktermios *termios,
const struct ktermios *old)
@@ -1349,7 +1393,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
/* baud rate */
baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
- ret = geni_serial_set_rate(uport, baud);
+ ret = port->dev_data->geni_serial_set_rate(uport, baud);
if (ret) {
dev_err(port->se.dev,
"%s: Failed to set baud:%u ret:%d\n",
@@ -1640,8 +1684,27 @@ static int geni_serial_resources_on(struct uart_port *uport)
return 0;
}
-static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
+static int geni_serial_resource_state(struct uart_port *uport, bool power_on)
{
+ return power_on ? geni_serial_resources_on(uport) : geni_serial_resources_off(uport);
+}
+
+static int geni_serial_pwr_init(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ int ret;
+
+ ret = dev_pm_domain_attach_list(port->se.dev,
+ &port->dev_data->pd_data, &port->pd_list);
+ if (ret <= 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int geni_serial_resource_init(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
int ret;
port->se.clk = devm_clk_get(port->se.dev, "se");
@@ -1680,7 +1743,6 @@ static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
static void qcom_geni_serial_pm(struct uart_port *uport,
unsigned int new_state, unsigned int old_state)
{
-
/* If we've never been called, treat it as off */
if (old_state == UART_PM_STATE_UNDEFINED)
old_state = UART_PM_STATE_OFF;
@@ -1774,13 +1836,16 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->se.dev = &pdev->dev;
port->se.wrapper = dev_get_drvdata(pdev->dev.parent);
- ret = geni_serial_resource_init(port);
+ ret = port->dev_data->geni_serial_pwr_rsc_init(uport);
if (ret)
return ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
+ if (!res) {
+ ret = -EINVAL;
+ goto error;
+ }
+
uport->mapbase = res->start;
port->tx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
@@ -1790,19 +1855,26 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (!data->console) {
port->rx_buf = devm_kzalloc(uport->dev,
DMA_RX_BUF_SIZE, GFP_KERNEL);
- if (!port->rx_buf)
- return -ENOMEM;
+ if (!port->rx_buf) {
+ ret = -ENOMEM;
+ goto error;
+ }
}
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
"qcom_geni_serial_%s%d",
uart_console(uport) ? "console" : "uart", uport->line);
- if (!port->name)
- return -ENOMEM;
+ if (!port->name) {
+ ret = -ENOMEM;
+ goto error;
+ }
irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
+ if (irq < 0) {
+ ret = irq;
+ goto error;
+ }
+
uport->irq = irq;
uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
@@ -1824,7 +1896,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
- return ret;
+ goto error;
}
pm_runtime_enable(port->se.dev);
@@ -1849,6 +1921,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
error:
pm_runtime_disable(port->se.dev);
+ dev_pm_domain_detach_list(port->pd_list);
return ret;
}
@@ -1863,22 +1936,31 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
ida_free(&port_ida, uport->line);
pm_runtime_disable(port->se.dev);
uart_remove_one_port(drv, &port->uport);
+ dev_pm_domain_detach_list(port->pd_list);
}
static int qcom_geni_serial_runtime_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
+ int ret = 0;
- return geni_serial_resources_off(uport);
+ if (port->dev_data->geni_serial_switch_power_state)
+ ret = port->dev_data->geni_serial_switch_power_state(uport, false);
+
+ return ret;
};
static int qcom_geni_serial_runtime_resume(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
+ int ret = 0;
+
+ if (port->dev_data->geni_serial_switch_power_state)
+ ret = port->dev_data->geni_serial_switch_power_state(uport, true);
- return geni_serial_resources_on(uport);
+ return ret;
};
static int qcom_geni_serial_suspend(struct device *dev)
@@ -1916,11 +1998,41 @@ static int qcom_geni_serial_resume(struct device *dev)
static const struct qcom_geni_device_data qcom_geni_console_data = {
.console = true,
.mode = GENI_SE_FIFO,
+ .geni_serial_pwr_rsc_init = geni_serial_resource_init,
+ .geni_serial_set_rate = geni_serial_set_rate,
+ .geni_serial_switch_power_state = geni_serial_resource_state,
};
static const struct qcom_geni_device_data qcom_geni_uart_data = {
.console = false,
.mode = GENI_SE_DMA,
+ .geni_serial_pwr_rsc_init = geni_serial_resource_init,
+ .geni_serial_set_rate = geni_serial_set_rate,
+ .geni_serial_switch_power_state = geni_serial_resource_state,
+};
+
+static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = {
+ .console = true,
+ .mode = GENI_SE_FIFO,
+ .pd_data = {
+ .pd_flags = PD_FLAG_DEV_LINK_ON,
+ .pd_names = (const char*[]) { "power", "perf" },
+ .num_pd_names = 2,
+ },
+ .geni_serial_pwr_rsc_init = geni_serial_pwr_init,
+ .geni_serial_set_rate = geni_serial_set_level,
+};
+
+static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = {
+ .console = false,
+ .mode = GENI_SE_DMA,
+ .pd_data = {
+ .pd_flags = PD_FLAG_DEV_LINK_ON,
+ .pd_names = (const char*[]) { "power", "perf" },
+ .num_pd_names = 2,
+ },
+ .geni_serial_pwr_rsc_init = geni_serial_pwr_init,
+ .geni_serial_set_rate = geni_serial_set_level,
};
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
@@ -1934,10 +2046,18 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
.compatible = "qcom,geni-debug-uart",
.data = &qcom_geni_console_data,
},
+ {
+ .compatible = "qcom,sa8255p-geni-debug-uart",
+ .data = &sa8255p_qcom_geni_console_data,
+ },
{
.compatible = "qcom,geni-uart",
.data = &qcom_geni_uart_data,
},
+ {
+ .compatible = "qcom,sa8255p-geni-uart",
+ .data = &sa8255p_qcom_geni_uart_data,
+ },
{}
};
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
--
2.17.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v3 9/9] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms
2025-05-02 3:10 ` [PATCH v3 9/9] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
@ 2025-05-02 9:24 ` neil.armstrong
0 siblings, 0 replies; 27+ messages in thread
From: neil.armstrong @ 2025-05-02 9:24 UTC (permalink / raw)
To: Praveen Talari, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Rafael J. Wysocki,
linux-arm-msm, linux-kernel, linux-serial, devicetree, linux-pm
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_mnaresh, quic_shazhuss
On 02/05/2025 05:10, Praveen Talari wrote:
> The Qualcomm automotive SA8255p SoC relies on firmware to configure
> platform resources, including clocks, interconnects and TLMM.
> The driver requests resources operations over SCMI using power
> and performance protocols.
>
> The SCMI power protocol enables or disables resources like clocks,
> interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs,
> such as resume/suspend, to control power states(on/off).
>
> The SCMI performance protocol manages UART baud rates, with each baud
> rate represented by a performance level. The driver uses the
> dev_pm_opp_set_level() API to request the desired baud rate by
> specifying the performance level.
>
> Signed-off-by: Praveen Talari <quic_ptalari@quicinc.com>
> ---
> drivers/tty/serial/qcom_geni_serial.c | 150 +++++++++++++++++++++++---
> 1 file changed, 135 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
> index 9d698c354510..51036d5c8ea1 100644
> --- a/drivers/tty/serial/qcom_geni_serial.c
> +++ b/drivers/tty/serial/qcom_geni_serial.c
> @@ -11,6 +11,7 @@
> #include <linux/irq.h>
> #include <linux/module.h>
> #include <linux/of.h>
> +#include <linux/pm_domain.h>
> #include <linux/pm_opp.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> @@ -99,10 +100,16 @@
> #define DMA_RX_BUF_SIZE 2048
>
> static DEFINE_IDA(port_ida);
> +#define DOMAIN_IDX_POWER 0
> +#define DOMAIN_IDX_PERF 1
>
> struct qcom_geni_device_data {
> bool console;
> enum geni_se_xfer_mode mode;
> + struct dev_pm_domain_attach_data pd_data;
> + int (*geni_serial_pwr_rsc_init)(struct uart_port *uport);
> + int (*geni_serial_set_rate)(struct uart_port *uport, unsigned long clk_freq);
> + int (*geni_serial_switch_power_state)(struct uart_port *uport, bool state);
The geni_serial_ is not needed here, so not need to use "pwr", just use the
original names:
resources_init
set_rate
power_state
Neil
> };
>
> struct qcom_geni_private_data {
> @@ -140,6 +147,7 @@ struct qcom_geni_serial_port {
>
> struct qcom_geni_private_data private_data;
> const struct qcom_geni_device_data *dev_data;
> + struct dev_pm_domain_list *pd_list;
> };
>
> static const struct uart_ops qcom_geni_console_pops;
> @@ -1331,6 +1339,42 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned long baud)
> return 0;
> }
>
> +static int geni_serial_set_level(struct uart_port *uport, unsigned long baud)
> +{
> + struct qcom_geni_serial_port *port = to_dev_port(uport);
> + struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF];
> +
> + /*
> + * The performance protocol sets UART communication
> + * speeds by selecting different performance levels
> + * through the OPP framework.
> + *
> + * Supported perf levels for baudrates in firmware are below
> + * +---------------------+--------------------+
> + * | Perf level value | Baudrate values |
> + * +---------------------+--------------------+
> + * | 300 | 300 |
> + * | 1200 | 1200 |
> + * | 2400 | 2400 |
> + * | 4800 | 4800 |
> + * | 9600 | 9600 |
> + * | 19200 | 19200 |
> + * | 38400 | 38400 |
> + * | 57600 | 57600 |
> + * | 115200 | 115200 |
> + * | 230400 | 230400 |
> + * | 460800 | 460800 |
> + * | 921600 | 921600 |
> + * | 2000000 | 2000000 |
> + * | 3000000 | 3000000 |
> + * | 3200000 | 3200000 |
> + * | 4000000 | 4000000 |
> + * +---------------------+--------------------+
> + */
> +
> + return dev_pm_opp_set_level(perf_dev, baud);
> +}
> +
> static void qcom_geni_serial_set_termios(struct uart_port *uport,
> struct ktermios *termios,
> const struct ktermios *old)
> @@ -1349,7 +1393,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
> /* baud rate */
> baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
>
> - ret = geni_serial_set_rate(uport, baud);
> + ret = port->dev_data->geni_serial_set_rate(uport, baud);
> if (ret) {
> dev_err(port->se.dev,
> "%s: Failed to set baud:%u ret:%d\n",
> @@ -1640,8 +1684,27 @@ static int geni_serial_resources_on(struct uart_port *uport)
> return 0;
> }
>
> -static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
> +static int geni_serial_resource_state(struct uart_port *uport, bool power_on)
> {
> + return power_on ? geni_serial_resources_on(uport) : geni_serial_resources_off(uport);
> +}
> +
> +static int geni_serial_pwr_init(struct uart_port *uport)
> +{
> + struct qcom_geni_serial_port *port = to_dev_port(uport);
> + int ret;
> +
> + ret = dev_pm_domain_attach_list(port->se.dev,
> + &port->dev_data->pd_data, &port->pd_list);
> + if (ret <= 0)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int geni_serial_resource_init(struct uart_port *uport)
> +{
> + struct qcom_geni_serial_port *port = to_dev_port(uport);
> int ret;
>
> port->se.clk = devm_clk_get(port->se.dev, "se");
> @@ -1680,7 +1743,6 @@ static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
> static void qcom_geni_serial_pm(struct uart_port *uport,
> unsigned int new_state, unsigned int old_state)
> {
> -
> /* If we've never been called, treat it as off */
> if (old_state == UART_PM_STATE_UNDEFINED)
> old_state = UART_PM_STATE_OFF;
> @@ -1774,13 +1836,16 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
> port->se.dev = &pdev->dev;
> port->se.wrapper = dev_get_drvdata(pdev->dev.parent);
>
> - ret = geni_serial_resource_init(port);
> + ret = port->dev_data->geni_serial_pwr_rsc_init(uport);
> if (ret)
> return ret;
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!res)
> - return -EINVAL;
> + if (!res) {
> + ret = -EINVAL;
> + goto error;
> + }
> +
> uport->mapbase = res->start;
>
> port->tx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
> @@ -1790,19 +1855,26 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
> if (!data->console) {
> port->rx_buf = devm_kzalloc(uport->dev,
> DMA_RX_BUF_SIZE, GFP_KERNEL);
> - if (!port->rx_buf)
> - return -ENOMEM;
> + if (!port->rx_buf) {
> + ret = -ENOMEM;
> + goto error;
> + }
> }
>
> port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
> "qcom_geni_serial_%s%d",
> uart_console(uport) ? "console" : "uart", uport->line);
> - if (!port->name)
> - return -ENOMEM;
> + if (!port->name) {
> + ret = -ENOMEM;
> + goto error;
> + }
>
> irq = platform_get_irq(pdev, 0);
> - if (irq < 0)
> - return irq;
> + if (irq < 0) {
> + ret = irq;
> + goto error;
> + }
> +
> uport->irq = irq;
> uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
>
> @@ -1824,7 +1896,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
> IRQF_TRIGGER_HIGH, port->name, uport);
> if (ret) {
> dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
> - return ret;
> + goto error;
> }
>
> pm_runtime_enable(port->se.dev);
> @@ -1849,6 +1921,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
>
> error:
> pm_runtime_disable(port->se.dev);
> + dev_pm_domain_detach_list(port->pd_list);
> return ret;
> }
>
> @@ -1863,22 +1936,31 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
> ida_free(&port_ida, uport->line);
> pm_runtime_disable(port->se.dev);
> uart_remove_one_port(drv, &port->uport);
> + dev_pm_domain_detach_list(port->pd_list);
> }
>
> static int qcom_geni_serial_runtime_suspend(struct device *dev)
> {
> struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
> struct uart_port *uport = &port->uport;
> + int ret = 0;
>
> - return geni_serial_resources_off(uport);
> + if (port->dev_data->geni_serial_switch_power_state)
> + ret = port->dev_data->geni_serial_switch_power_state(uport, false);
> +
> + return ret;
> };
>
> static int qcom_geni_serial_runtime_resume(struct device *dev)
> {
> struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
> struct uart_port *uport = &port->uport;
> + int ret = 0;
> +
> + if (port->dev_data->geni_serial_switch_power_state)
> + ret = port->dev_data->geni_serial_switch_power_state(uport, true);
>
> - return geni_serial_resources_on(uport);
> + return ret;
> };
>
> static int qcom_geni_serial_suspend(struct device *dev)
> @@ -1916,11 +1998,41 @@ static int qcom_geni_serial_resume(struct device *dev)
> static const struct qcom_geni_device_data qcom_geni_console_data = {
> .console = true,
> .mode = GENI_SE_FIFO,
> + .geni_serial_pwr_rsc_init = geni_serial_resource_init,
> + .geni_serial_set_rate = geni_serial_set_rate,
> + .geni_serial_switch_power_state = geni_serial_resource_state,
> };
>
> static const struct qcom_geni_device_data qcom_geni_uart_data = {
> .console = false,
> .mode = GENI_SE_DMA,
> + .geni_serial_pwr_rsc_init = geni_serial_resource_init,
> + .geni_serial_set_rate = geni_serial_set_rate,
> + .geni_serial_switch_power_state = geni_serial_resource_state,
> +};
> +
> +static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = {
> + .console = true,
> + .mode = GENI_SE_FIFO,
> + .pd_data = {
> + .pd_flags = PD_FLAG_DEV_LINK_ON,
> + .pd_names = (const char*[]) { "power", "perf" },
> + .num_pd_names = 2,
> + },
> + .geni_serial_pwr_rsc_init = geni_serial_pwr_init,
> + .geni_serial_set_rate = geni_serial_set_level,
> +};
> +
> +static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = {
> + .console = false,
> + .mode = GENI_SE_DMA,
> + .pd_data = {
> + .pd_flags = PD_FLAG_DEV_LINK_ON,
> + .pd_names = (const char*[]) { "power", "perf" },
> + .num_pd_names = 2,
> + },
> + .geni_serial_pwr_rsc_init = geni_serial_pwr_init,
> + .geni_serial_set_rate = geni_serial_set_level,
> };
>
> static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
> @@ -1934,10 +2046,18 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
> .compatible = "qcom,geni-debug-uart",
> .data = &qcom_geni_console_data,
> },
> + {
> + .compatible = "qcom,sa8255p-geni-debug-uart",
> + .data = &sa8255p_qcom_geni_console_data,
> + },
> {
> .compatible = "qcom,geni-uart",
> .data = &qcom_geni_uart_data,
> },
> + {
> + .compatible = "qcom,sa8255p-geni-uart",
> + .data = &sa8255p_qcom_geni_uart_data,
> + },
> {}
> };
> MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
^ permalink raw reply [flat|nested] 27+ messages in thread