This is a couple of fixes and clean-ups to use preferred CPU accessors
rather than directly parsing DT "reg" properties. It's part of a larger
effort to remove open coded parsing of "reg". The existing code is
fragile depending on the CPU architecture details and is wrong for
arm64 (though the dts files are also wrong).
Compile tested only.
Signed-off-by: Rob Herring <[email protected]>
---
Changes in v2:
- Add patch 4 previously posted here:
https://lore.kernel.org/all/[email protected]/
- Rebase on v6.4-rc1
- Link to v1: https://lore.kernel.org/r/[email protected]
---
Rob Herring (4):
MAINTAINERS: Add Marvell mvebu clock drivers
clk: mvebu: Use of_get_cpu_hwid() to read CPU ID
clk: mvebu: Iterate over possible CPUs instead of DT CPU nodes
clk: mvebu: Use of_address_to_resource()
MAINTAINERS | 1 +
drivers/clk/mvebu/ap-cpu-clk.c | 16 ++++++++--------
drivers/clk/mvebu/armada_ap_cp_helper.c | 8 +++-----
drivers/clk/mvebu/clk-cpu.c | 14 +++-----------
4 files changed, 15 insertions(+), 24 deletions(-)
---
base-commit: ac9a78681b921877518763ba0e89202254349d1b
change-id: 20230327-mvebu-clk-fixes-f4a1365fa0b7
Best regards,
--
Rob Herring <[email protected]>
Rework iterating over DT CPU nodes to iterate over possible CPUs
instead. There's no need to walk the DT CPU nodes again. Possible CPUs
is equal to the number of CPUs defined in the DT. Using the "reg" value
for an array index is fragile as it assumes "reg" is 0-N which often is
not the case.
Signed-off-by: Rob Herring <[email protected]>
---
drivers/clk/mvebu/clk-cpu.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index c2af3395cf13..db2b38c21304 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -168,8 +168,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
struct cpu_clk *cpuclk;
void __iomem *clock_complex_base = of_iomap(node, 0);
void __iomem *pmu_dfs_base = of_iomap(node, 1);
- int ncpus = 0;
- struct device_node *dn;
+ int ncpus = num_possible_cpus();
+ int cpu;
if (clock_complex_base == NULL) {
pr_err("%s: clock-complex base register not set\n",
@@ -181,9 +181,6 @@ static void __init of_cpu_clk_setup(struct device_node *node)
pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
__func__);
- for_each_of_cpu_node(dn)
- ncpus++;
-
cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL);
if (WARN_ON(!cpuclk))
goto cpuclk_out;
@@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node)
if (WARN_ON(!clks))
goto clks_out;
- for_each_of_cpu_node(dn) {
+ for_each_possible_cpu(cpu) {
struct clk_init_data init;
struct clk *clk;
char *clk_name = kzalloc(5, GFP_KERNEL);
- int cpu, err;
if (WARN_ON(!clk_name))
goto bail_out;
- err = of_property_read_u32(dn, "reg", &cpu);
- if (WARN_ON(err))
- goto bail_out;
-
sprintf(clk_name, "cpu%d", cpu);
cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
--
2.39.2
Replace of_get_property() and of_translate_address() calls with a single
call to of_address_to_resource().
Signed-off-by: Rob Herring <[email protected]>
---
drivers/clk/mvebu/armada_ap_cp_helper.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.c b/drivers/clk/mvebu/armada_ap_cp_helper.c
index 6a930f697ee5..e7005de66327 100644
--- a/drivers/clk/mvebu/armada_ap_cp_helper.c
+++ b/drivers/clk/mvebu/armada_ap_cp_helper.c
@@ -16,15 +16,13 @@
char *ap_cp_unique_name(struct device *dev, struct device_node *np,
const char *name)
{
- const __be32 *reg;
- u64 addr;
+ struct resource res;
/* Do not create a name if there is no clock */
if (!name)
return NULL;
- reg = of_get_property(np, "reg", NULL);
- addr = of_translate_address(np, reg);
+ of_address_to_resource(np, 0, &res);
return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
- (unsigned long long)addr, name);
+ (unsigned long long)res.start, name);
}
--
2.39.2
Use of_get_cpu_hwid() rather than the open coded reading of the CPU
nodes "reg" property. The existing code is in fact wrong as the "reg"
address cells size is 2 cells for arm64. The existing code happens to
work because the DTS files are wrong as well.
Signed-off-by: Rob Herring <[email protected]>
---
If the DTS files are fixed, then they will not work with the
existing code. This change should work for both existing and fixed DTS
files.
Therefore, this should be marked for stable so that if/when the DTS
files are fixed, then at least stable kernels will work. This is
untested, so I didn't mark for stable.
---
drivers/clk/mvebu/ap-cpu-clk.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c
index 71bdd7c3ff03..d8a7a4c90d54 100644
--- a/drivers/clk/mvebu/ap-cpu-clk.c
+++ b/drivers/clk/mvebu/ap-cpu-clk.c
@@ -253,12 +253,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
*/
nclusters = 1;
for_each_of_cpu_node(dn) {
- int cpu, err;
+ u64 cpu;
- err = of_property_read_u32(dn, "reg", &cpu);
- if (WARN_ON(err)) {
+ cpu = of_get_cpu_hwid(dn, 0);
+ if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn);
- return err;
+ return -EINVAL;
}
/* If cpu2 or cpu3 is enabled */
@@ -288,12 +288,12 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
struct clk_init_data init;
const char *parent_name;
struct clk *parent;
- int cpu, err;
+ u64 cpu;
- err = of_property_read_u32(dn, "reg", &cpu);
- if (WARN_ON(err)) {
+ cpu = of_get_cpu_hwid(dn, 0);
+ if (WARN_ON(cpu == OF_BAD_ADDR)) {
of_node_put(dn);
- return err;
+ return -EINVAL;
}
cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
--
2.39.2
Quoting Rob Herring (2023-06-09 11:13:46)
> Use of_get_cpu_hwid() rather than the open coded reading of the CPU
> nodes "reg" property. The existing code is in fact wrong as the "reg"
> address cells size is 2 cells for arm64. The existing code happens to
> work because the DTS files are wrong as well.
>
> Signed-off-by: Rob Herring <[email protected]>
> ---
Applied to clk-next
Quoting Rob Herring (2023-06-09 11:13:47)
> Rework iterating over DT CPU nodes to iterate over possible CPUs
> instead. There's no need to walk the DT CPU nodes again. Possible CPUs
> is equal to the number of CPUs defined in the DT. Using the "reg" value
> for an array index is fragile as it assumes "reg" is 0-N which often is
> not the case.
>
> Signed-off-by: Rob Herring <[email protected]>
> ---
Applied to clk-next
Le 09/06/2023 à 20:13, Rob Herring a écrit :
> Rework iterating over DT CPU nodes to iterate over possible CPUs
> instead. There's no need to walk the DT CPU nodes again. Possible CPUs
> is equal to the number of CPUs defined in the DT. Using the "reg" value
> for an array index is fragile as it assumes "reg" is 0-N which often is
> not the case.
Hi,
just for the records, this also fixes 2 bugs that were reported as patch
1 and 2 at [1].
Nice :)
Part of patch 1 could still have some interest in order to remove the
hard-coded 5 in the kzalloc().
Patch 3 and 4 are mostly useless.
Feel free to check/apply them if it makes sense to you.
Personaly, I won't bother resending them, unless explicitly requested.
CJ
[1]:
https://lore.kernel.org/all/[email protected]/
>
> Signed-off-by: Rob Herring <[email protected]>
> ---
> drivers/clk/mvebu/clk-cpu.c | 14 +++-----------
> 1 file changed, 3 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
> index c2af3395cf13..db2b38c21304 100644
> --- a/drivers/clk/mvebu/clk-cpu.c
> +++ b/drivers/clk/mvebu/clk-cpu.c
> @@ -168,8 +168,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
> struct cpu_clk *cpuclk;
> void __iomem *clock_complex_base = of_iomap(node, 0);
> void __iomem *pmu_dfs_base = of_iomap(node, 1);
> - int ncpus = 0;
> - struct device_node *dn;
> + int ncpus = num_possible_cpus();
> + int cpu;
>
> if (clock_complex_base == NULL) {
> pr_err("%s: clock-complex base register not set\n",
> @@ -181,9 +181,6 @@ static void __init of_cpu_clk_setup(struct device_node *node)
> pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
> __func__);
>
> - for_each_of_cpu_node(dn)
> - ncpus++;
> -
> cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL);
> if (WARN_ON(!cpuclk))
> goto cpuclk_out;
> @@ -192,19 +189,14 @@ static void __init of_cpu_clk_setup(struct device_node *node)
> if (WARN_ON(!clks))
> goto clks_out;
>
> - for_each_of_cpu_node(dn) {
> + for_each_possible_cpu(cpu) {
> struct clk_init_data init;
> struct clk *clk;
> char *clk_name = kzalloc(5, GFP_KERNEL);
> - int cpu, err;
>
> if (WARN_ON(!clk_name))
> goto bail_out;
>
> - err = of_property_read_u32(dn, "reg", &cpu);
> - if (WARN_ON(err))
> - goto bail_out;
> -
> sprintf(clk_name, "cpu%d", cpu);
>
> cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
>