2013-07-17 14:10:30

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 00/15] DT/core: update cpu device of_node

From: Sudeep KarkadaNagesha <[email protected]>

As more and more information is getting added into the cpu node, the number
of drivers needing to parse the device tree for CPU nodes are increasing.
Most of the time, the information needed from the cpu node is preferred
in the logical CPU order. Hence many drivers first parse and search the
CPU node, match them to logical index if needed and then search for the
required property inside a particular cpu node. Some of them assume the
logical and physical CPU ordering to be same which is incorrect.

This patch series initialises the of_node in all the cpu devices when
registering the CPU device.
1. This avoids different drivers having to parse the cpu nodes to obtain
different attributes like operating points, latency,...etc.
2. This handles different physical and logical cpu ordering which is not
the case in current code.
3. Also all the cpu nodes will have their of_node initialised correctly.
Currently different drivers assign them partially and incorrectly.
4. Removes all the reduntant parsing in various drivers.

Changes v1->v2:
1. Moved most of arch_of_get_cpu_node to OF/DT core as of_get_cpu_node
adding a provision for architecture specific hooks for matching
logical and physical ids.
2. Extended removal of DT cpu node parsing to PPC cpufreq drivers
3. Added Acks from Viresh and Shawn

Regards,
Sudeep

Sudeep KarkadaNagesha (15):
of: add support for retrieving cpu node for a given logical cpu index
driver/core: cpu: initialize of_node in cpu's device struture
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
ARM: mvebu: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

arch/arm/kernel/devtree.c | 5 +++
arch/arm/kernel/topology.c | 61 +++++++++++-----------------------
arch/arm/mach-imx/mach-imx6q.c | 3 +-
arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++---------------
drivers/base/cpu.c | 2 ++
drivers/bus/arm-cci.c | 28 ++++------------
drivers/cpufreq/arm_big_little_dt.c | 39 ++++++++++------------
drivers/cpufreq/cpufreq-cpu0.c | 23 +++----------
drivers/cpufreq/highbank-cpufreq.c | 18 ++++------
drivers/cpufreq/imx6q-cpufreq.c | 4 +--
drivers/cpufreq/kirkwood-cpufreq.c | 14 ++++++--
drivers/cpufreq/maple-cpufreq.c | 23 ++++---------
drivers/cpufreq/pmac32-cpufreq.c | 11 ++++++-
drivers/cpufreq/pmac64-cpufreq.c | 54 ++++++++++--------------------
drivers/cpufreq/spear-cpufreq.c | 10 +++++-
drivers/of/base.c | 66 +++++++++++++++++++++++++++++++++++++
include/linux/of.h | 5 +++
17 files changed, 213 insertions(+), 205 deletions(-)

--
1.8.1.2


2013-07-17 14:06:50

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 10/15] cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Deepak Sikri <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/spear-cpufreq.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index c3efa7f..eb73c47 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/clk.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -218,12 +219,19 @@ static struct cpufreq_driver spear_cpufreq_driver = {
static int spear_cpufreq_driver_init(void)
{
struct device_node *np;
+ struct device *cpu_dev;
const struct property *prop;
struct cpufreq_frequency_table *freq_tbl;
const __be32 *val;
int cnt, i, ret;

- np = of_find_node_by_path("/cpus/cpu@0");
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device\n");
+ return -ENODEV;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("No cpu node found");
return -ENODEV;
--
1.8.1.2

2013-07-17 14:06:57

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 15/15] cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes DT parsing and uses cpu->of_node instead.

Cc: Viresh Kumar <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac32-cpufreq.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 3104fad..b6822ee 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/adb.h>
#include <linux/pmu.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/device.h>
@@ -643,6 +644,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
*/
static int __init pmac_cpufreq_setup(void)
{
+ struct device *cpu_dev;
struct device_node *cpunode;
const u32 *value;

@@ -650,7 +652,14 @@ static int __init pmac_cpufreq_setup(void)
return 0;

/* Assume only one CPU */
- cpunode = of_find_node_by_type(NULL, "cpu");
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device\n");
+ return -ENODEV;
+ }
+
+ /* Get first CPU node */
+ cpunode = of_node_get(cpu_dev->of_node);
if (!cpunode)
goto out;

--
1.8.1.2

2013-07-17 14:07:26

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 14/15] cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Viresh Kumar <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac64-cpufreq.c | 54 ++++++++++++++--------------------------
1 file changed, 18 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 7ba4234..b60ccea 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/completion.h>
@@ -383,9 +384,8 @@ static struct cpufreq_driver g5_cpufreq_driver = {

#ifdef CONFIG_PMAC_SMU

-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
+static int __init g5_neo2_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpunode;
unsigned int psize, ssize;
unsigned long max_freq;
char *freq_method, *volt_method;
@@ -405,20 +405,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
else
return -ENODEV;

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- return -ENODEV;
- }
-
/* Check 970FX for now */
valp = of_get_property(cpunode, "cpu-version", NULL);
if (!valp) {
@@ -537,9 +523,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
#endif /* CONFIG_PMAC_SMU */


-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
+static int __init g5_pm72_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
+ struct device_node *cpuid = NULL, *hwclock = NULL;
const u8 *eeprom = NULL;
const u32 *valp;
u64 max_freq, min_freq, ih, il;
@@ -548,17 +534,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
" RackMac3,1...\n");

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
- return -ENODEV;
- }
-
/* Lookup the cpuid eeprom node */
cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
if (cpuid != NULL)
@@ -718,25 +693,32 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)

static int __init g5_cpufreq_init(void)
{
- struct device_node *cpus;
+ struct device *cpu_dev;
+ struct device_node *cpunode;
int rc = 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device\n");
+ return -ENODEV;
+ }
+
+ /* Get first CPU node */
+ cpunode = of_node_get(cpu_dev->of_node);
+ if (cpunode == NULL) {
+ pr_err("cpufreq: Can't find any CPU node\n");
return -ENODEV;
}

if (of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3") ||
of_machine_is_compatible("RackMac3,1"))
- rc = g5_pm72_cpufreq_init(cpus);
+ rc = g5_pm72_cpufreq_init(cpunode);
#ifdef CONFIG_PMAC_SMU
else
- rc = g5_neo2_cpufreq_init(cpus);
+ rc = g5_neo2_cpufreq_init(cpunode);
#endif /* CONFIG_PMAC_SMU */

- of_node_put(cpus);
return rc;
}

--
1.8.1.2

2013-07-17 14:06:48

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Andrew Lunn <[email protected]>
Cc: Jason Cooper <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/kirkwood-cpufreq.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index c233ea6..18aa3eb 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -165,6 +166,7 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = {
static int kirkwood_cpufreq_probe(struct platform_device *pdev)
{
struct device_node *np;
+ struct device *cpu_dev;
struct resource *res;
int err;

@@ -175,9 +177,17 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
if (IS_ERR(priv.base))
return PTR_ERR(priv.base);

- np = of_find_node_by_path("/cpus/cpu@0");
- if (!np)
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ dev_err(&pdev->dev, "failed to get cpu device\n");
return -ENODEV;
+ }
+
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ dev_err(&pdev->dev, "failed to get cpu device node\n");
+ return -ENODEV;
+ }

priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
if (IS_ERR(priv.cpu_clk)) {
--
1.8.1.2

2013-07-17 14:07:58

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 13/15] cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Viresh Kumar <[email protected]>
Cc: Dmitry Eremin-Solenikov <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/maple-cpufreq.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c
index cdd6291..bc7233b 100644
--- a/drivers/cpufreq/maple-cpufreq.c
+++ b/drivers/cpufreq/maple-cpufreq.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/completion.h>
@@ -201,7 +202,7 @@ static struct cpufreq_driver maple_cpufreq_driver = {

static int __init maple_cpufreq_init(void)
{
- struct device_node *cpus;
+ struct device *cpu_dev;
struct device_node *cpunode;
unsigned int psize;
unsigned long max_freq;
@@ -217,24 +218,17 @@ static int __init maple_cpufreq_init(void)
!of_machine_is_compatible("Momentum,Apache"))
return 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device\n");
return -ENODEV;
}

/* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
+ cpunode = of_node_get(cpu_dev->of_node);
if (cpunode == NULL) {
printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- goto bail_cpus;
+ goto bail_noprops;
}

/* Check 970FX for now */
@@ -290,14 +284,11 @@ static int __init maple_cpufreq_init(void)
rc = cpufreq_register_driver(&maple_cpufreq_driver);

of_node_put(cpunode);
- of_node_put(cpus);

return rc;

bail_noprops:
of_node_put(cpunode);
-bail_cpus:
- of_node_put(cpus);

return rc;
}
--
1.8.1.2

2013-07-17 14:08:17

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 12/15] cpufreq: arm_big_little: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/arm_big_little_dt.c | 39 ++++++++++++++++---------------------
1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c
index fd9e3ea..d2648d1 100644
--- a/drivers/cpufreq/arm_big_little_dt.c
+++ b/drivers/cpufreq/arm_big_little_dt.c
@@ -34,27 +34,19 @@
/* get cpu node with valid operating-points */
static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
- struct device_node *np = NULL, *parent;
- int count = 0;
+ struct device *cpu_dev = get_cpu_device(cpu);
+ struct device_node *np;

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
+ if (!cpu_dev) {
+ pr_err("failed to get cpu device\n");
return NULL;
}
-
- for_each_child_of_node(parent, np) {
- if (count++ != cpu)
- continue;
- if (!of_get_property(np, "operating-points", NULL)) {
- of_node_put(np);
- np = NULL;
- }
-
- break;
+ np = of_node_get(cpu_dev->of_node);
+ if (!of_get_property(np, "operating-points", NULL)) {
+ of_node_put(np);
+ np = NULL;
}

- of_node_put(parent);
return np;
}

@@ -63,11 +55,12 @@ static int dt_init_opp_table(struct device *cpu_dev)
struct device_node *np;
int ret;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
- return -ENODATA;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find cpu%d node\n", cpu_dev->id);
+ return -ENOENT;
+ }

- cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
of_node_put(np);

@@ -79,9 +72,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
struct device_node *np;
u32 transition_latency = CPUFREQ_ETERNAL;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
+ }

of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);
--
1.8.1.2

2013-07-17 14:06:47

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 09/15] cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Mark Langsdorf <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/highbank-cpufreq.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
index b61b5a3..794123f 100644
--- a/drivers/cpufreq/highbank-cpufreq.c
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void)
if (!of_machine_is_compatible("calxeda,highbank"))
return -ENODEV;

- for_each_child_of_node(of_find_node_by_path("/cpus"), np)
- if (of_get_property(np, "operating-points", NULL))
- break;
-
- if (!np) {
- pr_err("failed to find highbank cpufreq node\n");
- return -ENOENT;
- }
-
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
pr_err("failed to get highbank cpufreq device\n");
- ret = -ENODEV;
- goto out_put_node;
+ return -ENODEV;
}

- cpu_dev->of_node = np;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find highbank cpufreq node\n");
+ return -ENOENT;
+ }

cpu_clk = clk_get(cpu_dev, NULL);
if (IS_ERR(cpu_clk)) {
--
1.8.1.2

2013-07-17 14:06:44

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 04/15] ARM: topology: remove hwid/MPIDR dependency from cpu_capacity

From: Sudeep KarkadaNagesha <[email protected]>

Currently the topology code computes cpu capacity and stores it in
the list along with hwid(which is MPIDR) as it parses the CPU nodes
in the device tree. This is required as it needs to be mapped to the
logical CPU later.

Since the CPU device nodes can be retrieved in the logical ordering
using DT/OF helpers, its possible to store cpu_capacity also in logical
ordering and avoid storing hwid for each entry.

This patch removes hwid by making use of of_get_cpu_node.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/topology.c | 61 +++++++++++++++-------------------------------
1 file changed, 19 insertions(+), 42 deletions(-)

diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index c5a5954..28ef27a 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
{NULL, },
};

-struct cpu_capacity {
- unsigned long hwid;
- unsigned long capacity;
-};
-
-struct cpu_capacity *cpu_capacity;
+unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu) __cpu_capacity[cpu]

unsigned long middle_capacity = 1;

@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
unsigned long capacity = 0;
int alloc_size, cpu = 0;

- alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
- cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
+ alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
+ __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);

- while ((cn = of_find_node_by_type(cn, "cpu"))) {
- const u32 *rate, *reg;
+ for_each_possible_cpu(cpu) {
+ const u32 *rate;
int len;

- if (cpu >= num_possible_cpus())
- break;
+ /* too early to use cpu->of_node */
+ cn = of_get_cpu_node(cpu);
+ if (!cn) {
+ pr_err("missing device node for CPU %d\n", cpu);
+ continue;
+ }

for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
if (of_device_is_compatible(cn, cpu_eff->compatible))
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
continue;
}

- reg = of_get_property(cn, "reg", &len);
- if (!reg || len != 4) {
- pr_err("%s missing reg property\n", cn->full_name);
- continue;
- }
-
capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;

/* Save min capacity of the system */
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
if (capacity > max_capacity)
max_capacity = capacity;

- cpu_capacity[cpu].capacity = capacity;
- cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
+ cpu_capacity(cpu) = capacity;
}

- if (cpu < num_possible_cpus())
- cpu_capacity[cpu].hwid = (unsigned long)(-1);
-
/* If min and max capacities are equals, we bypass the update of the
* cpu_scale because all CPUs have the same capacity. Otherwise, we
* compute a middle_capacity factor that will ensure that the capacity
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
* SCHED_POWER_SCALE, which is the default value, but with the
* constraint explained near table_efficiency[].
*/
- if (min_capacity == max_capacity)
- cpu_capacity[0].hwid = (unsigned long)(-1);
- else if (4*max_capacity < (3*(max_capacity + min_capacity)))
+ if (4*max_capacity < (3*(max_capacity + min_capacity)))
middle_capacity = (min_capacity + max_capacity)
>> (SCHED_POWER_SHIFT+1);
else
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
* boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
* function returns directly for SMP system.
*/
-void update_cpu_power(unsigned int cpu, unsigned long hwid)
+void update_cpu_power(unsigned int cpu)
{
- unsigned int idx = 0;
-
- /* look for the cpu's hwid in the cpu capacity table */
- for (idx = 0; idx < num_possible_cpus(); idx++) {
- if (cpu_capacity[idx].hwid == hwid)
- break;
-
- if (cpu_capacity[idx].hwid == -1)
- return;
- }
-
- if (idx == num_possible_cpus())
+ if (!cpu_capacity(cpu))
return;

- set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
+ set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);

printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
cpu, arch_scale_freq_power(NULL, cpu));
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)

#else
static inline void parse_dt_topology(void) {}
-static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
+static inline void update_cpu_power(unsigned int cpuid) {}
#endif

/*
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)

update_siblings_masks(cpuid);

- update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
+ update_cpu_power(cpuid);

printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
cpuid, cpu_topology[cpuid].thread_id,
--
1.8.1.2

2013-07-17 14:08:57

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 08/15] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/cpufreq-cpu0.c | 23 ++++-------------------
1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index ad1fde2..5b05c26 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {

static int cpu0_cpufreq_probe(struct platform_device *pdev)
{
- struct device_node *np, *parent;
+ struct device_node *np;
int ret;

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
- return -ENOENT;
- }
-
- for_each_child_of_node(parent, np) {
- if (of_get_property(np, "operating-points", NULL))
- break;
- }
+ cpu_dev = &pdev->dev;

+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("failed to find cpu0 node\n");
- ret = -ENOENT;
- goto out_put_parent;
+ return -ENOENT;
}

- cpu_dev = &pdev->dev;
- cpu_dev->of_node = np;
-
cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
@@ -269,15 +257,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
}

of_node_put(np);
- of_node_put(parent);
return 0;

out_free_table:
opp_free_cpufreq_table(cpu_dev, &freq_table);
out_put_node:
of_node_put(np);
-out_put_parent:
- of_node_put(parent);
return ret;
}

--
1.8.1.2

2013-07-17 14:06:43

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 03/15] ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id

From: Sudeep KarkadaNagesha <[email protected]>

OF/DT core library now provides architecture specific hook to match the
logical cpu index with the corresponding physical identifier. Most of the
cpu DT node parsing and initialisation is contained in devtree.c. So it's
better to define ARM specific arch_match_cpu_phys_id there.

This mainly helps to avoid replication of the code doing CPU node parsing
and physical(MPIDR) to logical mapping.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/devtree.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 5859c8b..5a36f32 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
}
}

+int arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
+}
+
/**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt_phys: physical address of dt blob
--
1.8.1.2

2013-07-17 14:09:30

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 07/15] cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-imx/mach-imx6q.c | 3 +--
drivers/cpufreq/imx6q-cpufreq.c | 4 +---
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 7be13f8..a02f275 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev)
{
struct device_node *np;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_warn("failed to find cpu0 node\n");
return;
}

- cpu_dev->of_node = np;
if (of_init_opp_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index e37cdae..b16632b 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -221,14 +221,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)

cpu_dev = &pdev->dev;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
dev_err(cpu_dev, "failed to find cpu0 node\n");
return -ENOENT;
}

- cpu_dev->of_node = np;
-
arm_clk = devm_clk_get(cpu_dev, "arm");
pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
--
1.8.1.2

2013-07-17 14:09:29

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 06/15] drivers/bus: arm-cci: avoid parsing DT for cpu device nodes

From: Sudeep KarkadaNagesha <[email protected]>

Since the CPU device nodes can be retrieved using arch_of_get_cpu_node,
we can use it to avoid parsing the cpus node searching the cpu nodes and
mapping to logical index.

This patch removes parsing DT for cpu nodes by using of_get_cpu_node.

Cc: Lorenzo Pieralisi <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/bus/arm-cci.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 7332889..7dd891c 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);

static void __init cci_ace_init_ports(void)
{
- int port, ac, cpu;
- u64 hwid;
- const u32 *cell;
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (WARN(!cpus, "Missing cpus node, bailing out\n"))
- return;
-
- if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
- ac = of_n_addr_cells(cpus);
+ int port, cpu;
+ struct device_node *cpun;

/*
* Port index look-up speeds up the function disabling ports by CPU,
@@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
* The stashed index array is initialized for all possible CPUs
* at probe time.
*/
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
- cell = of_get_property(cpun, "reg", NULL);
- if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
- continue;
-
- hwid = of_read_number(cell, ac);
- cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
+ for_each_possible_cpu(cpu) {
+ /* too early to use cpu->of_node */
+ cpun = of_get_cpu_node(cpu);

- if (cpu < 0 || !cpu_possible(cpu))
+ if (WARN(!cpun, "Missing cpu device node\n"))
continue;
+
port = __cci_ace_get_port(cpun, ACE_PORT);
if (port < 0)
continue;
--
1.8.1.2

2013-07-17 14:10:04

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 05/15] ARM: mvebu: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Currently set_secondary_cpus_clock assume the CPU logical ordering
and the MPDIR in DT are same, which is incorrect.

Since the CPU device nodes can be retrieved in the logical ordering
using the DT helper, we can remove the devices tree parsing.

This patch removes DT parsing by making use of of_get_cpu_node.

Cc: Gregory Clement <[email protected]>
Cc: Andrew Lunn <[email protected]>
Cc: Jason Cooper <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index 93f2f3a..12585ad 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -23,51 +23,47 @@
#include <linux/of.h>
#include <linux/mbus.h>
#include <asm/cacheflush.h>
+#include <asm/prom.h>
#include <asm/smp_plat.h>
#include "common.h"
#include "armada-370-xp.h"
#include "pmsu.h"
#include "coherency.h"

+static struct clk *__init get_cpu_clk(int cpu)
+{
+ struct clk *cpu_clk;
+ struct device_node *np = of_get_cpu_node(cpu);
+
+ if (WARN(!np, "missing cpu node\n"))
+ return NULL;
+ cpu_clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(cpu_clk)))
+ return NULL;
+ return cpu_clk;
+}
+
void __init set_secondary_cpus_clock(void)
{
- int thiscpu;
+ int thiscpu, cpu;
unsigned long rate;
- struct clk *cpu_clk = NULL;
- struct device_node *np = NULL;
+ struct clk *cpu_clk;

thiscpu = smp_processor_id();
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
- return;
-
- if (cpu == thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- break;
- }
- }
- if (WARN_ON(IS_ERR(cpu_clk)))
+ cpu_clk = get_cpu_clk(thiscpu);
+ if (!cpu_clk)
return;
clk_prepare_enable(cpu_clk);
rate = clk_get_rate(cpu_clk);

/* set all the other CPU clk to the same rate than the boot CPU */
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
+ for_each_possible_cpu(cpu) {
+ if (cpu == thiscpu)
+ continue;
+ cpu_clk = get_cpu_clk(cpu);
+ if (!cpu_clk)
return;
-
- if (cpu != thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- clk_set_rate(cpu_clk, rate);
- }
+ clk_set_rate(cpu_clk, rate);
}
}

--
1.8.1.2

2013-07-17 14:10:32

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 02/15] driver/core: cpu: initialize of_node in cpu's device struture

From: Sudeep KarkadaNagesha <[email protected]>

CPUs are also registered as devices but the of_node in these cpu
devices are not initialized. Currently different drivers requiring
to access cpu device node are parsing the nodes themselves and
initialising the of_node in cpu device.

The of_node in all the cpu devices needs to be initialized properly
and at one place. The best place to update this is CPU subsystem
driver when registering the cpu devices.

The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
device node for a given logical index by abstracting the architecture
specific details.

This patch uses of_get_cpu_node to assign of_node when registering the
cpu devices.

Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/base/cpu.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index a16d20e..c0f7a08 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/acpi.h>
+#include <linux/of.h>

#include "base.h"

@@ -289,6 +290,7 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
+ cpu->dev.of_node = of_get_cpu_node(num);
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent;
#endif
--
1.8.1.2

2013-07-17 14:10:28

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 01/15] of: add support for retrieving cpu node for a given logical cpu index

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

This patch adds of_get_cpu_node to retrieve a cpu device node for a
given logical cpu index. The default matching of the physical id to the
logical cpu index can be overridden by architecture specific code.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Cc: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/of/base.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of.h | 5 +++++
2 files changed, 71 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..363b8f9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -230,6 +230,72 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical index of a cpu
+ * @phys_id: physical identifier of a cpu
+ *
+ * CPU logical to physical index mapping is architecure specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index.
+ *
+ * Returns 1 if the physical identifier and the logical index correspond
+ * to the same cpu, 0 otherwise.
+ */
+int __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to intialise the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecure specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu)
+{
+ struct device_node *cpun, *cpus;
+ const u32 *cell;
+ u64 hwid;
+ int ac, prop_len;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (WARN(!cpus, "Missing cpus node, bailing out\n"))
+ return NULL;
+
+ if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
+ ac = of_n_addr_cells(cpus);
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+ cell = of_get_property(cpun, "reg", &prop_len);
+ if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
+ continue;
+
+ while (prop_len) {
+ hwid = of_read_number(cell, ac);
+ prop_len -= ac;
+ if (arch_match_cpu_phys_id(cpu, hwid))
+ return cpun;
+ }
+ }
+
+ return NULL;
+}
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..150b48e 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -458,6 +459,10 @@ static inline const void *of_get_property(const struct device_node *node,
{
return NULL;
}
+static inline struct device_node *of_get_cpu_node(int cpu)
+{
+ return NULL;
+}

static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
--
1.8.1.2

2013-07-17 14:30:42

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [RFC PATCH v2 01/15] of: add support for retrieving cpu node for a given logical cpu index

On Wed, 17 Jul 2013, [email protected] wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> This patch adds of_get_cpu_node to retrieve a cpu device node for a
> given logical cpu index. The default matching of the physical id to the
> logical cpu index can be overridden by architecture specific code.
>
> It is recommended to use these helper function only in pre-SMP/early
> initialisation stages to retrieve CPU device node pointers in logical
> ordering. Once the cpu devices are registered, it can be retrieved easily
> from cpu device of_node which avoids unnecessary parsing and matching.
>
> Cc: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/of/base.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of.h | 5 +++++
> 2 files changed, 71 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 5c54279..363b8f9 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -230,6 +230,72 @@ const void *of_get_property(const struct device_node *np, const char *name,
> }
> EXPORT_SYMBOL(of_get_property);
>
> +/*
> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
> + *
> + * @cpu: logical index of a cpu
> + * @phys_id: physical identifier of a cpu
> + *
> + * CPU logical to physical index mapping is architecure specific.

Typo.

> + * However this __weak function provides a default match of physical
> + * id to logical cpu index.
> + *
> + * Returns 1 if the physical identifier and the logical index correspond
> + * to the same cpu, 0 otherwise.
> + */
> +int __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)

Please use a bool return type, and use true/false rather than 1/0 in the
comment.

> +{
> + return (u32)phys_id == cpu;
> +}
> +
> +/**
> + * of_get_cpu_node - Get device node associated with the given logical CPU
> + *
> + * @cpu: CPU number(logical index) for which device node is required
> + *
> + * The main purpose of this function is to retrieve the device node for the
> + * given logical CPU index. It should be used to intialise the of_node in

Typo.

> + * cpu device. Once of_node in cpu device is populated, all the further
> + * references can use that instead.
> + *
> + * CPU logical to physical index mapping is architecure specific and is built

Typo.

> + * before booting secondary cores. This function uses arch_match_cpu_phys_id
> + * which can be overridden by architecture specific implementation.
> + *
> + * Returns a node pointer for the logical cpu if found, else NULL.
> + */
> +struct device_node *of_get_cpu_node(int cpu)
> +{
> + struct device_node *cpun, *cpus;
> + const u32 *cell;
> + u64 hwid;
> + int ac, prop_len;
> +
> + cpus = of_find_node_by_path("/cpus");
> + if (WARN(!cpus, "Missing cpus node, bailing out\n"))
> + return NULL;
> +
> + if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
> + ac = of_n_addr_cells(cpus);
> +
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
> + cell = of_get_property(cpun, "reg", &prop_len);
> + if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
> + continue;
> +
> + while (prop_len) {
> + hwid = of_read_number(cell, ac);
> + prop_len -= ac;
> + if (arch_match_cpu_phys_id(cpu, hwid))
> + return cpun;
> + }
> + }
> +
> + return NULL;
> +}
> +
> /** Checks if the given "compat" string matches one of the strings in
> * the device's "compatible" property
> */
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 1fd08ca..150b48e 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
> extern const void *of_get_property(const struct device_node *node,
> const char *name,
> int *lenp);
> +extern struct device_node *of_get_cpu_node(int cpu);
> #define for_each_property_of_node(dn, pp) \
> for (pp = dn->properties; pp != NULL; pp = pp->next)
>
> @@ -458,6 +459,10 @@ static inline const void *of_get_property(const struct device_node *node,
> {
> return NULL;
> }
> +static inline struct device_node *of_get_cpu_node(int cpu)
> +{
> + return NULL;
> +}
>
> static inline int of_property_read_u64(const struct device_node *np,
> const char *propname, u64 *out_value)
> --
> 1.8.1.2
>
>
> _______________________________________________
> devicetree-discuss mailing list
> [email protected]
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

2013-07-17 14:45:08

by Andrew Lunn

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On Wed, Jul 17, 2013 at 03:06:20PM +0100, [email protected] wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Now that the cpu device registration initialises the of_node(if available)
> appropriately for all the cpus, parsing here is redundant.
>
> This patch removes all DT parsing and uses cpu->of_node instead.
>
> Cc: Andrew Lunn <[email protected]>
> Cc: Jason Cooper <[email protected]>
> Acked-by: Viresh Kumar <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/cpufreq/kirkwood-cpufreq.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
> index c233ea6..18aa3eb 100644
> --- a/drivers/cpufreq/kirkwood-cpufreq.c
> +++ b/drivers/cpufreq/kirkwood-cpufreq.c
> @@ -13,6 +13,7 @@
> #include <linux/module.h>
> #include <linux/clk.h>
> #include <linux/clk-provider.h>
> +#include <linux/cpu.h>
> #include <linux/cpufreq.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> @@ -165,6 +166,7 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = {
> static int kirkwood_cpufreq_probe(struct platform_device *pdev)
> {
> struct device_node *np;
> + struct device *cpu_dev;
> struct resource *res;
> int err;
>
> @@ -175,9 +177,17 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
> if (IS_ERR(priv.base))
> return PTR_ERR(priv.base);
>
> - np = of_find_node_by_path("/cpus/cpu@0");
> - if (!np)
> + cpu_dev = get_cpu_device(0);
> + if (!cpu_dev) {
> + dev_err(&pdev->dev, "failed to get cpu device\n");
> return -ENODEV;
> + }
> +
> + np = of_node_get(cpu_dev->of_node);
> + if (!np) {
> + dev_err(&pdev->dev, "failed to get cpu device node\n");
> + return -ENODEV;
> + }

Hi Sudeep

Are we not going a bit backwards here? You are replacing two lines
with 10 lines.

How about putting these 10 lines into some helper,
of_get_cpu_device()? It would be useful for spear, kirkwood and
imx6q, and maybe others.

Thanks
Andrew

2013-07-17 14:50:56

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC PATCH v2 01/15] of: add support for retrieving cpu node for a given logical cpu index

On 07/17/2013 09:06 AM, [email protected] wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> This patch adds of_get_cpu_node to retrieve a cpu device node for a
> given logical cpu index. The default matching of the physical id to the
> logical cpu index can be overridden by architecture specific code.
>
> It is recommended to use these helper function only in pre-SMP/early
> initialisation stages to retrieve CPU device node pointers in logical
> ordering. Once the cpu devices are registered, it can be retrieved easily
> from cpu device of_node which avoids unnecessary parsing and matching.
>
> Cc: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

One comment below, but otherwise for patches 1-4, 8 and 9:

Acked-by: Rob Herring <[email protected]>

Also, patch 3 needs to come before patch 2 or the matching will be wrong
if patch 3 is not applied.

> ---
> drivers/of/base.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of.h | 5 +++++
> 2 files changed, 71 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 5c54279..363b8f9 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -230,6 +230,72 @@ const void *of_get_property(const struct device_node *np, const char *name,
> }
> EXPORT_SYMBOL(of_get_property);
>
> +/*
> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
> + *
> + * @cpu: logical index of a cpu
> + * @phys_id: physical identifier of a cpu
> + *
> + * CPU logical to physical index mapping is architecure specific.
> + * However this __weak function provides a default match of physical
> + * id to logical cpu index.
> + *
> + * Returns 1 if the physical identifier and the logical index correspond
> + * to the same cpu, 0 otherwise.
> + */
> +int __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (u32)phys_id == cpu;
> +}
> +
> +/**
> + * of_get_cpu_node - Get device node associated with the given logical CPU
> + *
> + * @cpu: CPU number(logical index) for which device node is required
> + *
> + * The main purpose of this function is to retrieve the device node for the
> + * given logical CPU index. It should be used to intialise the of_node in
> + * cpu device. Once of_node in cpu device is populated, all the further
> + * references can use that instead.
> + *
> + * CPU logical to physical index mapping is architecure specific and is built
> + * before booting secondary cores. This function uses arch_match_cpu_phys_id
> + * which can be overridden by architecture specific implementation.
> + *
> + * Returns a node pointer for the logical cpu if found, else NULL.
> + */
> +struct device_node *of_get_cpu_node(int cpu)
> +{
> + struct device_node *cpun, *cpus;
> + const u32 *cell;
> + u64 hwid;
> + int ac, prop_len;
> +
> + cpus = of_find_node_by_path("/cpus");
> + if (WARN(!cpus, "Missing cpus node, bailing out\n"))

What happens on a system with no /cpus nodes? Seems like this is another
case of adding new warnings to existing working systems.

I'd replace all the WARN's with a single pr_warn on any errors below.
For missing /cpus, I would just silently return.

Rob

> + return NULL;
> +
> + if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
> + ac = of_n_addr_cells(cpus);
> +
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
> + cell = of_get_property(cpun, "reg", &prop_len);
> + if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
> + continue;
> +
> + while (prop_len) {
> + hwid = of_read_number(cell, ac);
> + prop_len -= ac;
> + if (arch_match_cpu_phys_id(cpu, hwid))
> + return cpun;
> + }
> + }
> +
> + return NULL;
> +}

2013-07-17 15:18:21

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 01/15] of: add support for retrieving cpu node for a given logical cpu index

On 17/07/13 15:50, Rob Herring wrote:
> On 07/17/2013 09:06 AM, [email protected] wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>>
>> It's better to consolidate them by adding support for getting cpu
>> device node for a given logical cpu index in DT core library. However
>> logical to physical index mapping can be architecture specific.
>>
>> This patch adds of_get_cpu_node to retrieve a cpu device node for a
>> given logical cpu index. The default matching of the physical id to the
>> logical cpu index can be overridden by architecture specific code.
>>
>> It is recommended to use these helper function only in pre-SMP/early
>> initialisation stages to retrieve CPU device node pointers in logical
>> ordering. Once the cpu devices are registered, it can be retrieved easily
>> from cpu device of_node which avoids unnecessary parsing and matching.
>>
>> Cc: Rob Herring <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> One comment below, but otherwise for patches 1-4, 8 and 9:
>
> Acked-by: Rob Herring <[email protected]>
>
> Also, patch 3 needs to come before patch 2 or the matching will be wrong
> if patch 3 is not applied.
Ah, correct will fix it in next version.

>
>> ---
>> drivers/of/base.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/of.h | 5 +++++
>> 2 files changed, 71 insertions(+)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index 5c54279..363b8f9 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -230,6 +230,72 @@ const void *of_get_property(const struct device_node *np, const char *name,
>> }
>> EXPORT_SYMBOL(of_get_property);
>>
>> +/*
>> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
>> + *
>> + * @cpu: logical index of a cpu
>> + * @phys_id: physical identifier of a cpu
>> + *
>> + * CPU logical to physical index mapping is architecure specific.
>> + * However this __weak function provides a default match of physical
>> + * id to logical cpu index.
>> + *
>> + * Returns 1 if the physical identifier and the logical index correspond
>> + * to the same cpu, 0 otherwise.
>> + */
>> +int __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
>> +{
>> + return (u32)phys_id == cpu;
>> +}
>> +
>> +/**
>> + * of_get_cpu_node - Get device node associated with the given logical CPU
>> + *
>> + * @cpu: CPU number(logical index) for which device node is required
>> + *
>> + * The main purpose of this function is to retrieve the device node for the
>> + * given logical CPU index. It should be used to intialise the of_node in
>> + * cpu device. Once of_node in cpu device is populated, all the further
>> + * references can use that instead.
>> + *
>> + * CPU logical to physical index mapping is architecure specific and is built
>> + * before booting secondary cores. This function uses arch_match_cpu_phys_id
>> + * which can be overridden by architecture specific implementation.
>> + *
>> + * Returns a node pointer for the logical cpu if found, else NULL.
>> + */
>> +struct device_node *of_get_cpu_node(int cpu)
>> +{
>> + struct device_node *cpun, *cpus;
>> + const u32 *cell;
>> + u64 hwid;
>> + int ac, prop_len;
>> +
>> + cpus = of_find_node_by_path("/cpus");
>> + if (WARN(!cpus, "Missing cpus node, bailing out\n"))
>
> What happens on a system with no /cpus nodes? Seems like this is another
> case of adding new warnings to existing working systems.
>
> I'd replace all the WARN's with a single pr_warn on any errors below.
> For missing /cpus, I would just silently return.

Ah, forgot recent discussions on this, will fix it.

Regards,
Sudeep

2013-07-18 07:53:45

by Viresh Kumar

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On 17 July 2013 20:13, Andrew Lunn <[email protected]> wrote:
> Are we not going a bit backwards here? You are replacing two lines
> with 10 lines.
>
> How about putting these 10 lines into some helper,
> of_get_cpu_device()? It would be useful for spear, kirkwood and
> imx6q, and maybe others.

+1

2013-07-18 07:54:20

by Viresh Kumar

[permalink] [raw]
Subject: Re: [RFC PATCH v2 00/15] DT/core: update cpu device of_node

On 17 July 2013 19:36, <[email protected]> wrote:
> 3. Added Acks from Viresh and Shawn

Add it for the new cpufreq drivers included in this patchset too..

2013-07-18 08:24:36

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On 17/07/13 15:43, Andrew Lunn wrote:
> On Wed, Jul 17, 2013 at 03:06:20PM +0100, [email protected] wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Now that the cpu device registration initialises the of_node(if available)
>> appropriately for all the cpus, parsing here is redundant.
>>
>> This patch removes all DT parsing and uses cpu->of_node instead.
>>
>> Cc: Andrew Lunn <[email protected]>
>> Cc: Jason Cooper <[email protected]>
>> Acked-by: Viresh Kumar <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>> ---
>> drivers/cpufreq/kirkwood-cpufreq.c | 14 ++++++++++++--
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
>> index c233ea6..18aa3eb 100644
>> --- a/drivers/cpufreq/kirkwood-cpufreq.c
>> +++ b/drivers/cpufreq/kirkwood-cpufreq.c
>> @@ -13,6 +13,7 @@
>> #include <linux/module.h>
>> #include <linux/clk.h>
>> #include <linux/clk-provider.h>
>> +#include <linux/cpu.h>
>> #include <linux/cpufreq.h>
>> #include <linux/of.h>
>> #include <linux/platform_device.h>
>> @@ -165,6 +166,7 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = {
>> static int kirkwood_cpufreq_probe(struct platform_device *pdev)
>> {
>> struct device_node *np;
>> + struct device *cpu_dev;
>> struct resource *res;
>> int err;
>>
>> @@ -175,9 +177,17 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
>> if (IS_ERR(priv.base))
>> return PTR_ERR(priv.base);
>>
>> - np = of_find_node_by_path("/cpus/cpu@0");
>> - if (!np)
>> + cpu_dev = get_cpu_device(0);
>> + if (!cpu_dev) {
>> + dev_err(&pdev->dev, "failed to get cpu device\n");
>> return -ENODEV;
>> + }
>> +
>> + np = of_node_get(cpu_dev->of_node);
>> + if (!np) {
>> + dev_err(&pdev->dev, "failed to get cpu device node\n");
>> + return -ENODEV;
>> + }
>
> Hi Sudeep
>
> Are we not going a bit backwards here? You are replacing two lines
> with 10 lines.
>
> How about putting these 10 lines into some helper,
> of_get_cpu_device()? It would be useful for spear, kirkwood and
> imx6q, and maybe others.
>
Yes I realised that after making changes to this and pmac32 drivers. I
have already made those changes in v3. I am waiting for more response
before posting them.

Regards,
Sudeep


2013-07-18 10:14:18

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On 18/07/13 09:24, Sudeep KarkadaNagesha wrote:
> On 17/07/13 15:43, Andrew Lunn wrote:
>> On Wed, Jul 17, 2013 at 03:06:20PM +0100, [email protected] wrote:
>>> From: Sudeep KarkadaNagesha <[email protected]>
>>>
[...]
>>> diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
>>> index c233ea6..18aa3eb 100644
>>> --- a/drivers/cpufreq/kirkwood-cpufreq.c
>>> +++ b/drivers/cpufreq/kirkwood-cpufreq.c
>>> @@ -13,6 +13,7 @@
>>> #include <linux/module.h>
>>> #include <linux/clk.h>
>>> #include <linux/clk-provider.h>
>>> +#include <linux/cpu.h>
>>> #include <linux/cpufreq.h>
>>> #include <linux/of.h>
>>> #include <linux/platform_device.h>
>>> @@ -165,6 +166,7 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = {
>>> static int kirkwood_cpufreq_probe(struct platform_device *pdev)
>>> {
>>> struct device_node *np;
>>> + struct device *cpu_dev;
>>> struct resource *res;
>>> int err;
>>>
>>> @@ -175,9 +177,17 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
>>> if (IS_ERR(priv.base))
>>> return PTR_ERR(priv.base);
>>>
>>> - np = of_find_node_by_path("/cpus/cpu@0");
>>> - if (!np)
>>> + cpu_dev = get_cpu_device(0);
>>> + if (!cpu_dev) {
>>> + dev_err(&pdev->dev, "failed to get cpu device\n");
>>> return -ENODEV;
>>> + }
>>> +
>>> + np = of_node_get(cpu_dev->of_node);
>>> + if (!np) {
>>> + dev_err(&pdev->dev, "failed to get cpu device node\n");
>>> + return -ENODEV;
>>> + }
>>
>> Hi Sudeep
>>
>> Are we not going a bit backwards here? You are replacing two lines
>> with 10 lines.
>>
>> How about putting these 10 lines into some helper,
>> of_get_cpu_device()? It would be useful for spear, kirkwood and
>> imx6q, and maybe others.
>>
> Yes I realised that after making changes to this and pmac32 drivers. I
> have already made those changes in v3. I am waiting for more response
> before posting them.
>
I thought of placing this helper in include/linux/of_device.h but I see:
#include <linux/of_platform.h> /* temporary until merge */

Does this mean of_platform.h and of_device.h will be merged ?
If so, which will be the final merged one ? I would like to avoid
changing all the header file inclusions later in users of this new helper.

Regards,
Sudeep

2013-07-18 18:31:05

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC PATCH v2 11/15] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On 07/18/2013 05:14 AM, Sudeep KarkadaNagesha wrote:
> On 18/07/13 09:24, Sudeep KarkadaNagesha wrote:
>> On 17/07/13 15:43, Andrew Lunn wrote:
>>> On Wed, Jul 17, 2013 at 03:06:20PM +0100, [email protected] wrote:
>>>> From: Sudeep KarkadaNagesha <[email protected]>
>>>>
> [...]

>>> Are we not going a bit backwards here? You are replacing two lines
>>> with 10 lines.
>>>
>>> How about putting these 10 lines into some helper,
>>> of_get_cpu_device()? It would be useful for spear, kirkwood and
>>> imx6q, and maybe others.
>>>
>> Yes I realised that after making changes to this and pmac32 drivers. I
>> have already made those changes in v3. I am waiting for more response
>> before posting them.
>>
> I thought of placing this helper in include/linux/of_device.h but I see:
> #include <linux/of_platform.h> /* temporary until merge */
>
> Does this mean of_platform.h and of_device.h will be merged ?

No, I think that was probably to avoid adding includes of of_platform.h
for 100's of files. Maybe things are cleaned up enough to remove this line.

> If so, which will be the final merged one ? I would like to avoid
> changing all the header file inclusions later in users of this new helper.

of_device.h is the right place.

Rob

>
> Regards,
> Sudeep
>
>
> _______________________________________________
> devicetree-discuss mailing list
> [email protected]
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

2013-07-22 11:32:58

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 13/16] cpufreq: arm_big_little: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/arm_big_little_dt.c | 40 +++++++++++++------------------------
1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c
index fd9e3ea..480c0bd 100644
--- a/drivers/cpufreq/arm_big_little_dt.c
+++ b/drivers/cpufreq/arm_big_little_dt.c
@@ -19,12 +19,11 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

-#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/opp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -34,27 +33,13 @@
/* get cpu node with valid operating-points */
static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
- struct device_node *np = NULL, *parent;
- int count = 0;
+ struct device_node *np = of_cpu_device_node_get(cpu);

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
- return NULL;
+ if (!of_get_property(np, "operating-points", NULL)) {
+ of_node_put(np);
+ np = NULL;
}

- for_each_child_of_node(parent, np) {
- if (count++ != cpu)
- continue;
- if (!of_get_property(np, "operating-points", NULL)) {
- of_node_put(np);
- np = NULL;
- }
-
- break;
- }
-
- of_node_put(parent);
return np;
}

@@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev)
struct device_node *np;
int ret;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
- return -ENODATA;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find cpu%d node\n", cpu_dev->id);
+ return -ENOENT;
+ }

- cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
of_node_put(np);

@@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
struct device_node *np;
u32 transition_latency = CPUFREQ_ETERNAL;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
+ }

of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);
--
1.8.1.2

2013-07-22 11:33:00

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 12/16] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Andrew Lunn <[email protected]>
Cc: Jason Cooper <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/kirkwood-cpufreq.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index c233ea6..25ac2cb 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -14,7 +14,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpufreq.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/proc-fns.h>
@@ -175,9 +175,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
if (IS_ERR(priv.base))
return PTR_ERR(priv.base);

- np = of_find_node_by_path("/cpus/cpu@0");
- if (!np)
+ np = of_cpu_device_node_get(0);
+ if (!np) {
+ dev_err(&pdev->dev, "failed to get cpu device node\n");
return -ENODEV;
+ }

priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
if (IS_ERR(priv.cpu_clk)) {
--
1.8.1.2

2013-07-22 11:33:03

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 15/16] cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Benjamin Herrenschmidt <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac64-cpufreq.c | 47 ++++++++++------------------------------
1 file changed, 11 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 7ba4234..97b719f 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/mutex.h>
+#include <linux/of_device.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/irq.h>
@@ -383,9 +384,8 @@ static struct cpufreq_driver g5_cpufreq_driver = {

#ifdef CONFIG_PMAC_SMU

-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
+static int __init g5_neo2_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpunode;
unsigned int psize, ssize;
unsigned long max_freq;
char *freq_method, *volt_method;
@@ -405,20 +405,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
else
return -ENODEV;

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- return -ENODEV;
- }
-
/* Check 970FX for now */
valp = of_get_property(cpunode, "cpu-version", NULL);
if (!valp) {
@@ -537,9 +523,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
#endif /* CONFIG_PMAC_SMU */


-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
+static int __init g5_pm72_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
+ struct device_node *cpuid = NULL, *hwclock = NULL;
const u8 *eeprom = NULL;
const u32 *valp;
u64 max_freq, min_freq, ih, il;
@@ -548,17 +534,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
" RackMac3,1...\n");

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
- return -ENODEV;
- }
-
/* Lookup the cpuid eeprom node */
cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
if (cpuid != NULL)
@@ -718,25 +693,25 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)

static int __init g5_cpufreq_init(void)
{
- struct device_node *cpus;
+ struct device_node *cpunode;
int rc = 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
+ /* Get first CPU node */
+ cpunode = of_cpu_device_node_get(0);
+ if (cpunode == NULL) {
+ pr_err("cpufreq: Can't find any CPU node\n");
return -ENODEV;
}

if (of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3") ||
of_machine_is_compatible("RackMac3,1"))
- rc = g5_pm72_cpufreq_init(cpus);
+ rc = g5_pm72_cpufreq_init(cpunode);
#ifdef CONFIG_PMAC_SMU
else
- rc = g5_neo2_cpufreq_init(cpus);
+ rc = g5_neo2_cpufreq_init(cpunode);
#endif /* CONFIG_PMAC_SMU */

- of_node_put(cpus);
return rc;
}

--
1.8.1.2

2013-07-22 11:32:57

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 11/16] cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Deepak Sikri <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/spear-cpufreq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index c3efa7f..19e364fa 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -18,7 +18,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/types.h>

@@ -223,7 +223,7 @@ static int spear_cpufreq_driver_init(void)
const __be32 *val;
int cnt, i, ret;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_cpu_device_node_get(0);
if (!np) {
pr_err("No cpu node found");
return -ENODEV;
--
1.8.1.2

2013-07-22 11:32:54

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 10/16] cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Mark Langsdorf <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/highbank-cpufreq.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
index b61b5a3..794123f 100644
--- a/drivers/cpufreq/highbank-cpufreq.c
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void)
if (!of_machine_is_compatible("calxeda,highbank"))
return -ENODEV;

- for_each_child_of_node(of_find_node_by_path("/cpus"), np)
- if (of_get_property(np, "operating-points", NULL))
- break;
-
- if (!np) {
- pr_err("failed to find highbank cpufreq node\n");
- return -ENOENT;
- }
-
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
pr_err("failed to get highbank cpufreq device\n");
- ret = -ENODEV;
- goto out_put_node;
+ return -ENODEV;
}

- cpu_dev->of_node = np;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find highbank cpufreq node\n");
+ return -ENOENT;
+ }

cpu_clk = clk_get(cpu_dev, NULL);
if (IS_ERR(cpu_clk)) {
--
1.8.1.2

2013-07-22 11:34:32

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 16/16] cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes DT parsing and uses cpu->of_node instead.

Cc: Benjamin Herrenschmidt <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac32-cpufreq.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 3104fad..56bfb6f 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/hardirq.h>
+#include <linux/of_device.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/irq.h>
@@ -649,8 +650,8 @@ static int __init pmac_cpufreq_setup(void)
if (strstr(cmd_line, "nocpufreq"))
return 0;

- /* Assume only one CPU */
- cpunode = of_find_node_by_type(NULL, "cpu");
+ /* Get first CPU node */
+ cpunode = of_cpu_device_node_get(0);
if (!cpunode)
goto out;

--
1.8.1.2

2013-07-22 11:34:55

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 14/16] cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Dmitry Eremin-Solenikov <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/maple-cpufreq.c | 23 +++--------------------
1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c
index cdd6291..f071dc4 100644
--- a/drivers/cpufreq/maple-cpufreq.c
+++ b/drivers/cpufreq/maple-cpufreq.c
@@ -24,7 +24,7 @@
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/time.h>
-#include <linux/of.h>
+#include <linux/of_device.h>

#define DBG(fmt...) pr_debug(fmt)

@@ -201,7 +201,6 @@ static struct cpufreq_driver maple_cpufreq_driver = {

static int __init maple_cpufreq_init(void)
{
- struct device_node *cpus;
struct device_node *cpunode;
unsigned int psize;
unsigned long max_freq;
@@ -217,24 +216,11 @@ static int __init maple_cpufreq_init(void)
!of_machine_is_compatible("Momentum,Apache"))
return 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
- return -ENODEV;
- }
-
/* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
+ cpunode = of_cpu_device_node_get(0);
if (cpunode == NULL) {
printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- goto bail_cpus;
+ goto bail_noprops;
}

/* Check 970FX for now */
@@ -290,14 +276,11 @@ static int __init maple_cpufreq_init(void)
rc = cpufreq_register_driver(&maple_cpufreq_driver);

of_node_put(cpunode);
- of_node_put(cpus);

return rc;

bail_noprops:
of_node_put(cpunode);
-bail_cpus:
- of_node_put(cpus);

return rc;
}
--
1.8.1.2

2013-07-22 11:32:47

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 02/16] ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id

From: Sudeep KarkadaNagesha <[email protected]>

OF/DT core library now provides architecture specific hook to match the
logical cpu index with the corresponding physical identifier. Most of the
cpu DT node parsing and initialisation is contained in devtree.c. So it's
better to define ARM specific arch_match_cpu_phys_id there.

This mainly helps to avoid replication of the code doing CPU node parsing
and physical(MPIDR) to logical mapping.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/devtree.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 5859c8b..2ee8a17 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
}
}

+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
+}
+
/**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt_phys: physical address of dt blob
--
1.8.1.2

2013-07-22 11:35:34

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 09/16] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/cpufreq-cpu0.c | 23 ++++-------------------
1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index ad1fde2..5b05c26 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {

static int cpu0_cpufreq_probe(struct platform_device *pdev)
{
- struct device_node *np, *parent;
+ struct device_node *np;
int ret;

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
- return -ENOENT;
- }
-
- for_each_child_of_node(parent, np) {
- if (of_get_property(np, "operating-points", NULL))
- break;
- }
+ cpu_dev = &pdev->dev;

+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("failed to find cpu0 node\n");
- ret = -ENOENT;
- goto out_put_parent;
+ return -ENOENT;
}

- cpu_dev = &pdev->dev;
- cpu_dev->of_node = np;
-
cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
@@ -269,15 +257,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
}

of_node_put(np);
- of_node_put(parent);
return 0;

out_free_table:
opp_free_cpufreq_table(cpu_dev, &freq_table);
out_put_node:
of_node_put(np);
-out_put_parent:
- of_node_put(parent);
return ret;
}

--
1.8.1.2

2013-07-22 11:35:53

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 07/16] of/device: add helper to get cpu device node from logical cpu index

From: Sudeep KarkadaNagesha <[email protected]>

Multiple drivers need to get the cpu device node from the cpu logical
index and then access the of_node.

This patch adds helper function to fetch the device node directly.

Cc: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
include/linux/of_device.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 9d27475..82ce324 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_OF_DEVICE_H
#define _LINUX_OF_DEVICE_H

+#include <linux/cpu.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h> /* temporary until merge */

@@ -43,6 +44,15 @@ static inline void of_device_node_put(struct device *dev)
of_node_put(dev->of_node);
}

+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+ struct device *cpu_dev;
+ cpu_dev = get_cpu_device(cpu);
+ if (!cpu_dev)
+ return NULL;
+ return of_node_get(cpu_dev->of_node);
+}
+
#else /* CONFIG_OF */

static inline int of_driver_match_device(struct device *dev,
@@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device(
{
return NULL;
}
+
+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */

#endif /* _LINUX_OF_DEVICE_H */
--
1.8.1.2

2013-07-22 11:35:51

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 08/16] cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-imx/mach-imx6q.c | 3 +--
drivers/cpufreq/imx6q-cpufreq.c | 4 +---
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 7be13f8..a02f275 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev)
{
struct device_node *np;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_warn("failed to find cpu0 node\n");
return;
}

- cpu_dev->of_node = np;
if (of_init_opp_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index e37cdae..b16632b 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -221,14 +221,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)

cpu_dev = &pdev->dev;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
dev_err(cpu_dev, "failed to find cpu0 node\n");
return -ENOENT;
}

- cpu_dev->of_node = np;
-
arm_clk = devm_clk_get(cpu_dev, "arm");
pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
--
1.8.1.2

2013-07-22 11:32:44

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 00/16] DT/core: update cpu device of_node

From: Sudeep KarkadaNagesha <[email protected]>

As more and more information is getting added into the cpu node, the number
of drivers needing to parse the device tree for CPU nodes are increasing.
Most of the time, the information needed from the cpu node is preferred
in the logical CPU order. Hence many drivers first parse and search the
CPU node, match them to logical index if needed and then search for the
required property inside a particular cpu node. Some of them assume the
logical and physical CPU ordering to be same which is incorrect.

This patch series initialises the of_node in all the cpu devices when
registering the CPU device.
1. This avoids different drivers having to parse the cpu nodes to obtain
different attributes like operating points, latency,...etc.
2. This handles different physical and logical cpu ordering which is not
the case in current code.
3. Also all the cpu nodes will have their of_node initialised correctly.
Currently different drivers assign them partially and incorrectly.
4. Removes all the reduntant parsing in various drivers.

Changes v2->v3:
1. Added new OF helper to get of_node from the cpu logical index.
With the use of this help, removed lots of duplicated code from
cpufreq drivers.
2. Fixed issue with property length calculation in of_get_cpu_node.
(previously had assumed of_get_property returns number of cells)
3. Changed return type of arch_match_cpu_phys_id to bool(as suggested by Nico)
4. Re-ordered patch 2 and 3, and few typo fixes.
5. Rebased on v3.11-rc2(to avoid any conflicts with __cpuinit* deletion)

Changes v1->v2:
1. Moved most of arch_of_get_cpu_node to OF/DT core as of_get_cpu_node
adding a provision for architecture specific hooks for matching
logical and physical ids.
2. Extended removal of DT cpu node parsing to PPC cpufreq drivers
3. Added Acks from Viresh and Shawn

Regards,
Sudeep

Sudeep KarkadaNagesha (16):
of: add support for retrieving cpu node for a given logical cpu index
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
driver/core: cpu: initialize of_node in cpu's device struture
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
ARM: mvebu: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
of/device: add helper to get cpu device node from logical cpu index
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

arch/arm/kernel/devtree.c | 5 +++
arch/arm/kernel/topology.c | 61 ++++++++++---------------------
arch/arm/mach-imx/mach-imx6q.c | 3 +-
arch/arm/mach-mvebu/platsmp.c | 52 +++++++++++++--------------
drivers/base/cpu.c | 2 ++
drivers/bus/arm-cci.c | 28 ++++-----------
drivers/cpufreq/arm_big_little_dt.c | 40 ++++++++-------------
drivers/cpufreq/cpufreq-cpu0.c | 23 +++---------
drivers/cpufreq/highbank-cpufreq.c | 18 ++++------
drivers/cpufreq/imx6q-cpufreq.c | 4 +--
drivers/cpufreq/kirkwood-cpufreq.c | 8 +++--
drivers/cpufreq/maple-cpufreq.c | 23 ++----------
drivers/cpufreq/pmac32-cpufreq.c | 5 +--
drivers/cpufreq/pmac64-cpufreq.c | 47 ++++++------------------
drivers/cpufreq/spear-cpufreq.c | 4 +--
drivers/of/base.c | 72 +++++++++++++++++++++++++++++++++++++
include/linux/of.h | 6 ++++
include/linux/of_device.h | 15 ++++++++
18 files changed, 200 insertions(+), 216 deletions(-)

--
1.8.1.2

2013-07-22 11:36:39

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Currently set_secondary_cpus_clock assume the CPU logical ordering
and the MPDIR in DT are same, which is incorrect.

Since the CPU device nodes can be retrieved in the logical ordering
using the DT helper, we can remove the devices tree parsing.

This patch removes DT parsing by making use of of_get_cpu_node.

Cc: Gregory Clement <[email protected]>
Cc: Andrew Lunn <[email protected]>
Cc: Jason Cooper <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index ce81d30..001dd42 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -23,51 +23,47 @@
#include <linux/of.h>
#include <linux/mbus.h>
#include <asm/cacheflush.h>
+#include <asm/prom.h>
#include <asm/smp_plat.h>
#include "common.h"
#include "armada-370-xp.h"
#include "pmsu.h"
#include "coherency.h"

+static struct clk *__init get_cpu_clk(int cpu)
+{
+ struct clk *cpu_clk;
+ struct device_node *np = of_get_cpu_node(cpu);
+
+ if (WARN(!np, "missing cpu node\n"))
+ return NULL;
+ cpu_clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(cpu_clk)))
+ return NULL;
+ return cpu_clk;
+}
+
void __init set_secondary_cpus_clock(void)
{
- int thiscpu;
+ int thiscpu, cpu;
unsigned long rate;
- struct clk *cpu_clk = NULL;
- struct device_node *np = NULL;
+ struct clk *cpu_clk;

thiscpu = smp_processor_id();
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
- return;
-
- if (cpu == thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- break;
- }
- }
- if (WARN_ON(IS_ERR(cpu_clk)))
+ cpu_clk = get_cpu_clk(thiscpu);
+ if (!cpu_clk)
return;
clk_prepare_enable(cpu_clk);
rate = clk_get_rate(cpu_clk);

/* set all the other CPU clk to the same rate than the boot CPU */
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
+ for_each_possible_cpu(cpu) {
+ if (cpu == thiscpu)
+ continue;
+ cpu_clk = get_cpu_clk(cpu);
+ if (!cpu_clk)
return;
-
- if (cpu != thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- clk_set_rate(cpu_clk, rate);
- }
+ clk_set_rate(cpu_clk, rate);
}
}

--
1.8.1.2

2013-07-22 11:36:37

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 06/16] drivers/bus: arm-cci: avoid parsing DT for cpu device nodes

From: Sudeep KarkadaNagesha <[email protected]>

Since the CPU device nodes can be retrieved using arch_of_get_cpu_node,
we can use it to avoid parsing the cpus node searching the cpu nodes and
mapping to logical index.

This patch removes parsing DT for cpu nodes by using of_get_cpu_node.

Cc: Lorenzo Pieralisi <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/bus/arm-cci.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 7332889..7dd891c 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);

static void __init cci_ace_init_ports(void)
{
- int port, ac, cpu;
- u64 hwid;
- const u32 *cell;
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (WARN(!cpus, "Missing cpus node, bailing out\n"))
- return;
-
- if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
- ac = of_n_addr_cells(cpus);
+ int port, cpu;
+ struct device_node *cpun;

/*
* Port index look-up speeds up the function disabling ports by CPU,
@@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
* The stashed index array is initialized for all possible CPUs
* at probe time.
*/
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
- cell = of_get_property(cpun, "reg", NULL);
- if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
- continue;
-
- hwid = of_read_number(cell, ac);
- cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
+ for_each_possible_cpu(cpu) {
+ /* too early to use cpu->of_node */
+ cpun = of_get_cpu_node(cpu);

- if (cpu < 0 || !cpu_possible(cpu))
+ if (WARN(!cpun, "Missing cpu device node\n"))
continue;
+
port = __cci_ace_get_port(cpun, ACE_PORT);
if (port < 0)
continue;
--
1.8.1.2

2013-07-22 11:37:09

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 03/16] driver/core: cpu: initialize of_node in cpu's device struture

From: Sudeep KarkadaNagesha <[email protected]>

CPUs are also registered as devices but the of_node in these cpu
devices are not initialized. Currently different drivers requiring
to access cpu device node are parsing the nodes themselves and
initialising the of_node in cpu device.

The of_node in all the cpu devices needs to be initialized properly
and at one place. The best place to update this is CPU subsystem
driver when registering the cpu devices.

The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
device node for a given logical index by abstracting the architecture
specific details.

This patch uses of_get_cpu_node to assign of_node when registering the
cpu devices.

Cc: Greg Kroah-Hartman <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/base/cpu.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4c358bc..ea51c6d 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/acpi.h>
+#include <linux/of.h>

#include "base.h"

@@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
+ cpu->dev.of_node = of_get_cpu_node(num);
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent;
#endif
--
1.8.1.2

2013-07-22 11:37:39

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 04/16] ARM: topology: remove hwid/MPIDR dependency from cpu_capacity

From: Sudeep KarkadaNagesha <[email protected]>

Currently the topology code computes cpu capacity and stores it in
the list along with hwid(which is MPIDR) as it parses the CPU nodes
in the device tree. This is required as it needs to be mapped to the
logical CPU later.

Since the CPU device nodes can be retrieved in the logical ordering
using DT/OF helpers, its possible to store cpu_capacity also in logical
ordering and avoid storing hwid for each entry.

This patch removes hwid by making use of of_get_cpu_node.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/topology.c | 61 +++++++++++++++-------------------------------
1 file changed, 19 insertions(+), 42 deletions(-)

diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index c5a5954..28ef27a 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
{NULL, },
};

-struct cpu_capacity {
- unsigned long hwid;
- unsigned long capacity;
-};
-
-struct cpu_capacity *cpu_capacity;
+unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu) __cpu_capacity[cpu]

unsigned long middle_capacity = 1;

@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
unsigned long capacity = 0;
int alloc_size, cpu = 0;

- alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
- cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
+ alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
+ __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);

- while ((cn = of_find_node_by_type(cn, "cpu"))) {
- const u32 *rate, *reg;
+ for_each_possible_cpu(cpu) {
+ const u32 *rate;
int len;

- if (cpu >= num_possible_cpus())
- break;
+ /* too early to use cpu->of_node */
+ cn = of_get_cpu_node(cpu);
+ if (!cn) {
+ pr_err("missing device node for CPU %d\n", cpu);
+ continue;
+ }

for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
if (of_device_is_compatible(cn, cpu_eff->compatible))
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
continue;
}

- reg = of_get_property(cn, "reg", &len);
- if (!reg || len != 4) {
- pr_err("%s missing reg property\n", cn->full_name);
- continue;
- }
-
capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;

/* Save min capacity of the system */
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
if (capacity > max_capacity)
max_capacity = capacity;

- cpu_capacity[cpu].capacity = capacity;
- cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
+ cpu_capacity(cpu) = capacity;
}

- if (cpu < num_possible_cpus())
- cpu_capacity[cpu].hwid = (unsigned long)(-1);
-
/* If min and max capacities are equals, we bypass the update of the
* cpu_scale because all CPUs have the same capacity. Otherwise, we
* compute a middle_capacity factor that will ensure that the capacity
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
* SCHED_POWER_SCALE, which is the default value, but with the
* constraint explained near table_efficiency[].
*/
- if (min_capacity == max_capacity)
- cpu_capacity[0].hwid = (unsigned long)(-1);
- else if (4*max_capacity < (3*(max_capacity + min_capacity)))
+ if (4*max_capacity < (3*(max_capacity + min_capacity)))
middle_capacity = (min_capacity + max_capacity)
>> (SCHED_POWER_SHIFT+1);
else
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
* boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
* function returns directly for SMP system.
*/
-void update_cpu_power(unsigned int cpu, unsigned long hwid)
+void update_cpu_power(unsigned int cpu)
{
- unsigned int idx = 0;
-
- /* look for the cpu's hwid in the cpu capacity table */
- for (idx = 0; idx < num_possible_cpus(); idx++) {
- if (cpu_capacity[idx].hwid == hwid)
- break;
-
- if (cpu_capacity[idx].hwid == -1)
- return;
- }
-
- if (idx == num_possible_cpus())
+ if (!cpu_capacity(cpu))
return;

- set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
+ set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);

printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
cpu, arch_scale_freq_power(NULL, cpu));
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)

#else
static inline void parse_dt_topology(void) {}
-static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
+static inline void update_cpu_power(unsigned int cpuid) {}
#endif

/*
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)

update_siblings_masks(cpuid);

- update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
+ update_cpu_power(cpuid);

printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
cpuid, cpu_topology[cpuid].thread_id,
--
1.8.1.2

2013-07-22 11:37:41

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

This patch adds of_get_cpu_node to retrieve a cpu device node for a
given logical cpu index. The default matching of the physical id to the
logical cpu index can be overridden by architecture specific code.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/of/base.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of.h | 6 +++++
2 files changed, 78 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..1e690bf 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -230,6 +230,78 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical index of a cpu
+ * @phys_id: physical identifier of a cpu
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index.
+ *
+ * Returns true if the physical identifier and the logical index correspond
+ * to the same cpu, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to intialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu)
+{
+ struct device_node *cpun, *cpus;
+ const __be32 *cell;
+ u64 hwid;
+ int ac, prop_len;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }
+
+ if (of_property_read_u32(cpus, "#address-cells", &ac)) {
+ pr_warn("%s: missing #address-cells\n", cpus->full_name);
+ ac = of_n_addr_cells(cpus);
+ }
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+ cell = of_get_property(cpun, "reg", &prop_len);
+ if (!cell) {
+ pr_warn("%s: missing reg property\n", cpun->full_name);
+ continue;
+ }
+ prop_len /= sizeof(*cell);
+ while (prop_len) {
+ hwid = of_read_number(cell, ac);
+ prop_len -= ac;
+ if (arch_match_cpu_phys_id(cpu, hwid))
+ return cpun;
+ }
+ }
+
+ return NULL;
+}
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..9e82812 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -459,6 +460,11 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}

+static inline struct device_node *of_get_cpu_node(int cpu)
+{
+ return NULL;
+}
+
static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
{
--
1.8.1.2

2013-07-22 14:14:10

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

On Mon, 22 Jul 2013, Sudeep KarkadaNagesha wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> This patch adds of_get_cpu_node to retrieve a cpu device node for a
> given logical cpu index. The default matching of the physical id to the
> logical cpu index can be overridden by architecture specific code.
>
> It is recommended to use these helper function only in pre-SMP/early
> initialisation stages to retrieve CPU device node pointers in logical
> ordering. Once the cpu devices are registered, it can be retrieved easily
> from cpu device of_node which avoids unnecessary parsing and matching.
>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Minor nits below. Otherwise...

Acked-by: Nicolas Pitre <[email protected]>

> ---
> drivers/of/base.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of.h | 6 +++++
> 2 files changed, 78 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 5c54279..1e690bf 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -230,6 +230,78 @@ const void *of_get_property(const struct device_node *np, const char *name,
> }
> EXPORT_SYMBOL(of_get_property);
>
> +/*
> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
> + *
> + * @cpu: logical index of a cpu
> + * @phys_id: physical identifier of a cpu
> + *
> + * CPU logical to physical index mapping is architecture specific.
> + * However this __weak function provides a default match of physical
> + * id to logical cpu index.
> + *
> + * Returns true if the physical identifier and the logical index correspond
> + * to the same cpu, false otherwise.
> + */
> +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)

Maybe a prototype declaration for this function should be added to
include/linux/of.h to avoid mismatch with architecture provided
versions.

> +{
> + return (u32)phys_id == cpu;
> +}
> +
> +/**
> + * of_get_cpu_node - Get device node associated with the given logical CPU
> + *
> + * @cpu: CPU number(logical index) for which device node is required
> + *
> + * The main purpose of this function is to retrieve the device node for the
> + * given logical CPU index. It should be used to intialize the of_node in

s/intialize/initialize/


Nicolas

2013-07-22 14:15:00

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 02/16] ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id

On Mon, 22 Jul 2013, Sudeep KarkadaNagesha wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> OF/DT core library now provides architecture specific hook to match the
> logical cpu index with the corresponding physical identifier. Most of the
> cpu DT node parsing and initialisation is contained in devtree.c. So it's
> better to define ARM specific arch_match_cpu_phys_id there.
>
> This mainly helps to avoid replication of the code doing CPU node parsing
> and physical(MPIDR) to logical mapping.
>
> Cc: Russell King <[email protected]>
> Cc: Lorenzo Pieralisi <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Acked-by: Nicolas Pitre <[email protected]>


> ---
> arch/arm/kernel/devtree.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
> index 5859c8b..2ee8a17 100644
> --- a/arch/arm/kernel/devtree.c
> +++ b/arch/arm/kernel/devtree.c
> @@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
> }
> }
>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
> +}
> +
> /**
> * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
> * @dt_phys: physical address of dt blob
> --
> 1.8.1.2
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2013-07-22 14:25:15

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 04/16] ARM: topology: remove hwid/MPIDR dependency from cpu_capacity

On Mon, 22 Jul 2013, Sudeep KarkadaNagesha wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently the topology code computes cpu capacity and stores it in
> the list along with hwid(which is MPIDR) as it parses the CPU nodes
> in the device tree. This is required as it needs to be mapped to the
> logical CPU later.
>
> Since the CPU device nodes can be retrieved in the logical ordering
> using DT/OF helpers, its possible to store cpu_capacity also in logical
> ordering and avoid storing hwid for each entry.
>
> This patch removes hwid by making use of of_get_cpu_node.
>
> Cc: Russell King <[email protected]>
> Cc: Lorenzo Pieralisi <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Acked-by: Nicolas Pitre <[email protected]>


> ---
> arch/arm/kernel/topology.c | 61 +++++++++++++++-------------------------------
> 1 file changed, 19 insertions(+), 42 deletions(-)
>
> diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
> index c5a5954..28ef27a 100644
> --- a/arch/arm/kernel/topology.c
> +++ b/arch/arm/kernel/topology.c
> @@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
> {NULL, },
> };
>
> -struct cpu_capacity {
> - unsigned long hwid;
> - unsigned long capacity;
> -};
> -
> -struct cpu_capacity *cpu_capacity;
> +unsigned long *__cpu_capacity;
> +#define cpu_capacity(cpu) __cpu_capacity[cpu]
>
> unsigned long middle_capacity = 1;
>
> @@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
> unsigned long capacity = 0;
> int alloc_size, cpu = 0;
>
> - alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
> - cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
> + alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
> + __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
>
> - while ((cn = of_find_node_by_type(cn, "cpu"))) {
> - const u32 *rate, *reg;
> + for_each_possible_cpu(cpu) {
> + const u32 *rate;
> int len;
>
> - if (cpu >= num_possible_cpus())
> - break;
> + /* too early to use cpu->of_node */
> + cn = of_get_cpu_node(cpu);
> + if (!cn) {
> + pr_err("missing device node for CPU %d\n", cpu);
> + continue;
> + }
>
> for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
> if (of_device_is_compatible(cn, cpu_eff->compatible))
> @@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
> continue;
> }
>
> - reg = of_get_property(cn, "reg", &len);
> - if (!reg || len != 4) {
> - pr_err("%s missing reg property\n", cn->full_name);
> - continue;
> - }
> -
> capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
>
> /* Save min capacity of the system */
> @@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
> if (capacity > max_capacity)
> max_capacity = capacity;
>
> - cpu_capacity[cpu].capacity = capacity;
> - cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
> + cpu_capacity(cpu) = capacity;
> }
>
> - if (cpu < num_possible_cpus())
> - cpu_capacity[cpu].hwid = (unsigned long)(-1);
> -
> /* If min and max capacities are equals, we bypass the update of the
> * cpu_scale because all CPUs have the same capacity. Otherwise, we
> * compute a middle_capacity factor that will ensure that the capacity
> @@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
> * SCHED_POWER_SCALE, which is the default value, but with the
> * constraint explained near table_efficiency[].
> */
> - if (min_capacity == max_capacity)
> - cpu_capacity[0].hwid = (unsigned long)(-1);
> - else if (4*max_capacity < (3*(max_capacity + min_capacity)))
> + if (4*max_capacity < (3*(max_capacity + min_capacity)))
> middle_capacity = (min_capacity + max_capacity)
> >> (SCHED_POWER_SHIFT+1);
> else
> @@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
> * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
> * function returns directly for SMP system.
> */
> -void update_cpu_power(unsigned int cpu, unsigned long hwid)
> +void update_cpu_power(unsigned int cpu)
> {
> - unsigned int idx = 0;
> -
> - /* look for the cpu's hwid in the cpu capacity table */
> - for (idx = 0; idx < num_possible_cpus(); idx++) {
> - if (cpu_capacity[idx].hwid == hwid)
> - break;
> -
> - if (cpu_capacity[idx].hwid == -1)
> - return;
> - }
> -
> - if (idx == num_possible_cpus())
> + if (!cpu_capacity(cpu))
> return;
>
> - set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
> + set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
>
> printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
> cpu, arch_scale_freq_power(NULL, cpu));
> @@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)
>
> #else
> static inline void parse_dt_topology(void) {}
> -static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
> +static inline void update_cpu_power(unsigned int cpuid) {}
> #endif
>
> /*
> @@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)
>
> update_siblings_masks(cpuid);
>
> - update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
> + update_cpu_power(cpuid);
>
> printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
> cpuid, cpu_topology[cpuid].thread_id,
> --
> 1.8.1.2
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2013-07-22 14:38:06

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 06/16] drivers/bus: arm-cci: avoid parsing DT for cpu device nodes

On Mon, 22 Jul 2013, Sudeep KarkadaNagesha wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> Since the CPU device nodes can be retrieved using arch_of_get_cpu_node,
> we can use it to avoid parsing the cpus node searching the cpu nodes and
> mapping to logical index.
>
> This patch removes parsing DT for cpu nodes by using of_get_cpu_node.
>
> Cc: Lorenzo Pieralisi <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Acked-by: Nicolas Pitre <[email protected]>


> ---
> drivers/bus/arm-cci.c | 28 +++++++---------------------
> 1 file changed, 7 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
> index 7332889..7dd891c 100644
> --- a/drivers/bus/arm-cci.c
> +++ b/drivers/bus/arm-cci.c
> @@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);
>
> static void __init cci_ace_init_ports(void)
> {
> - int port, ac, cpu;
> - u64 hwid;
> - const u32 *cell;
> - struct device_node *cpun, *cpus;
> -
> - cpus = of_find_node_by_path("/cpus");
> - if (WARN(!cpus, "Missing cpus node, bailing out\n"))
> - return;
> -
> - if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
> - ac = of_n_addr_cells(cpus);
> + int port, cpu;
> + struct device_node *cpun;
>
> /*
> * Port index look-up speeds up the function disabling ports by CPU,
> @@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
> * The stashed index array is initialized for all possible CPUs
> * at probe time.
> */
> - for_each_child_of_node(cpus, cpun) {
> - if (of_node_cmp(cpun->type, "cpu"))
> - continue;
> - cell = of_get_property(cpun, "reg", NULL);
> - if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
> - continue;
> -
> - hwid = of_read_number(cell, ac);
> - cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
> + for_each_possible_cpu(cpu) {
> + /* too early to use cpu->of_node */
> + cpun = of_get_cpu_node(cpu);
>
> - if (cpu < 0 || !cpu_possible(cpu))
> + if (WARN(!cpun, "Missing cpu device node\n"))
> continue;
> +
> port = __cci_ace_get_port(cpun, ACE_PORT);
> if (port < 0)
> continue;
> --
> 1.8.1.2
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2013-07-22 15:06:53

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

Hi Nico,

On 22/07/13 15:14, Nicolas Pitre wrote:
> On Mon, 22 Jul 2013, Sudeep KarkadaNagesha wrote:
>
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>>
>> It's better to consolidate them by adding support for getting cpu
>> device node for a given logical cpu index in DT core library. However
>> logical to physical index mapping can be architecture specific.
>>
>> This patch adds of_get_cpu_node to retrieve a cpu device node for a
>> given logical cpu index. The default matching of the physical id to the
>> logical cpu index can be overridden by architecture specific code.
>>
>> It is recommended to use these helper function only in pre-SMP/early
>> initialisation stages to retrieve CPU device node pointers in logical
>> ordering. Once the cpu devices are registered, it can be retrieved easily
>> from cpu device of_node which avoids unnecessary parsing and matching.
>>
>> Acked-by: Rob Herring <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> Minor nits below. Otherwise...
>
> Acked-by: Nicolas Pitre <[email protected]>
>
Thanks for all the Acks.

>> ---
>> drivers/of/base.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/of.h | 6 +++++
>> 2 files changed, 78 insertions(+)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index 5c54279..1e690bf 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -230,6 +230,78 @@ const void *of_get_property(const struct device_node *np, const char *name,
>> }
>> EXPORT_SYMBOL(of_get_property);
>>
>> +/*
>> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
>> + *
>> + * @cpu: logical index of a cpu
>> + * @phys_id: physical identifier of a cpu
>> + *
>> + * CPU logical to physical index mapping is architecture specific.
>> + * However this __weak function provides a default match of physical
>> + * id to logical cpu index.
>> + *
>> + * Returns true if the physical identifier and the logical index correspond
>> + * to the same cpu, false otherwise.
>> + */
>> +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
>
> Maybe a prototype declaration for this function should be added to
> include/linux/of.h to avoid mismatch with architecture provided
> versions.
>
Agreed, but include/linux/of.h doesn't seem to be right choice for me as
this function is not really related to OF/DT. I can't choose any better
place either. I don't have a strong opinion on that, just a thought.

Regards,
Sudeep

2013-07-23 09:26:57

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v3 12/16] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

On Mon, Jul 22, 2013 at 12:32:23PM +0100, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Now that the cpu device registration initialises the of_node(if available)
> appropriately for all the cpus, parsing here is redundant.
>
> This patch removes all DT parsing and uses cpu->of_node instead.
>
> Cc: Andrew Lunn <[email protected]>
> Cc: Jason Cooper <[email protected]>
> Acked-by: Viresh Kumar <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/cpufreq/kirkwood-cpufreq.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
> index c233ea6..25ac2cb 100644
> --- a/drivers/cpufreq/kirkwood-cpufreq.c
> +++ b/drivers/cpufreq/kirkwood-cpufreq.c
> @@ -14,7 +14,7 @@
> #include <linux/clk.h>
> #include <linux/clk-provider.h>
> #include <linux/cpufreq.h>
> -#include <linux/of.h>
> +#include <linux/of_device.h>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> #include <asm/proc-fns.h>
> @@ -175,9 +175,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
> if (IS_ERR(priv.base))
> return PTR_ERR(priv.base);
>
> - np = of_find_node_by_path("/cpus/cpu@0");
> - if (!np)
> + np = of_cpu_device_node_get(0);
> + if (!np) {
> + dev_err(&pdev->dev, "failed to get cpu device node\n");
> return -ENODEV;
> + }
>
> priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
> if (IS_ERR(priv.cpu_clk)) {
> --
> 1.8.1.2

Hi Sudeep

I've not had chance to test it, but it looks O.K.

Acked-by: Andrew Lunn <[email protected]>

Andrew

2013-07-23 10:53:59

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

This patch adds of_get_cpu_node to retrieve a cpu device node for a
given logical cpu index. The default matching of the physical id to the
logical cpu index can be overridden by architecture specific code.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Acked-by: Rob Herring <[email protected]>
Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/of/base.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 6 +++++
3 files changed, 80 insertions(+)

----------------->8--------------------------
Hi Nico,

I found include/linux/cpu.h is more appropriate for this.
Is that fine ?

Regards,
Sudeep

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..052b4b2 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -18,6 +18,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/ctype.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spinlock.h>
@@ -230,6 +231,78 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical index of a cpu
+ * @phys_id: physical identifier of a cpu
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index.
+ *
+ * Returns true if the physical identifier and the logical index correspond
+ * to the same cpu, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to initialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu)
+{
+ struct device_node *cpun, *cpus;
+ const __be32 *cell;
+ u64 hwid;
+ int ac, prop_len;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }
+
+ if (of_property_read_u32(cpus, "#address-cells", &ac)) {
+ pr_warn("%s: missing #address-cells\n", cpus->full_name);
+ ac = of_n_addr_cells(cpus);
+ }
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+ cell = of_get_property(cpun, "reg", &prop_len);
+ if (!cell) {
+ pr_warn("%s: missing reg property\n", cpun->full_name);
+ continue;
+ }
+ prop_len /= sizeof(*cell);
+ while (prop_len) {
+ hwid = of_read_number(cell, ac);
+ prop_len -= ac;
+ if (arch_match_cpu_phys_id(cpu, hwid))
+ return cpun;
+ }
+ }
+
+ return NULL;
+}
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index ab0eade..d0c8204 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -34,6 +34,7 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr);

extern int cpu_add_dev_attr_group(struct attribute_group *attrs);
extern void cpu_remove_dev_attr_group(struct attribute_group *attrs);
+extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);

#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *cpu);
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..9e82812 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -459,6 +460,11 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}

+static inline struct device_node *of_get_cpu_node(int cpu)
+{
+ return NULL;
+}
+
static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
{
--
1.8.1.2

2013-07-26 17:14:46

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 07/16] of/device: add helper to get cpu device node from logical cpu index

Rob,

On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Multiple drivers need to get the cpu device node from the cpu logical
> index and then access the of_node.
>
> This patch adds helper function to fetch the device node directly.
>
> Cc: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

If you have no objections with this patch, can I add your ACK ?

Regards,
Sudeep

> ---
> include/linux/of_device.h | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
> index 9d27475..82ce324 100644
> --- a/include/linux/of_device.h
> +++ b/include/linux/of_device.h
> @@ -1,6 +1,7 @@
> #ifndef _LINUX_OF_DEVICE_H
> #define _LINUX_OF_DEVICE_H
>
> +#include <linux/cpu.h>
> #include <linux/platform_device.h>
> #include <linux/of_platform.h> /* temporary until merge */
>
> @@ -43,6 +44,15 @@ static inline void of_device_node_put(struct device *dev)
> of_node_put(dev->of_node);
> }
>
> +static inline struct device_node *of_cpu_device_node_get(int cpu)
> +{
> + struct device *cpu_dev;
> + cpu_dev = get_cpu_device(cpu);
> + if (!cpu_dev)
> + return NULL;
> + return of_node_get(cpu_dev->of_node);
> +}
> +
> #else /* CONFIG_OF */
>
> static inline int of_driver_match_device(struct device *dev,
> @@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device(
> {
> return NULL;
> }
> +
> +static inline struct device_node *of_cpu_device_node_get(int cpu)
> +{
> + return NULL;
> +}
> #endif /* CONFIG_OF */
>
> #endif /* _LINUX_OF_DEVICE_H */
>


-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

2013-07-26 18:55:38

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v3 07/16] of/device: add helper to get cpu device node from logical cpu index

On Fri, Jul 26, 2013 at 12:01 PM, Sudeep KarkadaNagesha
<[email protected]> wrote:
> Rob,
>
> On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Multiple drivers need to get the cpu device node from the cpu logical
>> index and then access the of_node.
>>
>> This patch adds helper function to fetch the device node directly.
>>
>> Cc: Rob Herring <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> If you have no objections with this patch, can I add your ACK ?

Yes.

Acked-by: Rob Herring <[email protected]>

>
> Regards,
> Sudeep
>
>> ---
>> include/linux/of_device.h | 15 +++++++++++++++
>> 1 file changed, 15 insertions(+)
>>
>> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
>> index 9d27475..82ce324 100644
>> --- a/include/linux/of_device.h
>> +++ b/include/linux/of_device.h
>> @@ -1,6 +1,7 @@
>> #ifndef _LINUX_OF_DEVICE_H
>> #define _LINUX_OF_DEVICE_H
>>
>> +#include <linux/cpu.h>
>> #include <linux/platform_device.h>
>> #include <linux/of_platform.h> /* temporary until merge */
>>
>> @@ -43,6 +44,15 @@ static inline void of_device_node_put(struct device *dev)
>> of_node_put(dev->of_node);
>> }
>>
>> +static inline struct device_node *of_cpu_device_node_get(int cpu)
>> +{
>> + struct device *cpu_dev;
>> + cpu_dev = get_cpu_device(cpu);
>> + if (!cpu_dev)
>> + return NULL;
>> + return of_node_get(cpu_dev->of_node);
>> +}
>> +
>> #else /* CONFIG_OF */
>>
>> static inline int of_driver_match_device(struct device *dev,
>> @@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device(
>> {
>> return NULL;
>> }
>> +
>> +static inline struct device_node *of_cpu_device_node_get(int cpu)
>> +{
>> + return NULL;
>> +}
>> #endif /* CONFIG_OF */
>>
>> #endif /* _LINUX_OF_DEVICE_H */
>>
>
>
> -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2013-08-01 09:54:27

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently set_secondary_cpus_clock assume the CPU logical ordering
> and the MPDIR in DT are same, which is incorrect.
>
> Since the CPU device nodes can be retrieved in the logical ordering
> using the DT helper, we can remove the devices tree parsing.
>
> This patch removes DT parsing by making use of of_get_cpu_node.
>
> Cc: Gregory Clement <[email protected]>
> Cc: Andrew Lunn <[email protected]>
> Cc: Jason Cooper <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Hi Gregory/Andrew/Jason,

Does this change look fine for mvebu?
If yes, can I have your ACKs ?

Regards,
Sudeep
> ---
> arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
> 1 file changed, 24 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
> index ce81d30..001dd42 100644
> --- a/arch/arm/mach-mvebu/platsmp.c
> +++ b/arch/arm/mach-mvebu/platsmp.c
> @@ -23,51 +23,47 @@
> #include <linux/of.h>
> #include <linux/mbus.h>
> #include <asm/cacheflush.h>
> +#include <asm/prom.h>
> #include <asm/smp_plat.h>
> #include "common.h"
> #include "armada-370-xp.h"
> #include "pmsu.h"
> #include "coherency.h"
>
> +static struct clk *__init get_cpu_clk(int cpu)
> +{
> + struct clk *cpu_clk;
> + struct device_node *np = of_get_cpu_node(cpu);
> +
> + if (WARN(!np, "missing cpu node\n"))
> + return NULL;
> + cpu_clk = of_clk_get(np, 0);
> + if (WARN_ON(IS_ERR(cpu_clk)))
> + return NULL;
> + return cpu_clk;
> +}
> +
> void __init set_secondary_cpus_clock(void)
> {
> - int thiscpu;
> + int thiscpu, cpu;
> unsigned long rate;
> - struct clk *cpu_clk = NULL;
> - struct device_node *np = NULL;
> + struct clk *cpu_clk;
>
> thiscpu = smp_processor_id();
> - for_each_node_by_type(np, "cpu") {
> - int err;
> - int cpu;
> -
> - err = of_property_read_u32(np, "reg", &cpu);
> - if (WARN_ON(err))
> - return;
> -
> - if (cpu == thiscpu) {
> - cpu_clk = of_clk_get(np, 0);
> - break;
> - }
> - }
> - if (WARN_ON(IS_ERR(cpu_clk)))
> + cpu_clk = get_cpu_clk(thiscpu);
> + if (!cpu_clk)
> return;
> clk_prepare_enable(cpu_clk);
> rate = clk_get_rate(cpu_clk);
>
> /* set all the other CPU clk to the same rate than the boot CPU */
> - for_each_node_by_type(np, "cpu") {
> - int err;
> - int cpu;
> -
> - err = of_property_read_u32(np, "reg", &cpu);
> - if (WARN_ON(err))
> + for_each_possible_cpu(cpu) {
> + if (cpu == thiscpu)
> + continue;
> + cpu_clk = get_cpu_clk(cpu);
> + if (!cpu_clk)
> return;
> -
> - if (cpu != thiscpu) {
> - cpu_clk = of_clk_get(np, 0);
> - clk_set_rate(cpu_clk, rate);
> - }
> + clk_set_rate(cpu_clk, rate);
> }
> }
>
>

2013-08-01 10:04:44

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 00/16] DT/core: update cpu device of_node

On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> As more and more information is getting added into the cpu node, the number
> of drivers needing to parse the device tree for CPU nodes are increasing.
> Most of the time, the information needed from the cpu node is preferred
> in the logical CPU order. Hence many drivers first parse and search the
> CPU node, match them to logical index if needed and then search for the
> required property inside a particular cpu node. Some of them assume the
> logical and physical CPU ordering to be same which is incorrect.
>
> This patch series initialises the of_node in all the cpu devices when
> registering the CPU device.
> 1. This avoids different drivers having to parse the cpu nodes to obtain
> different attributes like operating points, latency,...etc.
> 2. This handles different physical and logical cpu ordering which is not
> the case in current code.
> 3. Also all the cpu nodes will have their of_node initialised correctly.
> Currently different drivers assign them partially and incorrectly.
> 4. Removes all the reduntant parsing in various drivers.
>
> Changes v2->v3:
> 1. Added new OF helper to get of_node from the cpu logical index.
> With the use of this help, removed lots of duplicated code from
> cpufreq drivers.
> 2. Fixed issue with property length calculation in of_get_cpu_node.
> (previously had assumed of_get_property returns number of cells)
> 3. Changed return type of arch_match_cpu_phys_id to bool(as suggested by Nico)
> 4. Re-ordered patch 2 and 3, and few typo fixes.
> 5. Rebased on v3.11-rc2(to avoid any conflicts with __cpuinit* deletion)
>
> Changes v1->v2:
> 1. Moved most of arch_of_get_cpu_node to OF/DT core as of_get_cpu_node
> adding a provision for architecture specific hooks for matching
> logical and physical ids.
> 2. Extended removal of DT cpu node parsing to PPC cpufreq drivers
> 3. Added Acks from Viresh and Shawn
>
> Regards,
> Sudeep
>
> Sudeep KarkadaNagesha (16):
Hi Rob,Olof,Rafael,

Since these changes are spread across multiple sub-systems, is it fine
if I split this and send pull request as below:

1. DT
of: add support for retrieving cpu node for a given logical cpu index
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
driver/core: cpu: initialize of_node in cpu's device struture
of/device: add helper to get cpu device node from logical cpu index
2. ARM SoC(clearly specifying dependency on 1)
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
ARM: mvebu: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
3. CPUFreq(clearly specifying dependency on 1)
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

Regards,
Sudeep

> arch/arm/kernel/devtree.c | 5 +++
> arch/arm/kernel/topology.c | 61 ++++++++++---------------------
> arch/arm/mach-imx/mach-imx6q.c | 3 +-
> arch/arm/mach-mvebu/platsmp.c | 52 +++++++++++++--------------
> drivers/base/cpu.c | 2 ++
> drivers/bus/arm-cci.c | 28 ++++-----------
> drivers/cpufreq/arm_big_little_dt.c | 40 ++++++++-------------
> drivers/cpufreq/cpufreq-cpu0.c | 23 +++---------
> drivers/cpufreq/highbank-cpufreq.c | 18 ++++------
> drivers/cpufreq/imx6q-cpufreq.c | 4 +--
> drivers/cpufreq/kirkwood-cpufreq.c | 8 +++--
> drivers/cpufreq/maple-cpufreq.c | 23 ++----------
> drivers/cpufreq/pmac32-cpufreq.c | 5 +--
> drivers/cpufreq/pmac64-cpufreq.c | 47 ++++++------------------
> drivers/cpufreq/spear-cpufreq.c | 4 +--
> drivers/of/base.c | 72 +++++++++++++++++++++++++++++++++++++
> include/linux/of.h | 6 ++++
> include/linux/of_device.h | 15 ++++++++
> 18 files changed, 200 insertions(+), 216 deletions(-)
>

2013-08-01 12:03:22

by Jason Cooper

[permalink] [raw]
Subject: Re: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

Sudeep,

On Thu, Aug 01, 2013 at 10:54:44AM +0100, Sudeep KarkadaNagesha wrote:
> On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
> > From: Sudeep KarkadaNagesha <[email protected]>
> >
> > Currently set_secondary_cpus_clock assume the CPU logical ordering
> > and the MPDIR in DT are same, which is incorrect.
> >
> > Since the CPU device nodes can be retrieved in the logical ordering
> > using the DT helper, we can remove the devices tree parsing.
> >
> > This patch removes DT parsing by making use of of_get_cpu_node.
> >
> > Cc: Gregory Clement <[email protected]>
> > Cc: Andrew Lunn <[email protected]>
> > Cc: Jason Cooper <[email protected]>
> > Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> Hi Gregory/Andrew/Jason,
>
> Does this change look fine for mvebu?
> If yes, can I have your ACKs ?

Gregory is the one best suited to review/Ack this. He'll be back on
Monday.

thx,

Jason.

>
> Regards,
> Sudeep
> > ---
> > arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
> > 1 file changed, 24 insertions(+), 28 deletions(-)
> >
> > diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
> > index ce81d30..001dd42 100644
> > --- a/arch/arm/mach-mvebu/platsmp.c
> > +++ b/arch/arm/mach-mvebu/platsmp.c
> > @@ -23,51 +23,47 @@
> > #include <linux/of.h>
> > #include <linux/mbus.h>
> > #include <asm/cacheflush.h>
> > +#include <asm/prom.h>
> > #include <asm/smp_plat.h>
> > #include "common.h"
> > #include "armada-370-xp.h"
> > #include "pmsu.h"
> > #include "coherency.h"
> >
> > +static struct clk *__init get_cpu_clk(int cpu)
> > +{
> > + struct clk *cpu_clk;
> > + struct device_node *np = of_get_cpu_node(cpu);
> > +
> > + if (WARN(!np, "missing cpu node\n"))
> > + return NULL;
> > + cpu_clk = of_clk_get(np, 0);
> > + if (WARN_ON(IS_ERR(cpu_clk)))
> > + return NULL;
> > + return cpu_clk;
> > +}
> > +
> > void __init set_secondary_cpus_clock(void)
> > {
> > - int thiscpu;
> > + int thiscpu, cpu;
> > unsigned long rate;
> > - struct clk *cpu_clk = NULL;
> > - struct device_node *np = NULL;
> > + struct clk *cpu_clk;
> >
> > thiscpu = smp_processor_id();
> > - for_each_node_by_type(np, "cpu") {
> > - int err;
> > - int cpu;
> > -
> > - err = of_property_read_u32(np, "reg", &cpu);
> > - if (WARN_ON(err))
> > - return;
> > -
> > - if (cpu == thiscpu) {
> > - cpu_clk = of_clk_get(np, 0);
> > - break;
> > - }
> > - }
> > - if (WARN_ON(IS_ERR(cpu_clk)))
> > + cpu_clk = get_cpu_clk(thiscpu);
> > + if (!cpu_clk)
> > return;
> > clk_prepare_enable(cpu_clk);
> > rate = clk_get_rate(cpu_clk);
> >
> > /* set all the other CPU clk to the same rate than the boot CPU */
> > - for_each_node_by_type(np, "cpu") {
> > - int err;
> > - int cpu;
> > -
> > - err = of_property_read_u32(np, "reg", &cpu);
> > - if (WARN_ON(err))
> > + for_each_possible_cpu(cpu) {
> > + if (cpu == thiscpu)
> > + continue;
> > + cpu_clk = get_cpu_clk(cpu);
> > + if (!cpu_clk)
> > return;
> > -
> > - if (cpu != thiscpu) {
> > - cpu_clk = of_clk_get(np, 0);
> > - clk_set_rate(cpu_clk, rate);
> > - }
> > + clk_set_rate(cpu_clk, rate);
> > }
> > }
> >
> >
>
>

2013-08-05 16:28:31

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

On 01/08/13 13:02, Jason Cooper wrote:
> Sudeep,
>
> On Thu, Aug 01, 2013 at 10:54:44AM +0100, Sudeep KarkadaNagesha wrote:
>> On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
>>> From: Sudeep KarkadaNagesha <[email protected]>
>>>
>>> Currently set_secondary_cpus_clock assume the CPU logical ordering
>>> and the MPDIR in DT are same, which is incorrect.
>>>
>>> Since the CPU device nodes can be retrieved in the logical ordering
>>> using the DT helper, we can remove the devices tree parsing.
>>>
>>> This patch removes DT parsing by making use of of_get_cpu_node.
>>>
>>> Cc: Gregory Clement <[email protected]>
>>> Cc: Andrew Lunn <[email protected]>
>>> Cc: Jason Cooper <[email protected]>
>>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>>
>> Hi Gregory/Andrew/Jason,
>>
>> Does this change look fine for mvebu?
>> If yes, can I have your ACKs ?
>
> Gregory is the one best suited to review/Ack this. He'll be back on
> Monday.
>
Hi Gregory,

Can you please review this patch ?

Regards,
Sudeep
>>> ---
>>> arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
>>> 1 file changed, 24 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
>>> index ce81d30..001dd42 100644
>>> --- a/arch/arm/mach-mvebu/platsmp.c
>>> +++ b/arch/arm/mach-mvebu/platsmp.c
>>> @@ -23,51 +23,47 @@
>>> #include <linux/of.h>
>>> #include <linux/mbus.h>
>>> #include <asm/cacheflush.h>
>>> +#include <asm/prom.h>
>>> #include <asm/smp_plat.h>
>>> #include "common.h"
>>> #include "armada-370-xp.h"
>>> #include "pmsu.h"
>>> #include "coherency.h"
>>>
>>> +static struct clk *__init get_cpu_clk(int cpu)
>>> +{
>>> + struct clk *cpu_clk;
>>> + struct device_node *np = of_get_cpu_node(cpu);
>>> +
>>> + if (WARN(!np, "missing cpu node\n"))
>>> + return NULL;
>>> + cpu_clk = of_clk_get(np, 0);
>>> + if (WARN_ON(IS_ERR(cpu_clk)))
>>> + return NULL;
>>> + return cpu_clk;
>>> +}
>>> +
>>> void __init set_secondary_cpus_clock(void)
>>> {
>>> - int thiscpu;
>>> + int thiscpu, cpu;
>>> unsigned long rate;
>>> - struct clk *cpu_clk = NULL;
>>> - struct device_node *np = NULL;
>>> + struct clk *cpu_clk;
>>>
>>> thiscpu = smp_processor_id();
>>> - for_each_node_by_type(np, "cpu") {
>>> - int err;
>>> - int cpu;
>>> -
>>> - err = of_property_read_u32(np, "reg", &cpu);
>>> - if (WARN_ON(err))
>>> - return;
>>> -
>>> - if (cpu == thiscpu) {
>>> - cpu_clk = of_clk_get(np, 0);
>>> - break;
>>> - }
>>> - }
>>> - if (WARN_ON(IS_ERR(cpu_clk)))
>>> + cpu_clk = get_cpu_clk(thiscpu);
>>> + if (!cpu_clk)
>>> return;
>>> clk_prepare_enable(cpu_clk);
>>> rate = clk_get_rate(cpu_clk);
>>>
>>> /* set all the other CPU clk to the same rate than the boot CPU */
>>> - for_each_node_by_type(np, "cpu") {
>>> - int err;
>>> - int cpu;
>>> -
>>> - err = of_property_read_u32(np, "reg", &cpu);
>>> - if (WARN_ON(err))
>>> + for_each_possible_cpu(cpu) {
>>> + if (cpu == thiscpu)
>>> + continue;
>>> + cpu_clk = get_cpu_clk(cpu);
>>> + if (!cpu_clk)
>>> return;
>>> -
>>> - if (cpu != thiscpu) {
>>> - cpu_clk = of_clk_get(np, 0);
>>> - clk_set_rate(cpu_clk, rate);
>>> - }
>>> + clk_set_rate(cpu_clk, rate);
>>> }
>>> }
>>>
>>>
>>
>>
>

2013-08-06 08:36:40

by Gregory CLEMENT

[permalink] [raw]
Subject: Re: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

On 05/08/2013 18:28, Sudeep KarkadaNagesha wrote:
> On 01/08/13 13:02, Jason Cooper wrote:
>> Sudeep,
>>
>> On Thu, Aug 01, 2013 at 10:54:44AM +0100, Sudeep KarkadaNagesha wrote:
>>> On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
>>>> From: Sudeep KarkadaNagesha <[email protected]>
>>>>
>>>> Currently set_secondary_cpus_clock assume the CPU logical ordering
>>>> and the MPDIR in DT are same, which is incorrect.
>>>>
>>>> Since the CPU device nodes can be retrieved in the logical ordering
>>>> using the DT helper, we can remove the devices tree parsing.
>>>>
>>>> This patch removes DT parsing by making use of of_get_cpu_node.
>>>>
>>>> Cc: Gregory Clement <[email protected]>
>>>> Cc: Andrew Lunn <[email protected]>
>>>> Cc: Jason Cooper <[email protected]>
>>>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>>>
>>> Hi Gregory/Andrew/Jason,
>>>
>>> Does this change look fine for mvebu?
>>> If yes, can I have your ACKs ?
>>
>> Gregory is the one best suited to review/Ack this. He'll be back on
>> Monday.
>>
> Hi Gregory,
>
> Can you please review this patch ?

Your patch is a nice improvement, I reviewed it and I also tested it on the
Armada XP DB board.

You can add my:
Acked-by: Gregory Clement <[email protected]>

>
> Regards,
> Sudeep
>>>> ---
>>>> arch/arm/mach-mvebu/platsmp.c | 52 ++++++++++++++++++++-----------------------
>>>> 1 file changed, 24 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
>>>> index ce81d30..001dd42 100644
>>>> --- a/arch/arm/mach-mvebu/platsmp.c
>>>> +++ b/arch/arm/mach-mvebu/platsmp.c
>>>> @@ -23,51 +23,47 @@
>>>> #include <linux/of.h>
>>>> #include <linux/mbus.h>
>>>> #include <asm/cacheflush.h>
>>>> +#include <asm/prom.h>
>>>> #include <asm/smp_plat.h>
>>>> #include "common.h"
>>>> #include "armada-370-xp.h"
>>>> #include "pmsu.h"
>>>> #include "coherency.h"
>>>>
>>>> +static struct clk *__init get_cpu_clk(int cpu)
>>>> +{
>>>> + struct clk *cpu_clk;
>>>> + struct device_node *np = of_get_cpu_node(cpu);
>>>> +
>>>> + if (WARN(!np, "missing cpu node\n"))
>>>> + return NULL;
>>>> + cpu_clk = of_clk_get(np, 0);
>>>> + if (WARN_ON(IS_ERR(cpu_clk)))
>>>> + return NULL;
>>>> + return cpu_clk;
>>>> +}
>>>> +
>>>> void __init set_secondary_cpus_clock(void)
>>>> {
>>>> - int thiscpu;
>>>> + int thiscpu, cpu;
>>>> unsigned long rate;
>>>> - struct clk *cpu_clk = NULL;
>>>> - struct device_node *np = NULL;
>>>> + struct clk *cpu_clk;
>>>>
>>>> thiscpu = smp_processor_id();
>>>> - for_each_node_by_type(np, "cpu") {
>>>> - int err;
>>>> - int cpu;
>>>> -
>>>> - err = of_property_read_u32(np, "reg", &cpu);
>>>> - if (WARN_ON(err))
>>>> - return;
>>>> -
>>>> - if (cpu == thiscpu) {
>>>> - cpu_clk = of_clk_get(np, 0);
>>>> - break;
>>>> - }
>>>> - }
>>>> - if (WARN_ON(IS_ERR(cpu_clk)))
>>>> + cpu_clk = get_cpu_clk(thiscpu);
>>>> + if (!cpu_clk)
>>>> return;
>>>> clk_prepare_enable(cpu_clk);
>>>> rate = clk_get_rate(cpu_clk);
>>>>
>>>> /* set all the other CPU clk to the same rate than the boot CPU */
>>>> - for_each_node_by_type(np, "cpu") {
>>>> - int err;
>>>> - int cpu;
>>>> -
>>>> - err = of_property_read_u32(np, "reg", &cpu);
>>>> - if (WARN_ON(err))
>>>> + for_each_possible_cpu(cpu) {
>>>> + if (cpu == thiscpu)
>>>> + continue;
>>>> + cpu_clk = get_cpu_clk(cpu);
>>>> + if (!cpu_clk)
>>>> return;
>>>> -
>>>> - if (cpu != thiscpu) {
>>>> - cpu_clk = of_clk_get(np, 0);
>>>> - clk_set_rate(cpu_clk, rate);
>>>> - }
>>>> + clk_set_rate(cpu_clk, rate);
>>>> }
>>>> }
>>>>
>>>>
>>>
>>>
>>
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>


--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

2013-08-06 09:02:44

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 05/16] ARM: mvebu: remove device tree parsing for cpu nodes

On 06/08/13 09:25, Gregory CLEMENT wrote:
> On 05/08/2013 18:28, Sudeep KarkadaNagesha wrote:
>> On 01/08/13 13:02, Jason Cooper wrote:
>>> Sudeep,
>>>
>>> On Thu, Aug 01, 2013 at 10:54:44AM +0100, Sudeep KarkadaNagesha wrote:
>>>> On 22/07/13 12:32, Sudeep KarkadaNagesha wrote:
>>>>> From: Sudeep KarkadaNagesha <[email protected]>
>>>>>
>>>>> Currently set_secondary_cpus_clock assume the CPU logical ordering
>>>>> and the MPDIR in DT are same, which is incorrect.
>>>>>
>>>>> Since the CPU device nodes can be retrieved in the logical ordering
>>>>> using the DT helper, we can remove the devices tree parsing.
>>>>>
>>>>> This patch removes DT parsing by making use of of_get_cpu_node.
>>>>>
>>>>> Cc: Gregory Clement <[email protected]>
>>>>> Cc: Andrew Lunn <[email protected]>
>>>>> Cc: Jason Cooper <[email protected]>
>>>>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>>>>
>>>> Hi Gregory/Andrew/Jason,
>>>>
>>>> Does this change look fine for mvebu?
>>>> If yes, can I have your ACKs ?
>>>
>>> Gregory is the one best suited to review/Ack this. He'll be back on
>>> Monday.
>>>
>> Hi Gregory,
>>
>> Can you please review this patch ?
>
> Your patch is a nice improvement, I reviewed it and I also tested it on the
> Armada XP DB board.
>
> You can add my:
> Acked-by: Gregory Clement <[email protected]>

Thanks Gregory.

Regards,
Sudeep

2013-08-15 11:32:29

by Tomasz Figa

[permalink] [raw]
Subject: Re: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

Hi Sudeep,

I don't like this constant DT parsing every time a node of given CPU is
required, but I believe it was correctly discussed with people that are
more into CPU topologies and similar things than me. (My idea would be to
make a lookup array with logical ID to struct device_node * mapping.)

Let me just review this from DT parsing perspective.

On Monday 22 of July 2013 12:32:12 Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> This patch adds of_get_cpu_node to retrieve a cpu device node for a
> given logical cpu index. The default matching of the physical id to the
> logical cpu index can be overridden by architecture specific code.
>
> It is recommended to use these helper function only in pre-SMP/early
> initialisation stages to retrieve CPU device node pointers in logical
> ordering. Once the cpu devices are registered, it can be retrieved
> easily from cpu device of_node which avoids unnecessary parsing and
> matching.
>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/of/base.c | 72
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of.h | 6 +++++
> 2 files changed, 78 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 5c54279..1e690bf 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -230,6 +230,78 @@ const void *of_get_property(const struct
> device_node *np, const char *name, }
> EXPORT_SYMBOL(of_get_property);
>
> +/*
> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
> + *
> + * @cpu: logical index of a cpu
> + * @phys_id: physical identifier of a cpu
> + *
> + * CPU logical to physical index mapping is architecture specific.
> + * However this __weak function provides a default match of physical
> + * id to logical cpu index.
> + *
> + * Returns true if the physical identifier and the logical index
> correspond + * to the same cpu, false otherwise.
> + */
> +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (u32)phys_id == cpu;
> +}
> +
> +/**
> + * of_get_cpu_node - Get device node associated with the given logical
> CPU + *
> + * @cpu: CPU number(logical index) for which device node is required
> + *
> + * The main purpose of this function is to retrieve the device node for
> the + * given logical CPU index. It should be used to intialize the
> of_node in + * cpu device. Once of_node in cpu device is populated, all
> the further + * references can use that instead.
> + *
> + * CPU logical to physical index mapping is architecture specific and
> is built + * before booting secondary cores. This function uses
> arch_match_cpu_phys_id + * which can be overridden by architecture
> specific implementation. + *
> + * Returns a node pointer for the logical cpu if found, else NULL.
> + */
> +struct device_node *of_get_cpu_node(int cpu)
> +{
> + struct device_node *cpun, *cpus;
> + const __be32 *cell;
> + u64 hwid;
> + int ac, prop_len;
> +
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
> +
> + if (of_property_read_u32(cpus, "#address-cells", &ac)) {
> + pr_warn("%s: missing #address-cells\n", cpus->full_name);
> + ac = of_n_addr_cells(cpus);

I'm not sure this fallback is appropriate. According to ePAPR:

"The #address-cells and #size-cells properties are not inherited from
ancestors in the device tree. They shall be explicitly defined."

In addition:

If missing, a client program should assume a default value of 2 for
#address-cells, and a value of 1 for #size-cells.

This also leaves in question the correctness of of_n_addr_cells() and
of_n_size_cells().

> + }
> +
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
> + cell = of_get_property(cpun, "reg", &prop_len);
> + if (!cell) {
> + pr_warn("%s: missing reg property\n", cpun-
>full_name);
> + continue;
> + }
> + prop_len /= sizeof(*cell);
> + while (prop_len) {
> + hwid = of_read_number(cell, ac);
> + prop_len -= ac;
> + if (arch_match_cpu_phys_id(cpu, hwid))
> + return cpun;

This is a nice potential infinite loop. Consider following example:

cpus {
#address-cells = <2>; /* A typo. Should be 1. */
#size-cells = <0>;

cpu@0 {
/* ... */
reg = <0>;
};
};

In this case prop_len will start with 1, while ac will be 2. After first
iteration of the loop (when the phys id doesn't match) you will end up
with prop_len = -1 and each iteration will decrement it even more.

By the way, I'm not sure why the whole loop is here. IMHO it should be
something like:

if (prop_len != ac) {
pr_warn(...); // or whatever
continue;
}

hwid = of_read_number(cell, ac);
// ...

Best regards,
Tomasz


Attachments:
signature.asc (836.00 B)
This is a digitally signed message part.

2013-08-15 11:35:49

by Tomasz Figa

[permalink] [raw]
Subject: Re: [PATCH v3 03/16] driver/core: cpu: initialize of_node in cpu's device struture

Hi Sudeep,

On Monday 22 of July 2013 12:32:14 Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> CPUs are also registered as devices but the of_node in these cpu
> devices are not initialized. Currently different drivers requiring
> to access cpu device node are parsing the nodes themselves and
> initialising the of_node in cpu device.
>
> The of_node in all the cpu devices needs to be initialized properly
> and at one place. The best place to update this is CPU subsystem
> driver when registering the cpu devices.
>
> The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
> device node for a given logical index by abstracting the architecture
> specific details.
>
> This patch uses of_get_cpu_node to assign of_node when registering the
> cpu devices.
>
> Cc: Greg Kroah-Hartman <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/base/cpu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
> index 4c358bc..ea51c6d 100644
> --- a/drivers/base/cpu.c
> +++ b/drivers/base/cpu.c
> @@ -14,6 +14,7 @@
> #include <linux/slab.h>
> #include <linux/percpu.h>
> #include <linux/acpi.h>
> +#include <linux/of.h>
>
> #include "base.h"
>
> @@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
> cpu->dev.release = cpu_device_release;
> cpu->dev.offline_disabled = !cpu->hotpluggable;
> cpu->dev.offline = !cpu_online(num);
> + cpu->dev.of_node = of_get_cpu_node(num);

Aha, so this would be the only place where of_get_cpu_node() gets called,
so the parsing would be done only once and then any code that needs CPU DT
node would just simply grab it from CPU dev. Fair enough.

Not sure if this makes the need for such helper to be globally available
in of/base.c, but I guess this won't hurt.

Best regards,
Tomasz


Attachments:
signature.asc (836.00 B)
This is a digitally signed message part.

2013-08-15 14:59:19

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 01/16] of: add support for retrieving cpu node for a given logical cpu index

On 15/08/13 12:32, Tomasz Figa wrote:
> Hi Sudeep,
>
> I don't like this constant DT parsing every time a node of given CPU is
> required, but I believe it was correctly discussed with people that are
> more into CPU topologies and similar things than me. (My idea would be to
> make a lookup array with logical ID to struct device_node * mapping.)
>
Yes that's the idea, see the last paragraph in the commit log.

> Let me just review this from DT parsing perspective.
>
> On Monday 22 of July 2013 12:32:12 Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>>
>> It's better to consolidate them by adding support for getting cpu
>> device node for a given logical cpu index in DT core library. However
>> logical to physical index mapping can be architecture specific.
>>
>> This patch adds of_get_cpu_node to retrieve a cpu device node for a
>> given logical cpu index. The default matching of the physical id to the
>> logical cpu index can be overridden by architecture specific code.
>>
>> It is recommended to use these helper function only in pre-SMP/early
>> initialisation stages to retrieve CPU device node pointers in logical
>> ordering. Once the cpu devices are registered, it can be retrieved
>> easily from cpu device of_node which avoids unnecessary parsing and
>> matching.
>>
Here we go, do I need to emphasis this recommendation more ?

>> Acked-by: Rob Herring <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>> ---
>> drivers/of/base.c | 72
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/of.h | 6 +++++
>> 2 files changed, 78 insertions(+)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index 5c54279..1e690bf 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -230,6 +230,78 @@ const void *of_get_property(const struct
>> device_node *np, const char *name, }
>> EXPORT_SYMBOL(of_get_property);
>>
>> +/*
>> + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
>> + *
>> + * @cpu: logical index of a cpu
>> + * @phys_id: physical identifier of a cpu
>> + *
>> + * CPU logical to physical index mapping is architecture specific.
>> + * However this __weak function provides a default match of physical
>> + * id to logical cpu index.
>> + *
>> + * Returns true if the physical identifier and the logical index
>> correspond + * to the same cpu, false otherwise.
>> + */
>> +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
>> +{
>> + return (u32)phys_id == cpu;
>> +}
>> +
>> +/**
>> + * of_get_cpu_node - Get device node associated with the given logical
>> CPU + *
>> + * @cpu: CPU number(logical index) for which device node is required
>> + *
>> + * The main purpose of this function is to retrieve the device node for
>> the + * given logical CPU index. It should be used to intialize the
>> of_node in + * cpu device. Once of_node in cpu device is populated, all
>> the further + * references can use that instead.
>> + *
>> + * CPU logical to physical index mapping is architecture specific and
>> is built + * before booting secondary cores. This function uses
>> arch_match_cpu_phys_id + * which can be overridden by architecture
>> specific implementation. + *
>> + * Returns a node pointer for the logical cpu if found, else NULL.
>> + */
>> +struct device_node *of_get_cpu_node(int cpu)
>> +{
>> + struct device_node *cpun, *cpus;
>> + const __be32 *cell;
>> + u64 hwid;
>> + int ac, prop_len;
>> +
>> + cpus = of_find_node_by_path("/cpus");
>> + if (!cpus) {
>> + pr_warn("Missing cpus node, bailing out\n");
>> + return NULL;
>> + }
>> +
>> + if (of_property_read_u32(cpus, "#address-cells", &ac)) {
>> + pr_warn("%s: missing #address-cells\n", cpus->full_name);
>> + ac = of_n_addr_cells(cpus);
>
> I'm not sure this fallback is appropriate. According to ePAPR:
>
> "The #address-cells and #size-cells properties are not inherited from
> ancestors in the device tree. They shall be explicitly defined."
>
> In addition:
>
> If missing, a client program should assume a default value of 2 for
> #address-cells, and a value of 1 for #size-cells.
>
> This also leaves in question the correctness of of_n_addr_cells() and
> of_n_size_cells().
>
Yes agreed. We can discus that and fix it separately as it might affect
multiple users.

>> + }
>> +
>> + for_each_child_of_node(cpus, cpun) {
>> + if (of_node_cmp(cpun->type, "cpu"))
>> + continue;
>> + cell = of_get_property(cpun, "reg", &prop_len);
>> + if (!cell) {
>> + pr_warn("%s: missing reg property\n", cpun-
>> full_name);
>> + continue;
>> + }
>> + prop_len /= sizeof(*cell);
>> + while (prop_len) {
>> + hwid = of_read_number(cell, ac);
>> + prop_len -= ac;
>> + if (arch_match_cpu_phys_id(cpu, hwid))
>> + return cpun;
>
> This is a nice potential infinite loop. Consider following example:
>
Good point, but based on the other discussion recently with PPC guys to
support thread ids, I have changed this loop differently, it should not
have this issue.

Regards,
Sudeep

> cpus {
> #address-cells = <2>; /* A typo. Should be 1. */
> #size-cells = <0>;
>
> cpu@0 {
> /* ... */
> reg = <0>;
> };
> };
>
> In this case prop_len will start with 1, while ac will be 2. After first
> iteration of the loop (when the phys id doesn't match) you will end up
> with prop_len = -1 and each iteration will decrement it even more.
>
> By the way, I'm not sure why the whole loop is here. IMHO it should be
> something like:
>
> if (prop_len != ac) {
> pr_warn(...); // or whatever
> continue;
> }
>
> hwid = of_read_number(cell, ac);
> // ...
>
> Best regards,
> Tomasz
>

2013-08-15 15:13:35

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v3 03/16] driver/core: cpu: initialize of_node in cpu's device struture

On 15/08/13 12:35, Tomasz Figa wrote:
> Hi Sudeep,
>
> On Monday 22 of July 2013 12:32:14 Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> CPUs are also registered as devices but the of_node in these cpu
>> devices are not initialized. Currently different drivers requiring
>> to access cpu device node are parsing the nodes themselves and
>> initialising the of_node in cpu device.
>>
>> The of_node in all the cpu devices needs to be initialized properly
>> and at one place. The best place to update this is CPU subsystem
>> driver when registering the cpu devices.
>>
>> The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
>> device node for a given logical index by abstracting the architecture
>> specific details.
>>
>> This patch uses of_get_cpu_node to assign of_node when registering the
>> cpu devices.
>>
>> Cc: Greg Kroah-Hartman <[email protected]>
>> Acked-by: Rob Herring <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>> ---
>> drivers/base/cpu.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
>> index 4c358bc..ea51c6d 100644
>> --- a/drivers/base/cpu.c
>> +++ b/drivers/base/cpu.c
>> @@ -14,6 +14,7 @@
>> #include <linux/slab.h>
>> #include <linux/percpu.h>
>> #include <linux/acpi.h>
>> +#include <linux/of.h>
>>
>> #include "base.h"
>>
>> @@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
>> cpu->dev.release = cpu_device_release;
>> cpu->dev.offline_disabled = !cpu->hotpluggable;
>> cpu->dev.offline = !cpu_online(num);
>> + cpu->dev.of_node = of_get_cpu_node(num);
>
> Aha, so this would be the only place where of_get_cpu_node() gets called,
> so the parsing would be done only once and then any code that needs CPU DT
> node would just simply grab it from CPU dev. Fair enough.
>
> Not sure if this makes the need for such helper to be globally available
> in of/base.c, but I guess this won't hurt.
>
Ah, you found it out yourself. Sorry responded to your earlier mail.
Yes but there may be uses cases which need cpu of_node before CPUs get
registered. I believe PATCH 4-6 in the series is good examples as why we
need this helper to be global.

Move over now we need to extend support to PowerPC where DT is scanned
needlessly always to fetch cpu of_node. Of course they need to fix it,
use cpu->of_node instead.

Regards,
Sudeep

2013-08-15 17:10:11

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

PowerPC has it's own implementation to get the cpu node for a given
logical index.

This patch refactors the current implementation of of_get_cpu_node.
This in preparation to move the implementation to DT core library.
It separates out the logical to physical mapping so that a default
matching of the physical id to the logical cpu index can be added
when moved to common code. Architecture specific code can override it.

Cc: Rob Herring <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/kernel/prom.c | 70 ++++++++++++++++++++++++++++------------------
1 file changed, 43 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index eb23ac9..594c9f9 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -865,45 +865,61 @@ static int __init prom_reconfig_setup(void)
__initcall(prom_reconfig_setup);
#endif

+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (int)phys_id == get_hard_smp_processor_id(cpu);
+}
+
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ }
+ return false;
+}
+
/* Find the device node for a given logical cpu number, also returns the cpu
* local thread number (index in ibm,interrupt-server#s) if relevant and
* asked for (non NULL)
*/
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
{
- int hardid;
- struct device_node *np;
+ struct device_node *cpun, *cpus;

- hardid = get_hard_smp_processor_id(cpu);
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }

- for_each_node_by_type(np, "cpu") {
- const u32 *intserv;
- unsigned int plen, t;
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;

/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
* fallback to "reg" property and assume no threads
*/
- intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
- &plen);
- if (intserv == NULL) {
- const u32 *reg = of_get_property(np, "reg", NULL);
- if (reg == NULL)
- continue;
- if (*reg == hardid) {
- if (thread)
- *thread = 0;
- return np;
- }
- } else {
- plen /= sizeof(u32);
- for (t = 0; t < plen; t++) {
- if (hardid == intserv[t]) {
- if (thread)
- *thread = t;
- return np;
- }
- }
- }
+ if (__of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
}
return NULL;
}
--
1.8.1.2

2013-08-15 17:10:10

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH 2/4] openrisc: remove undefined of_get_cpu_node declaration

From: Sudeep KarkadaNagesha <[email protected]>

This patch removes the declaration of the function 'of_get_cpu_node'
which is not defined for openrisc. This is in preparation to move
it's definition from PPC to DT common code.

Again it could be there as it was originally copied from powerpc.

Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
Cc: Jonas Bonn <[email protected]>
---
arch/openrisc/include/asm/prom.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
index bbb34e5..eb59bfe 100644
--- a/arch/openrisc/include/asm/prom.h
+++ b/arch/openrisc/include/asm/prom.h
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
/* Get the MAC address */
extern const void *of_get_mac_address(struct device_node *np);

--
1.8.1.2

2013-08-15 17:10:08

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH 0/4] DT: move of_get_cpu_node from PPC to DT core

From: Sudeep KarkadaNagesha <[email protected]>

Hi,

This series needs to be prepended with the original series[1][2][3]
Except the first patch in the original series(which is merged into this
as last patch), there is no other change(apart from function signature)
I am posting only this part for feedback separately for review as the
original series is already reviewed. Once this part is review and aknowledged
I will combine the complete series and post it.

Hi Rob,

Since the compatible 'ibm,ppc-interrupt-server#s' is one-off and for
historical reasons, if future architectures are adhering to ePAPR,
IMO having a weak definition of arch_of_cpu_get_node as you suggested
could lead to it's misuse in future. So I didn't take that approach.

Regards,
Sudeep

Sudeep KarkadaNagesha (4):
microblaze: remove undefined of_get_cpu_node declaration
openrisc: remove undefined of_get_cpu_node declaration
powerpc: refactor of_get_cpu_node to support other architectures
of: move of_get_cpu_node implementation to DT core library

arch/microblaze/include/asm/prom.h | 3 --
arch/openrisc/include/asm/prom.h | 3 --
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 43 +----------------
drivers/of/base.c | 94 ++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
7 files changed, 104 insertions(+), 50 deletions(-)

--
1.8.1.2

[1] https://lkml.org/lkml/2013/7/15/128
[2] https://lkml.org/lkml/2013/7/17/341
[3] https://lkml.org/lkml/2013/7/22/219

2013-08-15 17:10:07

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH 1/4] microblaze: remove undefined of_get_cpu_node declaration

From: Sudeep KarkadaNagesha <[email protected]>

This patch removes the declaration of the function 'of_get_cpu_node'
which is not defined for microblaze. This is in preparation to move
it's definition from PPC to DT common code.

Michal Simek says: "it was just there because Microblaze
was based on powerpc code"

Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
Cc: Michal Simek <[email protected]>
---
arch/microblaze/include/asm/prom.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 20c5e8e..9977816 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -50,9 +50,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */

--
1.8.1.2

2013-08-15 17:11:28

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH 4/4] of: move of_get_cpu_node implementation to DT core library

From: Sudeep KarkadaNagesha <[email protected]>

This patch moves the generalized implementation of of_get_cpu_node from
PowerPC to DT core library, thereby adding support for retrieving cpu
node for a given logical cpu index on any architecture.

The CPU subsystem can now use this function to assign of_node in the
cpu device while registering CPUs.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Cc: Rob Herring <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 55 ------------------------
drivers/of/base.c | 94 +++++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
5 files changed, 102 insertions(+), 58 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index bc2da15..ac204e0 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
/* cache lookup */
struct device_node *of_find_next_cache_node(struct device_node *np);

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 594c9f9..1c14cd4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -870,61 +870,6 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
return (int)phys_id == get_hard_smp_processor_id(cpu);
}

-static bool __of_find_n_match_cpu_property(struct device_node *cpun,
- const char *prop_name, int cpu, unsigned int *thread)
-{
- const __be32 *cell;
- int ac, prop_len, tid;
- u64 hwid;
-
- ac = of_n_addr_cells(cpun);
- cell = of_get_property(cpun, prop_name, &prop_len);
- if (!cell)
- return false;
- prop_len /= sizeof(*cell);
- for (tid = 0; tid < prop_len; tid++) {
- hwid = of_read_number(cell, ac);
- if (arch_match_cpu_phys_id(cpu, hwid)) {
- if (thread)
- *thread = tid;
- return true;
- }
- }
- return false;
-}
-
-/* Find the device node for a given logical cpu number, also returns the cpu
- * local thread number (index in ibm,interrupt-server#s) if relevant and
- * asked for (non NULL)
- */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
-{
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (!cpus) {
- pr_warn("Missing cpus node, bailing out\n");
- return NULL;
- }
-
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
-
- /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
- * fallback to "reg" property and assume no threads
- */
- if (__of_find_n_match_cpu_property(cpun,
- "ibm,ppc-interrupt-server#s", cpu, thread))
- return cpun;
-
- if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
- return cpun;
- }
- return NULL;
-}
-EXPORT_SYMBOL(of_get_cpu_node);
-
#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
static struct debugfs_blob_wrapper flat_dt_blob;

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..d088e45 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -18,6 +18,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/ctype.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spinlock.h>
@@ -230,6 +231,99 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical index of a cpu
+ * @phys_id: physical identifier of a cpu
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index.
+ *
+ * Returns true if the physical identifier and the logical index correspond
+ * to the same cpu, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * Checks if the given "prop_name" property holds the physical id of the
+ * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+ * NULL, local thread number within the core is returned in it.
+ */
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ * @thread: if not NULL, local thread number within the physical core is
+ * returned
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to initialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+ struct device_node *cpun, *cpus;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+#ifdef CONFIG_PPC
+ /* Check for historical "ibm,ppc-interrupt-server#s" property
+ * for thread ids on PowerPC. If it doesn't exist fallback to
+ * standard "reg" property.
+ */
+ if (__of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+#endif
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_node);
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index ab0eade..3dfed2b 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -28,6 +28,7 @@ struct cpu {
extern int register_cpu(struct cpu *cpu, int num);
extern struct device *get_cpu_device(unsigned cpu);
extern bool cpu_is_hotpluggable(unsigned cpu);
+extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);

extern int cpu_add_dev_attr(struct device_attribute *attr);
extern void cpu_remove_dev_attr(struct device_attribute *attr);
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..c0bb2f1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -459,6 +460,12 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}

+static inline struct device_node *of_get_cpu_node(int cpu,
+ unsigned int *thread)
+{
+ return NULL;
+}
+
static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
{
--
1.8.1.2

2013-08-16 04:55:41

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Thu, 2013-08-15 at 18:09 +0100, Sudeep KarkadaNagesha wrote:
> /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
> * fallback to "reg" property and assume no threads
> */
> -

Oh and I forgot ... that comment is now wrong, since your code handles
threads in the "reg" case...

Cheers,
Ben.

2013-08-16 04:55:45

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Thu, 2013-08-15 at 18:09 +0100, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.

.../...

>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (int)phys_id == get_hard_smp_processor_id(cpu);
> +}

Naming is a bit gross. You might want to make it clearer that
we are talking about CPU IDs in the device-tree here.

> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int *thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;
> + prop_len /= sizeof(*cell);
> + for (tid = 0; tid < prop_len; tid++) {
> + hwid = of_read_number(cell, ac);
> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> + if (thread)
> + *thread = tid;
> + return true;
> + }

Missing: cell += ac;

> + }
> + return false;
> +}
> +
> /* Find the device node for a given logical cpu number, also returns the cpu
> * local thread number (index in ibm,interrupt-server#s) if relevant and
> * asked for (non NULL)
> */
> struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> {
> - int hardid;
> - struct device_node *np;
> + struct device_node *cpun, *cpus;
>
> - hardid = get_hard_smp_processor_id(cpu);
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
>
> - for_each_node_by_type(np, "cpu") {
> - const u32 *intserv;
> - unsigned int plen, t;
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
>
> /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
> * fallback to "reg" property and assume no threads
> */
> - intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
> - &plen);
> - if (intserv == NULL) {
> - const u32 *reg = of_get_property(np, "reg", NULL);
> - if (reg == NULL)
> - continue;
> - if (*reg == hardid) {
> - if (thread)
> - *thread = 0;
> - return np;
> - }
> - } else {
> - plen /= sizeof(u32);
> - for (t = 0; t < plen; t++) {
> - if (hardid == intserv[t]) {
> - if (thread)
> - *thread = t;
> - return np;
> - }
> - }
> - }
> + if (__of_find_n_match_cpu_property(cpun,
> + "ibm,ppc-interrupt-server#s", cpu, thread))
> + return cpun;
> +
> + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> + return cpun;
> }
> return NULL;
> }

Cheers,
Ben.

2013-08-16 08:43:19

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 16/08/13 05:50, Benjamin Herrenschmidt wrote:
> On Thu, 2013-08-15 at 18:09 +0100, Sudeep KarkadaNagesha wrote:
>> /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
>> * fallback to "reg" property and assume no threads
>> */
>> -
>
> Oh and I forgot ... that comment is now wrong, since your code handles
> threads in the "reg" case...
>
I have fixed it in the next patch while adding the documentation to
these function. I wanted changes in this patch minimal. I can fix it
here too if you insist on it.

Regards,
Sudeep

2013-08-16 08:48:21

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 16/08/13 05:49, Benjamin Herrenschmidt wrote:
> On Thu, 2013-08-15 at 18:09 +0100, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>
> .../...
>
>>
>> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
>> +{
>> + return (int)phys_id == get_hard_smp_processor_id(cpu);
>> +}
>
> Naming is a bit gross. You might want to make it clearer that
> we are talking about CPU IDs in the device-tree here.
>
Any particular preference to the name or just a note is sufficient.
Also unlike PPC, in ARM we don't set hard processor id value based
values read from device tree. DT must contain the values matching to the
hardware ID registers.

>> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
>> + const char *prop_name, int cpu, unsigned int *thread)
>> +{
>> + const __be32 *cell;
>> + int ac, prop_len, tid;
>> + u64 hwid;
>> +
>> + ac = of_n_addr_cells(cpun);
>> + cell = of_get_property(cpun, prop_name, &prop_len);
>> + if (!cell)
>> + return false;
>> + prop_len /= sizeof(*cell);
>> + for (tid = 0; tid < prop_len; tid++) {
>> + hwid = of_read_number(cell, ac);
>> + if (arch_match_cpu_phys_id(cpu, hwid)) {
>> + if (thread)
>> + *thread = tid;
>> + return true;
>> + }
>
> Missing: cell += ac;
Ah, missed it while refactoring, will fix it. Thanks

Regards,
Sudeep



2013-08-16 09:41:15

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH 2/4] openrisc: remove undefined of_get_cpu_node declaration

On 15/08/13 18:09, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> This patch removes the declaration of the function 'of_get_cpu_node'
> which is not defined for openrisc. This is in preparation to move
> it's definition from PPC to DT common code.
>
> Again it could be there as it was originally copied from powerpc.
>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> Cc: Jonas Bonn <[email protected]>
Hi Jonas,

Since both microblaze and openrisc have moderated lists which I am not
member of, these patches were blocked. Michal Simek agreed to remove
this for microblaze. Do you see any concern with this patch for openrisc
? Can I have you ACK if it looks fine ?

Regards,
Sudeep
> ---
> arch/openrisc/include/asm/prom.h | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
> index bbb34e5..eb59bfe 100644
> --- a/arch/openrisc/include/asm/prom.h
> +++ b/arch/openrisc/include/asm/prom.h
> @@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>
> extern void kdump_move_device_tree(void);
>
> -/* CPU OF node matching */
> -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
> -
> /* Get the MAC address */
> extern const void *of_get_mac_address(struct device_node *np);
>
>

2013-08-16 12:33:45

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Fri, 2013-08-16 at 09:48 +0100, Sudeep KarkadaNagesha wrote:

> > Naming is a bit gross. You might want to make it clearer that
> > we are talking about CPU IDs in the device-tree here.
> >
> Any particular preference to the name or just a note is sufficient.
> Also unlike PPC, in ARM we don't set hard processor id value based
> values read from device tree. DT must contain the values matching to the
> hardware ID registers.

This is exactly the same on ppc. We don't "set" HW values. The
device-tree content matches the HW internals. Some processors have a
"PIR" register as well which contains the HW value, in this case the
device-tree must contain the same value as the PIR on that processor.

> >> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> >> + const char *prop_name, int cpu, unsigned int *thread)
> >> +{
> >> + const __be32 *cell;
> >> + int ac, prop_len, tid;
> >> + u64 hwid;
> >> +
> >> + ac = of_n_addr_cells(cpun);
> >> + cell = of_get_property(cpun, prop_name, &prop_len);
> >> + if (!cell)
> >> + return false;
> >> + prop_len /= sizeof(*cell);
> >> + for (tid = 0; tid < prop_len; tid++) {
> >> + hwid = of_read_number(cell, ac);
> >> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> >> + if (thread)
> >> + *thread = tid;
> >> + return true;
> >> + }
> >
> > Missing: cell += ac;
> Ah, missed it while refactoring, will fix it. Thanks

Ben.

>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2013-08-16 12:44:55

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 16/08/13 13:32, Benjamin Herrenschmidt wrote:
> On Fri, 2013-08-16 at 09:48 +0100, Sudeep KarkadaNagesha wrote:
>
>>> Naming is a bit gross. You might want to make it clearer that
>>> we are talking about CPU IDs in the device-tree here.
>>>
>> Any particular preference to the name or just a note is sufficient.
>> Also unlike PPC, in ARM we don't set hard processor id value based
>> values read from device tree. DT must contain the values matching to the
>> hardware ID registers.
>
> This is exactly the same on ppc. We don't "set" HW values. The
> device-tree content matches the HW internals. Some processors have a
> "PIR" register as well which contains the HW value, in this case the
> device-tree must contain the same value as the PIR on that processor.
>
Ok, I misread the function 'set_hard_smp_processor_id' function.
BTW, you didn't mention if you are OK by just have this clearly
documented in the function and/or you have any preference/better name.

I will send the next version based on that. I have even compile tested
:) now on PPC.

Regards,
Sudeep

2013-08-16 17:39:57

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 0/4] DT: move of_get_cpu_node from PPC to DT core

From: Sudeep KarkadaNagesha <[email protected]>

Hi,

This series needs to be prepended with the original series[1][2][3]
Except the first patch in the original series(which is merged into this
as last patch), there is no other change(apart from function signature)
I am posting only this part for feedback separately for review as the
original series is already reviewed and acked.

v1->v2:
- Fixed an issue - updating cell pointer
- Documentated in arch_match_cpu_phys_id that phys_id are values read
from the device tree only in the weak definition

[Since first 2 patches have not changed, microblaze and openrisc lists are
bouncing for non-members, I am not resending them again. Michal(for
microblaze) has acked when it was first pointed. I am waiting for response
from Jonas(for openrisc)]

Rob, Ben,

If you are OK with these patches and ACK, I can combine and post the complete
series.

Regards,
Sudeep

Sudeep KarkadaNagesha (4):
microblaze: remove undefined of_get_cpu_node declaration
openrisc: remove undefined of_get_cpu_node declaration
powerpc: refactor of_get_cpu_node to support other architectures
of: move of_get_cpu_node implementation to DT core library

arch/microblaze/include/asm/prom.h | 3 --
arch/openrisc/include/asm/prom.h | 3 --
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 43 +----------------
drivers/of/base.c | 96 ++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
7 files changed, 106 insertions(+), 50 deletions(-)

--
1.8.1.2

2013-08-16 17:40:28

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library

From: Sudeep KarkadaNagesha <[email protected]>

This patch moves the generalized implementation of of_get_cpu_node from
PowerPC to DT core library, thereby adding support for retrieving cpu
node for a given logical cpu index on any architecture.

The CPU subsystem can now use this function to assign of_node in the
cpu device while registering CPUs.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Cc: Rob Herring <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 57 ------------------------
drivers/of/base.c | 96 +++++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
5 files changed, 104 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index bc2da15..ac204e0 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
/* cache lookup */
struct device_node *of_find_next_cache_node(struct device_node *np);

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fb12be6..1c14cd4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -870,63 +870,6 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
return (int)phys_id == get_hard_smp_processor_id(cpu);
}

-static bool __of_find_n_match_cpu_property(struct device_node *cpun,
- const char *prop_name, int cpu, unsigned int *thread)
-{
- const __be32 *cell;
- int ac, prop_len, tid;
- u64 hwid;
-
- ac = of_n_addr_cells(cpun);
- cell = of_get_property(cpun, prop_name, &prop_len);
- if (!cell)
- return false;
- prop_len /= sizeof(*cell);
- for (tid = 0; tid < prop_len; tid++) {
- hwid = of_read_number(cell, ac);
- if (arch_match_cpu_phys_id(cpu, hwid)) {
- if (thread)
- *thread = tid;
- return true;
- }
- cell += ac;
- }
- return false;
-}
-
-/* Find the device node for a given logical cpu number, also returns the cpu
- * local thread number (index in ibm,interrupt-server#s) if relevant and
- * asked for (non NULL)
- */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
-{
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (!cpus) {
- pr_warn("Missing cpus node, bailing out\n");
- return NULL;
- }
-
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
-
- /* Check for historical "ibm,ppc-interrupt-server#s" property
- * for thread ids on PowerPC. If it doesn't exist fallback to
- * standard "reg" property.
- */
- if (__of_find_n_match_cpu_property(cpun,
- "ibm,ppc-interrupt-server#s", cpu, thread))
- return cpun;
-
- if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
- return cpun;
- }
- return NULL;
-}
-EXPORT_SYMBOL(of_get_cpu_node);
-
#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
static struct debugfs_blob_wrapper flat_dt_blob;

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..6feb823 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -18,6 +18,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/ctype.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spinlock.h>
@@ -230,6 +231,101 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical cpu index of a core/thread
+ * @phys_id: physical identifier of a core/thread
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index. phys_id provided here is usually values read
+ * from the device tree which must match the hardware internal registers.
+ *
+ * Returns true if the physical identifier and the logical cpu index
+ * correspond to the same core/thread, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * Checks if the given "prop_name" property holds the physical id of the
+ * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+ * NULL, local thread number within the core is returned in it.
+ */
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ cell += ac;
+ }
+ return false;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ * @thread: if not NULL, local thread number within the physical core is
+ * returned
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to initialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+ struct device_node *cpun, *cpus;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+#ifdef CONFIG_PPC
+ /* Check for historical "ibm,ppc-interrupt-server#s" property
+ * for thread ids on PowerPC. If it doesn't exist fallback to
+ * standard "reg" property.
+ */
+ if (__of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+#endif
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_node);
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index ab0eade..3dfed2b 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -28,6 +28,7 @@ struct cpu {
extern int register_cpu(struct cpu *cpu, int num);
extern struct device *get_cpu_device(unsigned cpu);
extern bool cpu_is_hotpluggable(unsigned cpu);
+extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);

extern int cpu_add_dev_attr(struct device_attribute *attr);
extern void cpu_remove_dev_attr(struct device_attribute *attr);
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..c0bb2f1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -459,6 +460,12 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}

+static inline struct device_node *of_get_cpu_node(int cpu,
+ unsigned int *thread)
+{
+ return NULL;
+}
+
static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
{
--
1.8.1.2

2013-08-16 17:40:32

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

PowerPC has it's own implementation to get the cpu node for a given
logical index.

This patch refactors the current implementation of of_get_cpu_node.
This in preparation to move the implementation to DT core library.
It separates out the logical to physical mapping so that a default
matching of the physical id to the logical cpu index can be added
when moved to common code. Architecture specific code can override it.

Cc: Rob Herring <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/kernel/prom.c | 76 ++++++++++++++++++++++++++++------------------
1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index eb23ac9..fb12be6 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
__initcall(prom_reconfig_setup);
#endif

+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (int)phys_id == get_hard_smp_processor_id(cpu);
+}
+
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ cell += ac;
+ }
+ return false;
+}
+
/* Find the device node for a given logical cpu number, also returns the cpu
* local thread number (index in ibm,interrupt-server#s) if relevant and
* asked for (non NULL)
*/
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
{
- int hardid;
- struct device_node *np;
+ struct device_node *cpun, *cpus;

- hardid = get_hard_smp_processor_id(cpu);
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }

- for_each_node_by_type(np, "cpu") {
- const u32 *intserv;
- unsigned int plen, t;
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;

- /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
- * fallback to "reg" property and assume no threads
+ /* Check for historical "ibm,ppc-interrupt-server#s" property
+ * for thread ids on PowerPC. If it doesn't exist fallback to
+ * standard "reg" property.
*/
- intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
- &plen);
- if (intserv == NULL) {
- const u32 *reg = of_get_property(np, "reg", NULL);
- if (reg == NULL)
- continue;
- if (*reg == hardid) {
- if (thread)
- *thread = 0;
- return np;
- }
- } else {
- plen /= sizeof(u32);
- for (t = 0; t < plen; t++) {
- if (hardid == intserv[t]) {
- if (thread)
- *thread = t;
- return np;
- }
- }
- }
+ if (__of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
}
return NULL;
}
--
1.8.1.2

2013-08-16 22:14:09

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Fri, 2013-08-16 at 18:39 +0100, Sudeep KarkadaNagesha wrote:
> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int
> *thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;
> + prop_len /= sizeof(*cell);
> + for (tid = 0; tid < prop_len; tid++) {
> + hwid = of_read_number(cell, ac);
> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> + if (thread)
> + *thread = tid;
> + return true;
> + }
> + cell += ac;
> + }
> + return false;
> +}

The only problem I can see here is if "ac" is not 1, that will not work
for the ibm,ppc-interrupt-server#s case. IE. The latter is always 1 cell
per entry, only "reg" depends on #address-cells.

However that's only a theorical problem since on ppc #address-cells of
/cpus is always 1...

Cheers,
Ben.

2013-08-16 22:20:21

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library

On Fri, 2013-08-16 at 18:39 +0100, Sudeep KarkadaNagesha wrote:
> +#ifdef CONFIG_PPC
> + /* Check for historical "ibm,ppc-interrupt-server#s" property
> + * for thread ids on PowerPC. If it doesn't exist fallback to
> + * standard "reg" property.
> + */
> + if (__of_find_n_match_cpu_property(cpun,
> + "ibm,ppc-interrupt-server#s", cpu, thread))
> + return cpun;
> +#endif

It's not "historical". It's still very much in use and well defined in PAPR :-)

Cheers,
Ben.

2013-08-17 10:50:16

by Tomasz Figa

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

Hi Sudeep,

This looks good to me overall, but I have one more question inline.

On Friday 16 of August 2013 18:39:50 Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> PowerPC has it's own implementation to get the cpu node for a given
> logical index.
>
> This patch refactors the current implementation of of_get_cpu_node.
> This in preparation to move the implementation to DT core library.
> It separates out the logical to physical mapping so that a default
> matching of the physical id to the logical cpu index can be added
> when moved to common code. Architecture specific code can override it.
>
> Cc: Rob Herring <[email protected]>
> Cc: Grant Likely <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> arch/powerpc/kernel/prom.c | 76
> ++++++++++++++++++++++++++++------------------ 1 file changed, 47
> insertions(+), 29 deletions(-)
>
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index eb23ac9..fb12be6 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
> __initcall(prom_reconfig_setup);
> #endif
>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (int)phys_id == get_hard_smp_processor_id(cpu);
> +}
> +
> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int
*thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;

I wonder how would this handle uniprocessor ARM (pre-v7) cores, for which
the updated bindings[1] define #address-cells = <0> and so no reg
property.

[1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795

Best regards,
Tomasz

2013-08-17 22:15:53

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> which
> the updated bindings[1] define #address-cells = <0> and so no reg
> property.
>
> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795

Why did you do that in the binding ? That sounds like looking to create
problems ...

Traditionally, UP setups just used "0" as the "reg" property on other
architectures, why do differently ?

Ben.



2013-08-17 22:22:51

by Tomasz Figa

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Sunday 18 of August 2013 08:09:36 Benjamin Herrenschmidt wrote:
> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> > I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> > which
> > the updated bindings[1] define #address-cells = <0> and so no reg
> > property.
> >
> > [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>
> Why did you do that in the binding ? That sounds like looking to create
> problems ...

[Copying Lorenzo...]

I'm not the author of the change. I was just passing by, while the
question showed up in my mind. ;)

> Traditionally, UP setups just used "0" as the "reg" property on other
> architectures, why do differently ?

Right, especially since the ARM DT topology parsing code still considers a
device tree without reg property in cpu node invalid.

Best regards,
Tomasz

2013-08-19 10:13:14

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 16/08/13 23:13, Benjamin Herrenschmidt wrote:
> On Fri, 2013-08-16 at 18:39 +0100, Sudeep KarkadaNagesha wrote:
>> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
>> + const char *prop_name, int cpu, unsigned int
>> *thread)
>> +{
>> + const __be32 *cell;
>> + int ac, prop_len, tid;
>> + u64 hwid;
>> +
>> + ac = of_n_addr_cells(cpun);
>> + cell = of_get_property(cpun, prop_name, &prop_len);
>> + if (!cell)
>> + return false;
>> + prop_len /= sizeof(*cell);
>> + for (tid = 0; tid < prop_len; tid++) {
>> + hwid = of_read_number(cell, ac);
>> + if (arch_match_cpu_phys_id(cpu, hwid)) {
>> + if (thread)
>> + *thread = tid;
>> + return true;
>> + }
>> + cell += ac;
>> + }
>> + return false;
>> +}
>
> The only problem I can see here is if "ac" is not 1, that will not work
> for the ibm,ppc-interrupt-server#s case. IE. The latter is always 1 cell
> per entry, only "reg" depends on #address-cells.
>
> However that's only a theorical problem since on ppc #address-cells of
> /cpus is always 1...
>
Ok agreed, but I assume in future if thread ids need 2 ac, it would use
standard 'reg' instead of 'ibm,ppc-interrupt-server#' property.

So I assume the above function is generic and need not be modified to
handle non '1' ac case with non standard 'ibm,ppc-interrupt-server#'.

Regards,
Sudeep

2013-08-19 10:20:12

by Mark Rutland

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> > I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> > which
> > the updated bindings[1] define #address-cells = <0> and so no reg
> > property.
> >
> > [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>
> Why did you do that in the binding ? That sounds like looking to create
> problems ...
>
> Traditionally, UP setups just used "0" as the "reg" property on other
> architectures, why do differently ?

The decision was taken because we defined our reg property to refer to
the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
there's no MPIDR register at all. Given there can only be a single CPU
in that case, describing a register that wasn't present didn't seem
necessary or helpful.

Thanks,
Mark.

2013-08-19 10:21:25

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library

On 16/08/13 23:14, Benjamin Herrenschmidt wrote:
> On Fri, 2013-08-16 at 18:39 +0100, Sudeep KarkadaNagesha wrote:
>> +#ifdef CONFIG_PPC
>> + /* Check for historical "ibm,ppc-interrupt-server#s" property
>> + * for thread ids on PowerPC. If it doesn't exist fallback to
>> + * standard "reg" property.
>> + */
>> + if (__of_find_n_match_cpu_property(cpun,
>> + "ibm,ppc-interrupt-server#s", cpu, thread))
>> + return cpun;
>> +#endif
>
> It's not "historical". It's still very much in use and well defined in PAPR :-)
>
By historical, I meant it should not be used in future bindings.

Ah, sorry missed it in ePAPR, because its not under CPU node section.
What's more interesting is that ePAPR has it as an example for
non-standard property names :)

Can I mark it as custom/non-standard instead ? I mainly want to indicate
that we need to use 'reg' property and not introduce any more custom
properties for thread ids.

Can I add your ACK with this comment fixed ?

Regards,
Sudeep

2013-08-19 13:02:59

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 08/19/2013 05:19 AM, Mark Rutland wrote:
> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
>>> which
>>> the updated bindings[1] define #address-cells = <0> and so no reg
>>> property.
>>>
>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>>
>> Why did you do that in the binding ? That sounds like looking to create
>> problems ...
>>
>> Traditionally, UP setups just used "0" as the "reg" property on other
>> architectures, why do differently ?
>
> The decision was taken because we defined our reg property to refer to
> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
> there's no MPIDR register at all. Given there can only be a single CPU
> in that case, describing a register that wasn't present didn't seem
> necessary or helpful.

What exactly reg represents is up to the binding definition, but it
still should be present IMO. I don't see any issue with it being
different for pre-v7.

Rob

>
> Thanks,
> Mark.
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

2013-08-19 13:11:18

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library

On 08/16/2013 12:39 PM, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> This patch moves the generalized implementation of of_get_cpu_node from
> PowerPC to DT core library, thereby adding support for retrieving cpu
> node for a given logical cpu index on any architecture.
>
> The CPU subsystem can now use this function to assign of_node in the
> cpu device while registering CPUs.
>
> It is recommended to use these helper function only in pre-SMP/early
> initialisation stages to retrieve CPU device node pointers in logical
> ordering. Once the cpu devices are registered, it can be retrieved easily
> from cpu device of_node which avoids unnecessary parsing and matching.
>
> Cc: Rob Herring <[email protected]>
> Cc: Grant Likely <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

[snip]

> +/**
> + * of_get_cpu_node - Get device node associated with the given logical CPU
> + *
> + * @cpu: CPU number(logical index) for which device node is required
> + * @thread: if not NULL, local thread number within the physical core is
> + * returned
> + *
> + * The main purpose of this function is to retrieve the device node for the
> + * given logical CPU index. It should be used to initialize the of_node in
> + * cpu device. Once of_node in cpu device is populated, all the further
> + * references can use that instead.
> + *
> + * CPU logical to physical index mapping is architecture specific and is built
> + * before booting secondary cores. This function uses arch_match_cpu_phys_id
> + * which can be overridden by architecture specific implementation.
> + *
> + * Returns a node pointer for the logical cpu if found, else NULL.
> + */
> +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> +{
> + struct device_node *cpun, *cpus;
> +
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
> +
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
> +#ifdef CONFIG_PPC

You don't really need this ifdef as this function should never succeed
on other arches. Alternatively, you can use "IS_ENABLED(CONFIG_PPC)"
instead.

Otherwise,

Acked-by: Rob Herring <[email protected]>

Rob

2013-08-19 13:24:06

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library

On 19/08/13 14:11, Rob Herring wrote:
> On 08/16/2013 12:39 PM, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> This patch moves the generalized implementation of of_get_cpu_node from
>> PowerPC to DT core library, thereby adding support for retrieving cpu
>> node for a given logical cpu index on any architecture.
>>
>> The CPU subsystem can now use this function to assign of_node in the
>> cpu device while registering CPUs.
>>
>> It is recommended to use these helper function only in pre-SMP/early
>> initialisation stages to retrieve CPU device node pointers in logical
>> ordering. Once the cpu devices are registered, it can be retrieved easily
>> from cpu device of_node which avoids unnecessary parsing and matching.
>>
>> Cc: Rob Herring <[email protected]>
>> Cc: Grant Likely <[email protected]>
>> Cc: Benjamin Herrenschmidt <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> [snip]
>
>> +/**
>> + * of_get_cpu_node - Get device node associated with the given logical CPU
>> + *
>> + * @cpu: CPU number(logical index) for which device node is required
>> + * @thread: if not NULL, local thread number within the physical core is
>> + * returned
>> + *
>> + * The main purpose of this function is to retrieve the device node for the
>> + * given logical CPU index. It should be used to initialize the of_node in
>> + * cpu device. Once of_node in cpu device is populated, all the further
>> + * references can use that instead.
>> + *
>> + * CPU logical to physical index mapping is architecture specific and is built
>> + * before booting secondary cores. This function uses arch_match_cpu_phys_id
>> + * which can be overridden by architecture specific implementation.
>> + *
>> + * Returns a node pointer for the logical cpu if found, else NULL.
>> + */
>> +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
>> +{
>> + struct device_node *cpun, *cpus;
>> +
>> + cpus = of_find_node_by_path("/cpus");
>> + if (!cpus) {
>> + pr_warn("Missing cpus node, bailing out\n");
>> + return NULL;
>> + }
>> +
>> + for_each_child_of_node(cpus, cpun) {
>> + if (of_node_cmp(cpun->type, "cpu"))
>> + continue;
>> +#ifdef CONFIG_PPC
>
> You don't really need this ifdef as this function should never succeed
> on other arches. Alternatively, you can use "IS_ENABLED(CONFIG_PPC)"
> instead.
>
Agreed, I can remove it as long as no other architecture use that
property. It's just to avoid checking for it on other architectures.
I will use IS_ENABLED as you suggested.

> Otherwise,
>
> Acked-by: Rob Herring <[email protected]>
>
Thanks.

Regards,
Sudeep

2013-08-19 13:55:55

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 19/08/13 14:02, Rob Herring wrote:
> On 08/19/2013 05:19 AM, Mark Rutland wrote:
>> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
>>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
>>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
>>>> which
>>>> the updated bindings[1] define #address-cells = <0> and so no reg
>>>> property.
>>>>
>>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>>>
>>> Why did you do that in the binding ? That sounds like looking to create
>>> problems ...
>>>
>>> Traditionally, UP setups just used "0" as the "reg" property on other
>>> architectures, why do differently ?
>>
>> The decision was taken because we defined our reg property to refer to
>> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
>> there's no MPIDR register at all. Given there can only be a single CPU
>> in that case, describing a register that wasn't present didn't seem
>> necessary or helpful.
>
> What exactly reg represents is up to the binding definition, but it
> still should be present IMO. I don't see any issue with it being
> different for pre-v7.
>
Yes it's better to have 'reg' with value 0 than not having it.
Otherwise this generic of_get_cpu_node implementation would need some
_hack_ to handle that case.

Regards,
Sudeep

2013-08-20 09:30:21

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 09/19] ARM: mvebu: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Currently set_secondary_cpus_clock assume the CPU logical ordering
and the MPDIR in DT are same, which is incorrect.

Since the CPU device nodes can be retrieved in the logical ordering
using the DT helper, we can remove the devices tree parsing.

This patch removes DT parsing by making use of of_get_cpu_node.

Cc: Andrew Lunn <[email protected]>
Cc: Jason Cooper <[email protected]>
Acked-by: Gregory Clement <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-mvebu/platsmp.c | 51 +++++++++++++++++++------------------------
1 file changed, 23 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index ce81d30..594b63d 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -29,45 +29,40 @@
#include "pmsu.h"
#include "coherency.h"

+static struct clk *__init get_cpu_clk(int cpu)
+{
+ struct clk *cpu_clk;
+ struct device_node *np = of_get_cpu_node(cpu, NULL);
+
+ if (WARN(!np, "missing cpu node\n"))
+ return NULL;
+ cpu_clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(cpu_clk)))
+ return NULL;
+ return cpu_clk;
+}
+
void __init set_secondary_cpus_clock(void)
{
- int thiscpu;
+ int thiscpu, cpu;
unsigned long rate;
- struct clk *cpu_clk = NULL;
- struct device_node *np = NULL;
+ struct clk *cpu_clk;

thiscpu = smp_processor_id();
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
- return;
-
- if (cpu == thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- break;
- }
- }
- if (WARN_ON(IS_ERR(cpu_clk)))
+ cpu_clk = get_cpu_clk(thiscpu);
+ if (!cpu_clk)
return;
clk_prepare_enable(cpu_clk);
rate = clk_get_rate(cpu_clk);

/* set all the other CPU clk to the same rate than the boot CPU */
- for_each_node_by_type(np, "cpu") {
- int err;
- int cpu;
-
- err = of_property_read_u32(np, "reg", &cpu);
- if (WARN_ON(err))
+ for_each_possible_cpu(cpu) {
+ if (cpu == thiscpu)
+ continue;
+ cpu_clk = get_cpu_clk(cpu);
+ if (!cpu_clk)
return;
-
- if (cpu != thiscpu) {
- cpu_clk = of_clk_get(np, 0);
- clk_set_rate(cpu_clk, rate);
- }
+ clk_set_rate(cpu_clk, rate);
}
}

--
1.8.1.2

2013-08-20 09:30:31

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 16/19] cpufreq: arm_big_little: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/arm_big_little_dt.c | 40 +++++++++++++------------------------
1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c
index fd9e3ea..480c0bd 100644
--- a/drivers/cpufreq/arm_big_little_dt.c
+++ b/drivers/cpufreq/arm_big_little_dt.c
@@ -19,12 +19,11 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

-#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/opp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -34,27 +33,13 @@
/* get cpu node with valid operating-points */
static struct device_node *get_cpu_node_with_valid_op(int cpu)
{
- struct device_node *np = NULL, *parent;
- int count = 0;
+ struct device_node *np = of_cpu_device_node_get(cpu);

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
- return NULL;
+ if (!of_get_property(np, "operating-points", NULL)) {
+ of_node_put(np);
+ np = NULL;
}

- for_each_child_of_node(parent, np) {
- if (count++ != cpu)
- continue;
- if (!of_get_property(np, "operating-points", NULL)) {
- of_node_put(np);
- np = NULL;
- }
-
- break;
- }
-
- of_node_put(parent);
return np;
}

@@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev)
struct device_node *np;
int ret;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
- return -ENODATA;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find cpu%d node\n", cpu_dev->id);
+ return -ENOENT;
+ }

- cpu_dev->of_node = np;
ret = of_init_opp_table(cpu_dev);
of_node_put(np);

@@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
struct device_node *np;
u32 transition_latency = CPUFREQ_ETERNAL;

- np = get_cpu_node_with_valid_op(cpu_dev->id);
- if (!np)
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
return CPUFREQ_ETERNAL;
+ }

of_property_read_u32(np, "clock-latency", &transition_latency);
of_node_put(np);
--
1.8.1.2

2013-08-20 09:30:33

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 18/19] cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Benjamin Herrenschmidt <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac64-cpufreq.c | 47 ++++++++++------------------------------
1 file changed, 11 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 7ba4234..97b719f 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/mutex.h>
+#include <linux/of_device.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/irq.h>
@@ -383,9 +384,8 @@ static struct cpufreq_driver g5_cpufreq_driver = {

#ifdef CONFIG_PMAC_SMU

-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
+static int __init g5_neo2_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpunode;
unsigned int psize, ssize;
unsigned long max_freq;
char *freq_method, *volt_method;
@@ -405,20 +405,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
else
return -ENODEV;

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- return -ENODEV;
- }
-
/* Check 970FX for now */
valp = of_get_property(cpunode, "cpu-version", NULL);
if (!valp) {
@@ -537,9 +523,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
#endif /* CONFIG_PMAC_SMU */


-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
+static int __init g5_pm72_cpufreq_init(struct device_node *cpunode)
{
- struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
+ struct device_node *cpuid = NULL, *hwclock = NULL;
const u8 *eeprom = NULL;
const u32 *valp;
u64 max_freq, min_freq, ih, il;
@@ -548,17 +534,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
" RackMac3,1...\n");

- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
- return -ENODEV;
- }
-
/* Lookup the cpuid eeprom node */
cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
if (cpuid != NULL)
@@ -718,25 +693,25 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)

static int __init g5_cpufreq_init(void)
{
- struct device_node *cpus;
+ struct device_node *cpunode;
int rc = 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
+ /* Get first CPU node */
+ cpunode = of_cpu_device_node_get(0);
+ if (cpunode == NULL) {
+ pr_err("cpufreq: Can't find any CPU node\n");
return -ENODEV;
}

if (of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3") ||
of_machine_is_compatible("RackMac3,1"))
- rc = g5_pm72_cpufreq_init(cpus);
+ rc = g5_pm72_cpufreq_init(cpunode);
#ifdef CONFIG_PMAC_SMU
else
- rc = g5_neo2_cpufreq_init(cpus);
+ rc = g5_neo2_cpufreq_init(cpunode);
#endif /* CONFIG_PMAC_SMU */

- of_node_put(cpus);
return rc;
}

--
1.8.1.2

2013-08-20 09:30:29

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 19/19] cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes DT parsing and uses cpu->of_node instead.

Cc: Benjamin Herrenschmidt <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/pmac32-cpufreq.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 3104fad..56bfb6f 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/hardirq.h>
+#include <linux/of_device.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/irq.h>
@@ -649,8 +650,8 @@ static int __init pmac_cpufreq_setup(void)
if (strstr(cmd_line, "nocpufreq"))
return 0;

- /* Assume only one CPU */
- cpunode = of_find_node_by_type(NULL, "cpu");
+ /* Get first CPU node */
+ cpunode = of_cpu_device_node_get(0);
if (!cpunode)
goto out;

--
1.8.1.2

2013-08-20 09:30:25

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 13/19] cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Mark Langsdorf <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/highbank-cpufreq.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
index b61b5a3..794123f 100644
--- a/drivers/cpufreq/highbank-cpufreq.c
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void)
if (!of_machine_is_compatible("calxeda,highbank"))
return -ENODEV;

- for_each_child_of_node(of_find_node_by_path("/cpus"), np)
- if (of_get_property(np, "operating-points", NULL))
- break;
-
- if (!np) {
- pr_err("failed to find highbank cpufreq node\n");
- return -ENOENT;
- }
-
cpu_dev = get_cpu_device(0);
if (!cpu_dev) {
pr_err("failed to get highbank cpufreq device\n");
- ret = -ENODEV;
- goto out_put_node;
+ return -ENODEV;
}

- cpu_dev->of_node = np;
+ np = of_node_get(cpu_dev->of_node);
+ if (!np) {
+ pr_err("failed to find highbank cpufreq node\n");
+ return -ENOENT;
+ }

cpu_clk = clk_get(cpu_dev, NULL);
if (IS_ERR(cpu_clk)) {
--
1.8.1.2

2013-08-20 09:31:32

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 17/19] cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Dmitry Eremin-Solenikov <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/maple-cpufreq.c | 23 +++--------------------
1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c
index cdd6291..f071dc4 100644
--- a/drivers/cpufreq/maple-cpufreq.c
+++ b/drivers/cpufreq/maple-cpufreq.c
@@ -24,7 +24,7 @@
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/time.h>
-#include <linux/of.h>
+#include <linux/of_device.h>

#define DBG(fmt...) pr_debug(fmt)

@@ -201,7 +201,6 @@ static struct cpufreq_driver maple_cpufreq_driver = {

static int __init maple_cpufreq_init(void)
{
- struct device_node *cpus;
struct device_node *cpunode;
unsigned int psize;
unsigned long max_freq;
@@ -217,24 +216,11 @@ static int __init maple_cpufreq_init(void)
!of_machine_is_compatible("Momentum,Apache"))
return 0;

- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
- return -ENODEV;
- }
-
/* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
+ cpunode = of_cpu_device_node_get(0);
if (cpunode == NULL) {
printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- goto bail_cpus;
+ goto bail_noprops;
}

/* Check 970FX for now */
@@ -290,14 +276,11 @@ static int __init maple_cpufreq_init(void)
rc = cpufreq_register_driver(&maple_cpufreq_driver);

of_node_put(cpunode);
- of_node_put(cpus);

return rc;

bail_noprops:
of_node_put(cpunode);
-bail_cpus:
- of_node_put(cpus);

return rc;
}
--
1.8.1.2

2013-08-20 09:31:54

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 14/19] cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Deepak Sikri <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/spear-cpufreq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index c3efa7f..19e364fa 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -18,7 +18,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/types.h>

@@ -223,7 +223,7 @@ static int spear_cpufreq_driver_init(void)
const __be32 *val;
int cnt, i, ret;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_cpu_device_node_get(0);
if (!np) {
pr_err("No cpu node found");
return -ENODEV;
--
1.8.1.2

2013-08-20 09:32:11

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 15/19] cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Cc: Jason Cooper <[email protected]>
Acked-by: Andrew Lunn <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/kirkwood-cpufreq.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index c233ea6..25ac2cb 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -14,7 +14,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpufreq.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/proc-fns.h>
@@ -175,9 +175,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
if (IS_ERR(priv.base))
return PTR_ERR(priv.base);

- np = of_find_node_by_path("/cpus/cpu@0");
- if (!np)
+ np = of_cpu_device_node_get(0);
+ if (!np) {
+ dev_err(&pdev->dev, "failed to get cpu device node\n");
return -ENODEV;
+ }

priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
if (IS_ERR(priv.cpu_clk)) {
--
1.8.1.2

2013-08-20 09:32:37

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/cpufreq/cpufreq-cpu0.c | 23 ++++-------------------
1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index ad1fde2..5b05c26 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {

static int cpu0_cpufreq_probe(struct platform_device *pdev)
{
- struct device_node *np, *parent;
+ struct device_node *np;
int ret;

- parent = of_find_node_by_path("/cpus");
- if (!parent) {
- pr_err("failed to find OF /cpus\n");
- return -ENOENT;
- }
-
- for_each_child_of_node(parent, np) {
- if (of_get_property(np, "operating-points", NULL))
- break;
- }
+ cpu_dev = &pdev->dev;

+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_err("failed to find cpu0 node\n");
- ret = -ENOENT;
- goto out_put_parent;
+ return -ENOENT;
}

- cpu_dev = &pdev->dev;
- cpu_dev->of_node = np;
-
cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
@@ -269,15 +257,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
}

of_node_put(np);
- of_node_put(parent);
return 0;

out_free_table:
opp_free_cpufreq_table(cpu_dev, &freq_table);
out_put_node:
of_node_put(np);
-out_put_parent:
- of_node_put(parent);
return ret;
}

--
1.8.1.2

2013-08-20 09:30:19

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

From: Sudeep KarkadaNagesha <[email protected]>

Currently different drivers requiring to access cpu device node are
parsing the device tree themselves. Since the ordering in the DT need
not match the logical cpu ordering, the parsing logic needs to consider
that. However, this has resulted in lots of code duplication and in some
cases even incorrect logic.

It's better to consolidate them by adding support for getting cpu
device node for a given logical cpu index in DT core library. However
logical to physical index mapping can be architecture specific.

PowerPC has it's own implementation to get the cpu node for a given
logical index.

This patch refactors the current implementation of of_get_cpu_node.
This in preparation to move the implementation to DT core library.
It separates out the logical to physical mapping so that a default
matching of the physical id to the logical cpu index can be added
when moved to common code. Architecture specific code can override it.

Cc: Rob Herring <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/kernel/prom.c | 76 ++++++++++++++++++++++++++++------------------
1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index eb23ac9..f7b8c0b 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
__initcall(prom_reconfig_setup);
#endif

+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (int)phys_id == get_hard_smp_processor_id(cpu);
+}
+
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ cell += ac;
+ }
+ return false;
+}
+
/* Find the device node for a given logical cpu number, also returns the cpu
* local thread number (index in ibm,interrupt-server#s) if relevant and
* asked for (non NULL)
*/
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
{
- int hardid;
- struct device_node *np;
+ struct device_node *cpun, *cpus;

- hardid = get_hard_smp_processor_id(cpu);
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }

- for_each_node_by_type(np, "cpu") {
- const u32 *intserv;
- unsigned int plen, t;
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;

- /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
- * fallback to "reg" property and assume no threads
+ /* Check for non-standard "ibm,ppc-interrupt-server#s" property
+ * for thread ids on PowerPC. If it doesn't exist fallback to
+ * standard "reg" property.
*/
- intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
- &plen);
- if (intserv == NULL) {
- const u32 *reg = of_get_property(np, "reg", NULL);
- if (reg == NULL)
- continue;
- if (*reg == hardid) {
- if (thread)
- *thread = 0;
- return np;
- }
- } else {
- plen /= sizeof(u32);
- for (t = 0; t < plen; t++) {
- if (hardid == intserv[t]) {
- if (thread)
- *thread = t;
- return np;
- }
- }
- }
+ if (__of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
}
return NULL;
}
--
1.8.1.2

2013-08-20 09:33:15

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 11/19] cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes

From: Sudeep KarkadaNagesha <[email protected]>

Now that the cpu device registration initialises the of_node(if available)
appropriately for all the cpus, parsing here is redundant.

This patch removes all DT parsing and uses cpu->of_node instead.

Acked-by: Shawn Guo <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/mach-imx/mach-imx6q.c | 3 +--
drivers/cpufreq/imx6q-cpufreq.c | 4 +---
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 7be13f8..a02f275 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev)
{
struct device_node *np;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
pr_warn("failed to find cpu0 node\n");
return;
}

- cpu_dev->of_node = np;
if (of_init_opp_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index e37cdae..b16632b 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -221,14 +221,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)

cpu_dev = &pdev->dev;

- np = of_find_node_by_path("/cpus/cpu@0");
+ np = of_node_get(cpu_dev->of_node);
if (!np) {
dev_err(cpu_dev, "failed to find cpu0 node\n");
return -ENOENT;
}

- cpu_dev->of_node = np;
-
arm_clk = devm_clk_get(cpu_dev, "arm");
pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
--
1.8.1.2

2013-08-20 09:30:18

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 02/19] openrisc: remove undefined of_get_cpu_node declaration

From: Sudeep KarkadaNagesha <[email protected]>

This patch removes the declaration of the function 'of_get_cpu_node'
which is not defined for openrisc. This is in preparation to move
it's definition from PPC to DT common code.

Again it could be there as it was originally copied from powerpc.

Cc: Jonas Bonn <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/openrisc/include/asm/prom.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
index bbb34e5..eb59bfe 100644
--- a/arch/openrisc/include/asm/prom.h
+++ b/arch/openrisc/include/asm/prom.h
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
/* Get the MAC address */
extern const void *of_get_mac_address(struct device_node *np);

--
1.8.1.2

2013-08-20 09:33:35

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 10/19] drivers/bus: arm-cci: avoid parsing DT for cpu device nodes

From: Sudeep KarkadaNagesha <[email protected]>

Since the CPU device nodes can be retrieved using arch_of_get_cpu_node,
we can use it to avoid parsing the cpus node searching the cpu nodes and
mapping to logical index.

This patch removes parsing DT for cpu nodes by using of_get_cpu_node.

Cc: Lorenzo Pieralisi <[email protected]>
Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/bus/arm-cci.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 7332889..2009266 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);

static void __init cci_ace_init_ports(void)
{
- int port, ac, cpu;
- u64 hwid;
- const u32 *cell;
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (WARN(!cpus, "Missing cpus node, bailing out\n"))
- return;
-
- if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
- ac = of_n_addr_cells(cpus);
+ int port, cpu;
+ struct device_node *cpun;

/*
* Port index look-up speeds up the function disabling ports by CPU,
@@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
* The stashed index array is initialized for all possible CPUs
* at probe time.
*/
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
- cell = of_get_property(cpun, "reg", NULL);
- if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
- continue;
-
- hwid = of_read_number(cell, ac);
- cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
+ for_each_possible_cpu(cpu) {
+ /* too early to use cpu->of_node */
+ cpun = of_get_cpu_node(cpu, NULL);

- if (cpu < 0 || !cpu_possible(cpu))
+ if (WARN(!cpun, "Missing cpu device node\n"))
continue;
+
port = __cci_ace_get_port(cpun, ACE_PORT);
if (port < 0)
continue;
--
1.8.1.2

2013-08-20 09:30:16

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 01/19] microblaze: remove undefined of_get_cpu_node declaration

From: Sudeep KarkadaNagesha <[email protected]>

This patch removes the declaration of the function 'of_get_cpu_node'
which is not defined for microblaze. This is in preparation to move
it's definition from PPC to DT common code.

Michal Simek says: "it was just there because Microblaze
was based on powerpc code"

Acked-by: Michal Simek <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/microblaze/include/asm/prom.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 20c5e8e..9977816 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -50,9 +50,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */

--
1.8.1.2

2013-08-20 09:34:05

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 08/19] ARM: topology: remove hwid/MPIDR dependency from cpu_capacity

From: Sudeep KarkadaNagesha <[email protected]>

Currently the topology code computes cpu capacity and stores it in
the list along with hwid(which is MPIDR) as it parses the CPU nodes
in the device tree. This is required as it needs to be mapped to the
logical CPU later.

Since the CPU device nodes can be retrieved in the logical ordering
using DT/OF helpers, its possible to store cpu_capacity also in logical
ordering and avoid storing hwid for each entry.

This patch removes hwid by making use of of_get_cpu_node.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/topology.c | 61 +++++++++++++++-------------------------------
1 file changed, 19 insertions(+), 42 deletions(-)

diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index c5a5954..85a8737 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
{NULL, },
};

-struct cpu_capacity {
- unsigned long hwid;
- unsigned long capacity;
-};
-
-struct cpu_capacity *cpu_capacity;
+unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu) __cpu_capacity[cpu]

unsigned long middle_capacity = 1;

@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
unsigned long capacity = 0;
int alloc_size, cpu = 0;

- alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
- cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
+ alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
+ __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);

- while ((cn = of_find_node_by_type(cn, "cpu"))) {
- const u32 *rate, *reg;
+ for_each_possible_cpu(cpu) {
+ const u32 *rate;
int len;

- if (cpu >= num_possible_cpus())
- break;
+ /* too early to use cpu->of_node */
+ cn = of_get_cpu_node(cpu, NULL);
+ if (!cn) {
+ pr_err("missing device node for CPU %d\n", cpu);
+ continue;
+ }

for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
if (of_device_is_compatible(cn, cpu_eff->compatible))
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
continue;
}

- reg = of_get_property(cn, "reg", &len);
- if (!reg || len != 4) {
- pr_err("%s missing reg property\n", cn->full_name);
- continue;
- }
-
capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;

/* Save min capacity of the system */
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
if (capacity > max_capacity)
max_capacity = capacity;

- cpu_capacity[cpu].capacity = capacity;
- cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
+ cpu_capacity(cpu) = capacity;
}

- if (cpu < num_possible_cpus())
- cpu_capacity[cpu].hwid = (unsigned long)(-1);
-
/* If min and max capacities are equals, we bypass the update of the
* cpu_scale because all CPUs have the same capacity. Otherwise, we
* compute a middle_capacity factor that will ensure that the capacity
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
* SCHED_POWER_SCALE, which is the default value, but with the
* constraint explained near table_efficiency[].
*/
- if (min_capacity == max_capacity)
- cpu_capacity[0].hwid = (unsigned long)(-1);
- else if (4*max_capacity < (3*(max_capacity + min_capacity)))
+ if (4*max_capacity < (3*(max_capacity + min_capacity)))
middle_capacity = (min_capacity + max_capacity)
>> (SCHED_POWER_SHIFT+1);
else
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
* boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
* function returns directly for SMP system.
*/
-void update_cpu_power(unsigned int cpu, unsigned long hwid)
+void update_cpu_power(unsigned int cpu)
{
- unsigned int idx = 0;
-
- /* look for the cpu's hwid in the cpu capacity table */
- for (idx = 0; idx < num_possible_cpus(); idx++) {
- if (cpu_capacity[idx].hwid == hwid)
- break;
-
- if (cpu_capacity[idx].hwid == -1)
- return;
- }
-
- if (idx == num_possible_cpus())
+ if (!cpu_capacity(cpu))
return;

- set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
+ set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);

printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
cpu, arch_scale_freq_power(NULL, cpu));
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)

#else
static inline void parse_dt_topology(void) {}
-static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
+static inline void update_cpu_power(unsigned int cpuid) {}
#endif

/*
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)

update_siblings_masks(cpuid);

- update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
+ update_cpu_power(cpuid);

printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
cpuid, cpu_topology[cpuid].thread_id,
--
1.8.1.2

2013-08-20 09:34:37

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 05/19] ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id

From: Sudeep KarkadaNagesha <[email protected]>

OF/DT core library now provides architecture specific hook to match the
logical cpu index with the corresponding physical identifier. Most of the
cpu DT node parsing and initialisation is contained in devtree.c. So it's
better to define ARM specific arch_match_cpu_phys_id there.

This mainly helps to avoid replication of the code doing CPU node parsing
and physical(MPIDR) to logical mapping.

Cc: Russell King <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/arm/kernel/devtree.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 5859c8b..2ee8a17 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
}
}

+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
+}
+
/**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt_phys: physical address of dt blob
--
1.8.1.2

2013-08-20 09:34:36

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 06/19] driver/core: cpu: initialize of_node in cpu's device struture

From: Sudeep KarkadaNagesha <[email protected]>

CPUs are also registered as devices but the of_node in these cpu
devices are not initialized. Currently different drivers requiring
to access cpu device node are parsing the nodes themselves and
initialising the of_node in cpu device.

The of_node in all the cpu devices needs to be initialized properly
and at one place. The best place to update this is CPU subsystem
driver when registering the cpu devices.

The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
device node for a given logical index by abstracting the architecture
specific details.

This patch uses of_get_cpu_node to assign of_node when registering the
cpu devices.

Cc: Greg Kroah-Hartman <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
drivers/base/cpu.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4c358bc..4cf0717 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/acpi.h>
+#include <linux/of.h>

#include "base.h"

@@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
+ cpu->dev.of_node = of_get_cpu_node(num, NULL);
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent;
#endif
--
1.8.1.2

2013-08-20 09:34:34

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 07/19] of/device: add helper to get cpu device node from logical cpu index

From: Sudeep KarkadaNagesha <[email protected]>

Multiple drivers need to get the cpu device node from the cpu logical
index and then access the of_node.

This patch adds helper function to fetch the device node directly.

Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
include/linux/of_device.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 9d27475..82ce324 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_OF_DEVICE_H
#define _LINUX_OF_DEVICE_H

+#include <linux/cpu.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h> /* temporary until merge */

@@ -43,6 +44,15 @@ static inline void of_device_node_put(struct device *dev)
of_node_put(dev->of_node);
}

+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+ struct device *cpu_dev;
+ cpu_dev = get_cpu_device(cpu);
+ if (!cpu_dev)
+ return NULL;
+ return of_node_get(cpu_dev->of_node);
+}
+
#else /* CONFIG_OF */

static inline int of_driver_match_device(struct device *dev,
@@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device(
{
return NULL;
}
+
+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */

#endif /* _LINUX_OF_DEVICE_H */
--
1.8.1.2

2013-08-20 09:30:14

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 00/19] DT/core: update cpu device of_node

From: Sudeep KarkadaNagesha <[email protected]>

As more and more information is getting added into the cpu node, the number
of drivers needing to parse the device tree for CPU nodes are increasing.
Most of the time, the information needed from the cpu node is preferred
in the logical CPU order. Hence many drivers first parse and search the
CPU node, match them to logical index if needed and then search for the
required property inside a particular cpu node. Some of them assume the
logical and physical CPU ordering to be same which is incorrect.

This patch series initialises the of_node in all the cpu devices when
registering the CPU device.
1. This avoids different drivers having to parse the cpu nodes to obtain
different attributes like operating points, latency,...etc.
2. This handles different physical and logical cpu ordering which is not
the case in current code.
3. Also all the cpu nodes will have their of_node initialised correctly.
Currently different drivers assign them partially and incorrectly.
4. Removes all the reduntant parsing in various drivers.

Changes v3->v4:
1. There was a conflict with the generic definition of of_get_cpu_node
with the one defined in PPC with the same name but different arguments.
This version refactored the PPC definition to support other architectures
before moving the code to DT core. This part was separately posted and
reviewed[1].
2. Updated the users of of_get_cpu_node with second argument(i.e. thread id
mostly NULL as its currently used only in PPC).

Changes v2->v3:
1. Added new OF helper to get of_node from the cpu logical index.
With the use of this help, removed lots of duplicated code from
cpufreq drivers.
2. Fixed issue with property length calculation in of_get_cpu_node.
(previously had assumed of_get_property returns number of cells)
3. Changed return type of arch_match_cpu_phys_id to bool(as suggested by Nico)
4. Re-ordered patch 2 and 3, and few typo fixes.
5. Rebased on v3.11-rc2(to avoid any conflicts with __cpuinit* deletion)

Changes v1->v2:
1. Moved most of arch_of_get_cpu_node to OF/DT core as of_get_cpu_node
adding a provision for architecture specific hooks for matching
logical and physical ids.
2. Extended removal of DT cpu node parsing to PPC cpufreq drivers
3. Added Acks from Viresh and Shawn

Regards,
Sudeep

v1: https://lkml.org/lkml/2013/7/15/128
v2: https://lkml.org/lkml/2013/7/17/341
v3: https://lkml.org/lkml/2013/7/22/219
[1] https://lkml.org/lkml/2013/8/15/319 (PPC refactoring)

Sudeep KarkadaNagesha (19):
microblaze: remove undefined of_get_cpu_node declaration
openrisc: remove undefined of_get_cpu_node declaration
powerpc: refactor of_get_cpu_node to support other architectures
of: move of_get_cpu_node implementation to DT core library
ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
driver/core: cpu: initialize of_node in cpu's device struture
of/device: add helper to get cpu device node from logical cpu index
ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
ARM: mvebu: remove device tree parsing for cpu nodes
drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
cpufreq: arm_big_little: remove device tree parsing for cpu nodes
cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes

arch/arm/kernel/devtree.c | 5 ++
arch/arm/kernel/topology.c | 61 ++++++++----------------
arch/arm/mach-imx/mach-imx6q.c | 3 +-
arch/arm/mach-mvebu/platsmp.c | 51 +++++++++-----------
arch/microblaze/include/asm/prom.h | 3 --
arch/openrisc/include/asm/prom.h | 3 --
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 43 +----------------
drivers/base/cpu.c | 2 +
drivers/bus/arm-cci.c | 28 +++--------
drivers/cpufreq/arm_big_little_dt.c | 40 ++++++----------
drivers/cpufreq/cpufreq-cpu0.c | 23 ++-------
drivers/cpufreq/highbank-cpufreq.c | 18 +++----
drivers/cpufreq/imx6q-cpufreq.c | 4 +-
drivers/cpufreq/kirkwood-cpufreq.c | 8 ++--
drivers/cpufreq/maple-cpufreq.c | 23 ++-------
drivers/cpufreq/pmac32-cpufreq.c | 5 +-
drivers/cpufreq/pmac64-cpufreq.c | 47 +++++-------------
drivers/cpufreq/spear-cpufreq.c | 4 +-
drivers/of/base.c | 95 +++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
include/linux/of_device.h | 15 ++++++
23 files changed, 226 insertions(+), 266 deletions(-)

--
1.8.1.2

2013-08-20 09:35:54

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: [PATCH v4 04/19] of: move of_get_cpu_node implementation to DT core library

From: Sudeep KarkadaNagesha <[email protected]>

This patch moves the generalized implementation of of_get_cpu_node from
PowerPC to DT core library, thereby adding support for retrieving cpu
node for a given logical cpu index on any architecture.

The CPU subsystem can now use this function to assign of_node in the
cpu device while registering CPUs.

It is recommended to use these helper function only in pre-SMP/early
initialisation stages to retrieve CPU device node pointers in logical
ordering. Once the cpu devices are registered, it can be retrieved easily
from cpu device of_node which avoids unnecessary parsing and matching.

Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Grant Likely <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
---
arch/powerpc/include/asm/prom.h | 3 --
arch/powerpc/kernel/prom.c | 57 -------------------------
drivers/of/base.c | 95 +++++++++++++++++++++++++++++++++++++++++
include/linux/cpu.h | 1 +
include/linux/of.h | 7 +++
5 files changed, 103 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index bc2da15..ac204e0 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,

extern void kdump_move_device_tree(void);

-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
/* cache lookup */
struct device_node *of_find_next_cache_node(struct device_node *np);

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f7b8c0b..1c14cd4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -870,63 +870,6 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
return (int)phys_id == get_hard_smp_processor_id(cpu);
}

-static bool __of_find_n_match_cpu_property(struct device_node *cpun,
- const char *prop_name, int cpu, unsigned int *thread)
-{
- const __be32 *cell;
- int ac, prop_len, tid;
- u64 hwid;
-
- ac = of_n_addr_cells(cpun);
- cell = of_get_property(cpun, prop_name, &prop_len);
- if (!cell)
- return false;
- prop_len /= sizeof(*cell);
- for (tid = 0; tid < prop_len; tid++) {
- hwid = of_read_number(cell, ac);
- if (arch_match_cpu_phys_id(cpu, hwid)) {
- if (thread)
- *thread = tid;
- return true;
- }
- cell += ac;
- }
- return false;
-}
-
-/* Find the device node for a given logical cpu number, also returns the cpu
- * local thread number (index in ibm,interrupt-server#s) if relevant and
- * asked for (non NULL)
- */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
-{
- struct device_node *cpun, *cpus;
-
- cpus = of_find_node_by_path("/cpus");
- if (!cpus) {
- pr_warn("Missing cpus node, bailing out\n");
- return NULL;
- }
-
- for_each_child_of_node(cpus, cpun) {
- if (of_node_cmp(cpun->type, "cpu"))
- continue;
-
- /* Check for non-standard "ibm,ppc-interrupt-server#s" property
- * for thread ids on PowerPC. If it doesn't exist fallback to
- * standard "reg" property.
- */
- if (__of_find_n_match_cpu_property(cpun,
- "ibm,ppc-interrupt-server#s", cpu, thread))
- return cpun;
-
- if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
- return cpun;
- }
- return NULL;
-}
-EXPORT_SYMBOL(of_get_cpu_node);
-
#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
static struct debugfs_blob_wrapper flat_dt_blob;

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5c54279..605afa9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -18,6 +18,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/ctype.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spinlock.h>
@@ -230,6 +231,100 @@ const void *of_get_property(const struct device_node *np, const char *name,
}
EXPORT_SYMBOL(of_get_property);

+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical cpu index of a core/thread
+ * @phys_id: physical identifier of a core/thread
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index. phys_id provided here is usually values read
+ * from the device tree which must match the hardware internal registers.
+ *
+ * Returns true if the physical identifier and the logical cpu index
+ * correspond to the same core/thread, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return (u32)phys_id == cpu;
+}
+
+/**
+ * Checks if the given "prop_name" property holds the physical id of the
+ * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+ * NULL, local thread number within the core is returned in it.
+ */
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+ const char *prop_name, int cpu, unsigned int *thread)
+{
+ const __be32 *cell;
+ int ac, prop_len, tid;
+ u64 hwid;
+
+ ac = of_n_addr_cells(cpun);
+ cell = of_get_property(cpun, prop_name, &prop_len);
+ if (!cell)
+ return false;
+ prop_len /= sizeof(*cell);
+ for (tid = 0; tid < prop_len; tid++) {
+ hwid = of_read_number(cell, ac);
+ if (arch_match_cpu_phys_id(cpu, hwid)) {
+ if (thread)
+ *thread = tid;
+ return true;
+ }
+ cell += ac;
+ }
+ return false;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ * @thread: if not NULL, local thread number within the physical core is
+ * returned
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to initialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+ struct device_node *cpun, *cpus;
+
+ cpus = of_find_node_by_path("/cpus");
+ if (!cpus) {
+ pr_warn("Missing cpus node, bailing out\n");
+ return NULL;
+ }
+
+ for_each_child_of_node(cpus, cpun) {
+ if (of_node_cmp(cpun->type, "cpu"))
+ continue;
+ /* Check for non-standard "ibm,ppc-interrupt-server#s" property
+ * for thread ids on PowerPC. If it doesn't exist fallback to
+ * standard "reg" property.
+ */
+ if (IS_ENABLED(CONFIG_PPC) &&
+ __of_find_n_match_cpu_property(cpun,
+ "ibm,ppc-interrupt-server#s", cpu, thread))
+ return cpun;
+ if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+ return cpun;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_node);
+
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index ab0eade..3dfed2b 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -28,6 +28,7 @@ struct cpu {
extern int register_cpu(struct cpu *cpu, int num);
extern struct device *get_cpu_device(unsigned cpu);
extern bool cpu_is_hotpluggable(unsigned cpu);
+extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);

extern int cpu_add_dev_attr(struct device_attribute *attr);
extern void cpu_remove_dev_attr(struct device_attribute *attr);
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..c0bb2f1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)

@@ -459,6 +460,12 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}

+static inline struct device_node *of_get_cpu_node(int cpu,
+ unsigned int *thread)
+{
+ return NULL;
+}
+
static inline int of_property_read_u64(const struct device_node *np,
const char *propname, u64 *out_value)
{
--
1.8.1.2

2013-08-20 12:16:58

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

On Tuesday, August 20, 2013 10:30:05 AM Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> PowerPC has it's own implementation to get the cpu node for a given
> logical index.
>
> This patch refactors the current implementation of of_get_cpu_node.
> This in preparation to move the implementation to DT core library.
> It separates out the logical to physical mapping so that a default
> matching of the physical id to the logical cpu index can be added
> when moved to common code. Architecture specific code can override it.
>
> Cc: Rob Herring <[email protected]>
> Cc: Grant Likely <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

This needs an ACK from Ben to go anywhere.

Thanks,
Rafael


> ---
> arch/powerpc/kernel/prom.c | 76 ++++++++++++++++++++++++++++------------------
> 1 file changed, 47 insertions(+), 29 deletions(-)
>
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index eb23ac9..f7b8c0b 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
> __initcall(prom_reconfig_setup);
> #endif
>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (int)phys_id == get_hard_smp_processor_id(cpu);
> +}
> +
> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int *thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;
> + prop_len /= sizeof(*cell);
> + for (tid = 0; tid < prop_len; tid++) {
> + hwid = of_read_number(cell, ac);
> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> + if (thread)
> + *thread = tid;
> + return true;
> + }
> + cell += ac;
> + }
> + return false;
> +}
> +
> /* Find the device node for a given logical cpu number, also returns the cpu
> * local thread number (index in ibm,interrupt-server#s) if relevant and
> * asked for (non NULL)
> */
> struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> {
> - int hardid;
> - struct device_node *np;
> + struct device_node *cpun, *cpus;
>
> - hardid = get_hard_smp_processor_id(cpu);
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
>
> - for_each_node_by_type(np, "cpu") {
> - const u32 *intserv;
> - unsigned int plen, t;
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
>
> - /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
> - * fallback to "reg" property and assume no threads
> + /* Check for non-standard "ibm,ppc-interrupt-server#s" property
> + * for thread ids on PowerPC. If it doesn't exist fallback to
> + * standard "reg" property.
> */
> - intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
> - &plen);
> - if (intserv == NULL) {
> - const u32 *reg = of_get_property(np, "reg", NULL);
> - if (reg == NULL)
> - continue;
> - if (*reg == hardid) {
> - if (thread)
> - *thread = 0;
> - return np;
> - }
> - } else {
> - plen /= sizeof(u32);
> - for (t = 0; t < plen; t++) {
> - if (hardid == intserv[t]) {
> - if (thread)
> - *thread = t;
> - return np;
> - }
> - }
> - }
> + if (__of_find_n_match_cpu_property(cpun,
> + "ibm,ppc-interrupt-server#s", cpu, thread))
> + return cpun;
> +
> + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> + return cpun;
> }
> return NULL;
> }
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

2013-08-20 12:18:21

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v4 06/19] driver/core: cpu: initialize of_node in cpu's device struture

On Tuesday, August 20, 2013 10:30:08 AM Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> CPUs are also registered as devices but the of_node in these cpu
> devices are not initialized. Currently different drivers requiring
> to access cpu device node are parsing the nodes themselves and
> initialising the of_node in cpu device.
>
> The of_node in all the cpu devices needs to be initialized properly
> and at one place. The best place to update this is CPU subsystem
> driver when registering the cpu devices.
>
> The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
> device node for a given logical index by abstracting the architecture
> specific details.
>
> This patch uses of_get_cpu_node to assign of_node when registering the
> cpu devices.
>
> Cc: Greg Kroah-Hartman <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Hi Greg,

I this one fine with you?

Rafael


> ---
> drivers/base/cpu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
> index 4c358bc..4cf0717 100644
> --- a/drivers/base/cpu.c
> +++ b/drivers/base/cpu.c
> @@ -14,6 +14,7 @@
> #include <linux/slab.h>
> #include <linux/percpu.h>
> #include <linux/acpi.h>
> +#include <linux/of.h>
>
> #include "base.h"
>
> @@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
> cpu->dev.release = cpu_device_release;
> cpu->dev.offline_disabled = !cpu->hotpluggable;
> cpu->dev.offline = !cpu_online(num);
> + cpu->dev.of_node = of_get_cpu_node(num, NULL);
> #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
> cpu->dev.bus->uevent = arch_cpu_uevent;
> #endif
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

2013-08-20 12:22:15

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

On 20/08/13 13:27, Rafael J. Wysocki wrote:
> On Tuesday, August 20, 2013 10:30:05 AM Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>>
>> It's better to consolidate them by adding support for getting cpu
>> device node for a given logical cpu index in DT core library. However
>> logical to physical index mapping can be architecture specific.
>>
>> PowerPC has it's own implementation to get the cpu node for a given
>> logical index.
>>
>> This patch refactors the current implementation of of_get_cpu_node.
>> This in preparation to move the implementation to DT core library.
>> It separates out the logical to physical mapping so that a default
>> matching of the physical id to the logical cpu index can be added
>> when moved to common code. Architecture specific code can override it.
>>
>> Cc: Rob Herring <[email protected]>
>> Cc: Grant Likely <[email protected]>
>> Cc: Benjamin Herrenschmidt <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>
> This needs an ACK from Ben to go anywhere.
>
Hi Rafael,

Correct, he has reviewed but I am waiting for his ACK before I could
sent you pull request. Hopefully I should be able to send pull request
tomorrow with his ACK.

Hi Ben,

If this is patch is fine, can I have your ACK ?

Regards,
Sudeep

2013-08-20 15:17:05

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH v4 06/19] driver/core: cpu: initialize of_node in cpu's device struture

On Tue, Aug 20, 2013 at 10:30:08AM +0100, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> CPUs are also registered as devices but the of_node in these cpu
> devices are not initialized. Currently different drivers requiring
> to access cpu device node are parsing the nodes themselves and
> initialising the of_node in cpu device.
>
> The of_node in all the cpu devices needs to be initialized properly
> and at one place. The best place to update this is CPU subsystem
> driver when registering the cpu devices.
>
> The OF/DT core library now provides of_get_cpu_node to retrieve a cpu
> device node for a given logical index by abstracting the architecture
> specific details.
>
> This patch uses of_get_cpu_node to assign of_node when registering the
> cpu devices.
>
> Cc: Greg Kroah-Hartman <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>

2013-08-20 21:49:34

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

On Tue, 2013-08-20 at 13:22 +0100, Sudeep KarkadaNagesha wrote:
> Correct, he has reviewed but I am waiting for his ACK before I could
> sent you pull request. Hopefully I should be able to send pull request
> tomorrow with his ACK.
>
> Hi Ben,
>
> If this is patch is fine, can I have your ACK ?

I just want to test it (just in case...), will give an Ack then.

Cheers,
Ben.

2013-08-21 05:10:45

by Jonas Bonn

[permalink] [raw]
Subject: Re: [RFC PATCH 2/4] openrisc: remove undefined of_get_cpu_node declaration

On 08/16/13 11:41, Sudeep KarkadaNagesha wrote:
> On 15/08/13 18:09, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> This patch removes the declaration of the function 'of_get_cpu_node'
>> which is not defined for openrisc. This is in preparation to move
>> it's definition from PPC to DT common code.
>>
>> Again it could be there as it was originally copied from powerpc.
>>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>> Cc: Jonas Bonn <[email protected]>
> Hi Jonas,
>
> Since both microblaze and openrisc have moderated lists which I am not
> member of, these patches were blocked. Michal Simek agreed to remove
> this for microblaze. Do you see any concern with this patch for openrisc
> ? Can I have you ACK if it looks fine ?

Hi Sudeep,
Yes, thanks, the patch looks good.

Acked-by: Jonas Bonn <[email protected]>

/Jonas

>
> Regards,
> Sudeep
>> ---
>> arch/openrisc/include/asm/prom.h | 3 ---
>> 1 file changed, 3 deletions(-)
>>
>> diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
>> index bbb34e5..eb59bfe 100644
>> --- a/arch/openrisc/include/asm/prom.h
>> +++ b/arch/openrisc/include/asm/prom.h
>> @@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>>
>> extern void kdump_move_device_tree(void);
>>
>> -/* CPU OF node matching */
>> -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
>> -
>> /* Get the MAC address */
>> extern const void *of_get_mac_address(struct device_node *np);
>>
>>
>

2013-08-22 06:22:02

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

On Tue, 2013-08-20 at 10:30 +0100, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <[email protected]>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.
>
> It's better to consolidate them by adding support for getting cpu
> device node for a given logical cpu index in DT core library. However
> logical to physical index mapping can be architecture specific.
>
> PowerPC has it's own implementation to get the cpu node for a given
> logical index.
>
> This patch refactors the current implementation of of_get_cpu_node.
> This in preparation to move the implementation to DT core library.
> It separates out the logical to physical mapping so that a default
> matching of the physical id to the logical cpu index can be added
> when moved to common code. Architecture specific code can override it.

So the patch unfortunately collides with other changes in powerpc -next,
though it's not a huge deal and not hard to fixup, but expect Linus
to tick unless we sort it out some other way.

Appart from that, it's fine, builds on all my test configs and doesn't
seem to negatively impact things as far as I can tell so far...

Acked-by: Benjamin Herrenschmidt <[email protected]>

> Cc: Rob Herring <[email protected]>
> Cc: Grant Likely <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> arch/powerpc/kernel/prom.c | 76 ++++++++++++++++++++++++++++------------------
> 1 file changed, 47 insertions(+), 29 deletions(-)
>
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index eb23ac9..f7b8c0b 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -865,45 +865,63 @@ static int __init prom_reconfig_setup(void)
> __initcall(prom_reconfig_setup);
> #endif
>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (int)phys_id == get_hard_smp_processor_id(cpu);
> +}
> +
> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int *thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;
> + prop_len /= sizeof(*cell);
> + for (tid = 0; tid < prop_len; tid++) {
> + hwid = of_read_number(cell, ac);
> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> + if (thread)
> + *thread = tid;
> + return true;
> + }
> + cell += ac;
> + }
> + return false;
> +}
> +
> /* Find the device node for a given logical cpu number, also returns the cpu
> * local thread number (index in ibm,interrupt-server#s) if relevant and
> * asked for (non NULL)
> */
> struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> {
> - int hardid;
> - struct device_node *np;
> + struct device_node *cpun, *cpus;
>
> - hardid = get_hard_smp_processor_id(cpu);
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
>
> - for_each_node_by_type(np, "cpu") {
> - const u32 *intserv;
> - unsigned int plen, t;
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
>
> - /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
> - * fallback to "reg" property and assume no threads
> + /* Check for non-standard "ibm,ppc-interrupt-server#s" property
> + * for thread ids on PowerPC. If it doesn't exist fallback to
> + * standard "reg" property.
> */
> - intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
> - &plen);
> - if (intserv == NULL) {
> - const u32 *reg = of_get_property(np, "reg", NULL);
> - if (reg == NULL)
> - continue;
> - if (*reg == hardid) {
> - if (thread)
> - *thread = 0;
> - return np;
> - }
> - } else {
> - plen /= sizeof(u32);
> - for (t = 0; t < plen; t++) {
> - if (hardid == intserv[t]) {
> - if (thread)
> - *thread = t;
> - return np;
> - }
> - }
> - }
> + if (__of_find_n_match_cpu_property(cpun,
> + "ibm,ppc-interrupt-server#s", cpu, thread))
> + return cpun;
> +
> + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> + return cpun;
> }
> return NULL;
> }

2013-08-22 13:29:19

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v4 03/19] powerpc: refactor of_get_cpu_node to support other architectures

On 22/08/13 07:15, Benjamin Herrenschmidt wrote:
> On Tue, 2013-08-20 at 10:30 +0100, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Currently different drivers requiring to access cpu device node are
>> parsing the device tree themselves. Since the ordering in the DT need
>> not match the logical cpu ordering, the parsing logic needs to consider
>> that. However, this has resulted in lots of code duplication and in some
>> cases even incorrect logic.
>>
>> It's better to consolidate them by adding support for getting cpu
>> device node for a given logical cpu index in DT core library. However
>> logical to physical index mapping can be architecture specific.
>>
>> PowerPC has it's own implementation to get the cpu node for a given
>> logical index.
>>
>> This patch refactors the current implementation of of_get_cpu_node.
>> This in preparation to move the implementation to DT core library.
>> It separates out the logical to physical mapping so that a default
>> matching of the physical id to the logical cpu index can be added
>> when moved to common code. Architecture specific code can override it.
>
> So the patch unfortunately collides with other changes in powerpc -next,
> though it's not a huge deal and not hard to fixup, but expect Linus
> to tick unless we sort it out some other way.
>
> Appart from that, it's fine, builds on all my test configs and doesn't
> seem to negatively impact things as far as I can tell so far...
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>
>

Hi Ben,

Thanks a lot for testing and ACK.
I will check with Rafael about these (trivial) conflicts.

Regards,
Sudeep

2013-08-22 13:59:34

by Mark Rutland

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Mon, Aug 19, 2013 at 02:56:10PM +0100, Sudeep KarkadaNagesha wrote:
> On 19/08/13 14:02, Rob Herring wrote:
> > On 08/19/2013 05:19 AM, Mark Rutland wrote:
> >> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
> >>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> >>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> >>>> which
> >>>> the updated bindings[1] define #address-cells = <0> and so no reg
> >>>> property.
> >>>>
> >>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
> >>>
> >>> Why did you do that in the binding ? That sounds like looking to create
> >>> problems ...
> >>>
> >>> Traditionally, UP setups just used "0" as the "reg" property on other
> >>> architectures, why do differently ?
> >>
> >> The decision was taken because we defined our reg property to refer to
> >> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
> >> there's no MPIDR register at all. Given there can only be a single CPU
> >> in that case, describing a register that wasn't present didn't seem
> >> necessary or helpful.
> >
> > What exactly reg represents is up to the binding definition, but it
> > still should be present IMO. I don't see any issue with it being
> > different for pre-v7.
> >
> Yes it's better to have 'reg' with value 0 than not having it.
> Otherwise this generic of_get_cpu_node implementation would need some
> _hack_ to handle that case.

I'm not sure that having some code to handle a difference in standard
between two architectures is a hack. If anything, I'd argue encoding a
reg of 0 that corresponds to a nonexistent MPIDR value (given that's
what the reg property is defined to map to on ARM) is more of a hack ;)

I'm not averse to having a reg value of 0 for this case, but given that
there are existing devicetrees without it, requiring a reg property will
break compatibility with them.

Mark.

2013-08-22 16:51:26

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On 22/08/13 14:59, Mark Rutland wrote:
> On Mon, Aug 19, 2013 at 02:56:10PM +0100, Sudeep KarkadaNagesha wrote:
>> On 19/08/13 14:02, Rob Herring wrote:
>>> On 08/19/2013 05:19 AM, Mark Rutland wrote:
>>>> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
>>>>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
>>>>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
>>>>>> which
>>>>>> the updated bindings[1] define #address-cells = <0> and so no reg
>>>>>> property.
>>>>>>
>>>>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>>>>>
>>>>> Why did you do that in the binding ? That sounds like looking to create
>>>>> problems ...
>>>>>
>>>>> Traditionally, UP setups just used "0" as the "reg" property on other
>>>>> architectures, why do differently ?
>>>>
>>>> The decision was taken because we defined our reg property to refer to
>>>> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
>>>> there's no MPIDR register at all. Given there can only be a single CPU
>>>> in that case, describing a register that wasn't present didn't seem
>>>> necessary or helpful.
>>>
>>> What exactly reg represents is up to the binding definition, but it
>>> still should be present IMO. I don't see any issue with it being
>>> different for pre-v7.
>>>
>> Yes it's better to have 'reg' with value 0 than not having it.
>> Otherwise this generic of_get_cpu_node implementation would need some
>> _hack_ to handle that case.
>
> I'm not sure that having some code to handle a difference in standard
> between two architectures is a hack. If anything, I'd argue encoding a
> reg of 0 that corresponds to a nonexistent MPIDR value (given that's
> what the reg property is defined to map to on ARM) is more of a hack ;)
>
Agreed. But I am more confused.

1. This raises another question as how much do we follow from ePAPR
standard. ePAPR marks the reg property in /cpu as required.
Does that mean we must have all the properties marked as required to be
present in DT ? On the contrary timebase/clock-frequency is some thing
that can be found dynamically and need not be present but they are
marked as required too.

> I'm not averse to having a reg value of 0 for this case, but given that
> there are existing devicetrees without it, requiring a reg property will
> break compatibility with them.
>

2. What exactly does backward compatibility has to cover ? This can't be
considered as breaking of the binding definition. In continuation to the
above argument that reg property is required, do we need to cover this
as it's clearly a case of missing required property(this holds only if
reg is required always).

Regards,
Sudeep

2013-08-28 19:46:38

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Thu, 22 Aug 2013 14:59:30 +0100, Mark Rutland <[email protected]> wrote:
> On Mon, Aug 19, 2013 at 02:56:10PM +0100, Sudeep KarkadaNagesha wrote:
> > On 19/08/13 14:02, Rob Herring wrote:
> > > On 08/19/2013 05:19 AM, Mark Rutland wrote:
> > >> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
> > >>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> > >>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> > >>>> which
> > >>>> the updated bindings[1] define #address-cells = <0> and so no reg
> > >>>> property.
> > >>>>
> > >>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
> > >>>
> > >>> Why did you do that in the binding ? That sounds like looking to create
> > >>> problems ...
> > >>>
> > >>> Traditionally, UP setups just used "0" as the "reg" property on other
> > >>> architectures, why do differently ?
> > >>
> > >> The decision was taken because we defined our reg property to refer to
> > >> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
> > >> there's no MPIDR register at all. Given there can only be a single CPU
> > >> in that case, describing a register that wasn't present didn't seem
> > >> necessary or helpful.
> > >
> > > What exactly reg represents is up to the binding definition, but it
> > > still should be present IMO. I don't see any issue with it being
> > > different for pre-v7.
> > >
> > Yes it's better to have 'reg' with value 0 than not having it.
> > Otherwise this generic of_get_cpu_node implementation would need some
> > _hack_ to handle that case.
>
> I'm not sure that having some code to handle a difference in standard
> between two architectures is a hack. If anything, I'd argue encoding a
> reg of 0 that corresponds to a nonexistent MPIDR value (given that's
> what the reg property is defined to map to on ARM) is more of a hack ;)
>
> I'm not averse to having a reg value of 0 for this case, but given that
> there are existing devicetrees without it, requiring a reg property will
> break compatibility with them.

Then special cases those device trees, but you changing existing
convention really needs to be avoided. The referenced documentation
change is brand new, so we're not stuck with it.

g.

2013-08-29 09:50:32

by Lorenzo Pieralisi

[permalink] [raw]
Subject: Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures

On Wed, Aug 28, 2013 at 08:46:38PM +0100, Grant Likely wrote:
> On Thu, 22 Aug 2013 14:59:30 +0100, Mark Rutland <[email protected]> wrote:
> > On Mon, Aug 19, 2013 at 02:56:10PM +0100, Sudeep KarkadaNagesha wrote:
> > > On 19/08/13 14:02, Rob Herring wrote:
> > > > On 08/19/2013 05:19 AM, Mark Rutland wrote:
> > > >> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
> > > >>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
> > > >>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
> > > >>>> which
> > > >>>> the updated bindings[1] define #address-cells = <0> and so no reg
> > > >>>> property.
> > > >>>>
> > > >>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
> > > >>>
> > > >>> Why did you do that in the binding ? That sounds like looking to create
> > > >>> problems ...
> > > >>>
> > > >>> Traditionally, UP setups just used "0" as the "reg" property on other
> > > >>> architectures, why do differently ?
> > > >>
> > > >> The decision was taken because we defined our reg property to refer to
> > > >> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
> > > >> there's no MPIDR register at all. Given there can only be a single CPU
> > > >> in that case, describing a register that wasn't present didn't seem
> > > >> necessary or helpful.
> > > >
> > > > What exactly reg represents is up to the binding definition, but it
> > > > still should be present IMO. I don't see any issue with it being
> > > > different for pre-v7.
> > > >
> > > Yes it's better to have 'reg' with value 0 than not having it.
> > > Otherwise this generic of_get_cpu_node implementation would need some
> > > _hack_ to handle that case.
> >
> > I'm not sure that having some code to handle a difference in standard
> > between two architectures is a hack. If anything, I'd argue encoding a
> > reg of 0 that corresponds to a nonexistent MPIDR value (given that's
> > what the reg property is defined to map to on ARM) is more of a hack ;)
> >
> > I'm not averse to having a reg value of 0 for this case, but given that
> > there are existing devicetrees without it, requiring a reg property will
> > break compatibility with them.
>
> Then special cases those device trees, but you changing existing
> convention really needs to be avoided. The referenced documentation
> change is brand new, so we're not stuck with it.

I have no problem with changing the bindings and forcing:

#address-cells = <1>;
reg = <0>;

for UP predating v7, my big worry is related to in-kernel dts that we
already patched to follow the #address-cells = <0> rule (and we had to
do it since we got asked that question multiple times on the public
lists).

What do you mean by "special case those device trees" ? I have not
planned to patch them again, unless we really consider that a necessary
evil.

Thanks,
Lorenzo

2013-09-08 15:29:06

by Guennadi Liakhovetski

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

Hi

On Tue, 20 Aug 2013, Sudeep KarkadaNagesha wrote:

> From: Sudeep KarkadaNagesha <[email protected]>
>
> Now that the cpu device registration initialises the of_node(if available)
> appropriately for all the cpus, parsing here is redundant.
>
> This patch removes all DT parsing and uses cpu->of_node instead.
>
> Acked-by: Shawn Guo <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> Acked-by: Viresh Kumar <[email protected]>
> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
> ---
> drivers/cpufreq/cpufreq-cpu0.c | 23 ++++-------------------
> 1 file changed, 4 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.=
> c
> index ad1fde2..5b05c26 100644
> --- a/drivers/cpufreq/cpufreq-cpu0.c
> +++ b/drivers/cpufreq/cpufreq-cpu0.c
> @@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver =3D =
> {
> =20
> static int cpu0_cpufreq_probe(struct platform_device *pdev)
> {
> -=09struct device_node *np, *parent;
> +=09struct device_node *np;
> =09int ret;
> =20
> -=09parent =3D of_find_node_by_path("/cpus");
> -=09if (!parent) {
> -=09=09pr_err("failed to find OF /cpus\n");
> -=09=09return -ENOENT;
> -=09}
> -
> -=09for_each_child_of_node(parent, np) {
> -=09=09if (of_get_property(np, "operating-points", NULL))
> -=09=09=09break;
> -=09}
> +=09cpu_dev =3D &pdev->dev;
> =20
> +=09np =3D of_node_get(cpu_dev->of_node);

Has this actually been tested? This seems to break cpufreq-cpu0. The
reason is, that this probe function is called not for the DT CPU node, but
for a special virtual cpufreq-cpu0 platform device, typically created by
platforms, using

platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);

which then of course doesn't have on .of_node associated with it.

Thanks
Guennadi

> =09if (!np) {
> =09=09pr_err("failed to find cpu0 node\n");
> -=09=09ret =3D -ENOENT;
> -=09=09goto out_put_parent;
> +=09=09return -ENOENT;
> =09}
> =20
> -=09cpu_dev =3D &pdev->dev;
> -=09cpu_dev->of_node =3D np;
> -
> =09cpu_reg =3D devm_regulator_get(cpu_dev, "cpu0");
> =09if (IS_ERR(cpu_reg)) {
> =09=09/*
> @@ -269,15 +257,12 @@ static int cpu0_cpufreq_probe(struct platform_device =
> *pdev)
> =09}
> =20
> =09of_node_put(np);
> -=09of_node_put(parent);
> =09return 0;
> =20
> out_free_table:
> =09opp_free_cpufreq_table(cpu_dev, &freq_table);
> out_put_node:
> =09of_node_put(np);
> -out_put_parent:
> -=09of_node_put(parent);
> =09return ret;
> }
> =20
> --=20
> 1.8.1.2
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

2013-09-09 09:23:47

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

On 06/09/13 14:44, Guennadi Liakhovetski wrote:
> Hi
>
> On Tue, 20 Aug 2013, Sudeep KarkadaNagesha wrote:
>
>> From: Sudeep KarkadaNagesha <[email protected]>
>>
>> Now that the cpu device registration initialises the of_node(if available)
>> appropriately for all the cpus, parsing here is redundant.
>>
>> This patch removes all DT parsing and uses cpu->of_node instead.
>>
>> Acked-by: Shawn Guo <[email protected]>
>> Acked-by: Rob Herring <[email protected]>
>> Acked-by: Viresh Kumar <[email protected]>
>> Signed-off-by: Sudeep KarkadaNagesha <[email protected]>
>> ---
>> drivers/cpufreq/cpufreq-cpu0.c | 23 ++++-------------------
>> 1 file changed, 4 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.=
>> c
>> index ad1fde2..5b05c26 100644
>> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> @@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver =3D =
>> {
>> =20
>> static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> {
>> -=09struct device_node *np, *parent;
>> +=09struct device_node *np;
>> =09int ret;
>> =20
>> -=09parent =3D of_find_node_by_path("/cpus");
>> -=09if (!parent) {
>> -=09=09pr_err("failed to find OF /cpus\n");
>> -=09=09return -ENOENT;
>> -=09}
>> -
>> -=09for_each_child_of_node(parent, np) {
>> -=09=09if (of_get_property(np, "operating-points", NULL))
>> -=09=09=09break;
>> -=09}
>> +=09cpu_dev =3D &pdev->dev;
>> =20
>> +=09np =3D of_node_get(cpu_dev->of_node);
>
> Has this actually been tested? This seems to break cpufreq-cpu0. The
> reason is, that this probe function is called not for the DT CPU node, but
> for a special virtual cpufreq-cpu0 platform device, typically created by
> platforms, using
>
> platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
>
> which then of course doesn't have on .of_node associated with it.
>

Hi Guennadi,

Based on my understanding of the original code:
cpu_dev = &pdev->dev;
...
ret = of_init_opp_table(cpu_dev);

of_init_opp_table needs cpu_dev to be get_cpu_device(0). My
understanding was that platform using cpufreq-cpu0 sets &pdev->dev to
get_cpu_device(0). But looks like that's not the case.

Hi Shawn,

Can you please clarify ? The fix would be as below but I would like to
know if setting cpu_dev to get_cpu_device(0) instead of &pdev->dev has
any impact on other parts of code using cpu_dev ?

diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index cbfffa9..871c336 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -177,7 +177,7 @@ static int cpu0_cpufreq_probe(struct platform_device
*pdev)
struct device_node *np;
int ret;

- cpu_dev = &pdev->dev;
+ cpu_dev = get_cpu_device(0);

np = of_node_get(cpu_dev->of_node);
if (!np) {


Regards,
Sudeep


2013-09-09 14:32:55

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

Hi Sudeep,

On Mon, Sep 09, 2013 at 10:24:39AM +0100, Sudeep KarkadaNagesha wrote:
> Hi Shawn,
>
> Can you please clarify ? The fix would be as below but I would like to
> know if setting cpu_dev to get_cpu_device(0) instead of &pdev->dev has
> any impact on other parts of code using cpu_dev ?

I'm sorry. I should have given it a test on hardware before ACKing the
changes.

The fix below should not have other impact except the prefix of dev_err
[info, dbg] message output ('cpufreq-cpu0:' to 'cpu cpu0:'), which
shouldn't be a problem.

>
> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
> index cbfffa9..871c336 100644
> --- a/drivers/cpufreq/cpufreq-cpu0.c
> +++ b/drivers/cpufreq/cpufreq-cpu0.c
> @@ -177,7 +177,7 @@ static int cpu0_cpufreq_probe(struct platform_device
> *pdev)
> struct device_node *np;
> int ret;
>
> - cpu_dev = &pdev->dev;
> + cpu_dev = get_cpu_device(0);
>
> np = of_node_get(cpu_dev->of_node);
> if (!np) {
>

The imx6q-cpufreq driver needs a similar fixing. Please include the
following changes into your fixing patches. Thanks.

Shawn

---8<---------

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 85a1b51..69fd4b6 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -233,9 +233,10 @@ put_node:
of_node_put(np);
}

-static void __init imx6q_opp_init(struct device *cpu_dev)
+static void __init imx6q_opp_init(void)
{
struct device_node *np;
+ struct device *cpu_dev = get_cpu_device(0);

np = of_node_get(cpu_dev->of_node);
if (!np) {
@@ -268,7 +269,7 @@ static void __init imx6q_init_late(void)
imx6q_cpuidle_init();

if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
- imx6q_opp_init(&imx6q_cpufreq_pdev.dev);
+ imx6q_opp_init();
platform_device_register(&imx6q_cpufreq_pdev);
}
}
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 3e39654..d7ebd91 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -7,6 +7,7 @@
*/

#include <linux/clk.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -202,7 +203,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
unsigned long min_volt, max_volt;
int num, ret;

- cpu_dev = &pdev->dev;
+ cpu_dev = get_cpu_device(0);

np = of_node_get(cpu_dev->of_node);
if (!np) {

2013-09-09 15:23:27

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

On 09/09/13 15:32, Shawn Guo wrote:
> Hi Sudeep,
>
> On Mon, Sep 09, 2013 at 10:24:39AM +0100, Sudeep KarkadaNagesha wrote:
>> Hi Shawn,
>>
>> Can you please clarify ? The fix would be as below but I would like to
>> know if setting cpu_dev to get_cpu_device(0) instead of &pdev->dev has
>> any impact on other parts of code using cpu_dev ?
>
> I'm sorry. I should have given it a test on hardware before ACKing the
> changes.
>
> The fix below should not have other impact except the prefix of dev_err
> [info, dbg] message output ('cpufreq-cpu0:' to 'cpu cpu0:'), which
> shouldn't be a problem.
>
Hi Shawn,

Ok. But I am bit suspicious about devm_clk_get(cpu_dev, NULL).
I don't understand completely as how the clock are registered(whether
with dev_id or with connection_id).

A quick grep revealed that i.mx and shmobile is using conection id while
registering. If the clock is registered with connection id and retrieved
with cpu_dev(now dev_id is cpu0 and not cpufreq-cpu0), IIUC that would
break. If we pass pdev->dev for clk_get, it should be fine but again
IIUC it breaks highbank which gets all the information from DT.

So only solution I can think of is to continue to have the code
assigning (&pdev->dev)->of_node with cpu device node which is not clean
and arguable as incorrect since there is no DT node for cpufreq-cpu0.
I don't have a strong opinion though.

Let me know how would you like to fix this.

>>
>> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
>> index cbfffa9..871c336 100644
>> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> @@ -177,7 +177,7 @@ static int cpu0_cpufreq_probe(struct platform_device
>> *pdev)
>> struct device_node *np;
>> int ret;
>>
>> - cpu_dev = &pdev->dev;
>> + cpu_dev = get_cpu_device(0);
>>
>> np = of_node_get(cpu_dev->of_node);
>> if (!np) {
>>
>
> The imx6q-cpufreq driver needs a similar fixing. Please include the
> following changes into your fixing patches. Thanks.
>
Ok no problem I can post the fix based on response for the above question.

Regard,
Sudeep

2013-09-10 02:44:23

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

On Mon, Sep 09, 2013 at 04:24:18PM +0100, Sudeep KarkadaNagesha wrote:
> Hi Shawn,
>
> Ok. But I am bit suspicious about devm_clk_get(cpu_dev, NULL).
> I don't understand completely as how the clock are registered(whether
> with dev_id or with connection_id).

As the connection_id of devm_clk_get() call here is NULL, the clock
lookup should be registered with a proper dev_id in clk_register_clkdev()
call. And that's what you have seen with imx and shmobile code.


> A quick grep revealed that i.mx and shmobile is using conection id while
> registering.

They are using dev_id.

> If the clock is registered with connection id and retrieved
> with cpu_dev(now dev_id is cpu0 and not cpufreq-cpu0), IIUC that would
> break. If we pass pdev->dev for clk_get, it should be fine but again
> IIUC it breaks highbank which gets all the information from DT.

If the clock lookup is from DT, we should be just fine, since it will
work as long as the DT node with 'clocks' property (/cpus/cpu@0 in this
case) is attached to the struct device pointer of devm_clk_get() call.

> So only solution I can think of is to continue to have the code
> assigning (&pdev->dev)->of_node with cpu device node which is not clean
> and arguable as incorrect since there is no DT node for cpufreq-cpu0.
> I don't have a strong opinion though.
>
> Let me know how would you like to fix this.

So we only need to change all clkdev registration to use "cpu0" as
dev_id intstead of "cpufreq-cpu0.0", something like below.

And for imx, it should work even without the changes, because we have
device tree lookup ready there, and those clk_register_clkdev() calls
can just be removed now. But I prefer to include the change and leave
the cleanup to another patch for keeping the change log clear.

Shawn

---8<----------

diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index c3cfa41..c6b40f3 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -285,7 +285,7 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
clk_register_clkdev(clk[rtc_ipg_gate], NULL, "imx21-rtc");
clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
- clk_register_clkdev(clk[cpu_div], NULL, "cpufreq-cpu0.0");
+ clk_register_clkdev(clk[cpu_div], NULL, "cpu0");
clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);

mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 1a56a33..de1964c 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -328,7 +328,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
- clk_register_clkdev(clk[cpu_podf], NULL, "cpufreq-cpu0.0");
+ clk_register_clkdev(clk[cpu_podf], NULL, "cpu0");
clk_register_clkdev(clk[iim_gate], "iim", NULL);
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 8ea5ef6..5bd2e85 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -555,7 +555,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("pll2h", &pll2h_clk),

/* CPU clock */
- CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk),
+ CLKDEV_DEV_ID("cpu0", &z_clk),

/* DIV6 */
CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 1942eae..c92c023 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -616,7 +616,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */

/* DIV4 clocks */
- CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
+ CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),

/* DIV6 clocks */
CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),

2013-09-10 10:56:25

by Sudeep KarkadaNagesha

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

On 10/09/13 03:44, Shawn Guo wrote:
> On Mon, Sep 09, 2013 at 04:24:18PM +0100, Sudeep KarkadaNagesha wrote:
>> Hi Shawn,
>>
>> Ok. But I am bit suspicious about devm_clk_get(cpu_dev, NULL).
>> I don't understand completely as how the clock are registered(whether
>> with dev_id or with connection_id).
>
> As the connection_id of devm_clk_get() call here is NULL, the clock
> lookup should be registered with a proper dev_id in clk_register_clkdev()
> call. And that's what you have seen with imx and shmobile code.
>
>
>> A quick grep revealed that i.mx and shmobile is using conection id while
>> registering.
>
> They are using dev_id.
>
Yes correct. I misunderstood, was expecting caller to pass dev and clk
layer extract dev_name so that even when device name is changed the clk
registration need not be changed.

>> If the clock is registered with connection id and retrieved
>> with cpu_dev(now dev_id is cpu0 and not cpufreq-cpu0), IIUC that would
>> break. If we pass pdev->dev for clk_get, it should be fine but again
>> IIUC it breaks highbank which gets all the information from DT.
>
> If the clock lookup is from DT, we should be just fine, since it will
> work as long as the DT node with 'clocks' property (/cpus/cpu@0 in this
> case) is attached to the struct device pointer of devm_clk_get() call.
>
This can be ignored if we are registering with "cpu0" as below in your
patch.

>> So only solution I can think of is to continue to have the code
>> assigning (&pdev->dev)->of_node with cpu device node which is not clean
>> and arguable as incorrect since there is no DT node for cpufreq-cpu0.
>> I don't have a strong opinion though.
>>
>> Let me know how would you like to fix this.
>
> So we only need to change all clkdev registration to use "cpu0" as
> dev_id intstead of "cpufreq-cpu0.0", something like below.
>
> And for imx, it should work even without the changes, because we have
> device tree lookup ready there, and those clk_register_clkdev() calls
> can just be removed now. But I prefer to include the change and leave
> the cleanup to another patch for keeping the change log clear.
>
Ok makes sense, do you want me to include this patch also as fix.
I can send a series to fix this if you OK:
1. Fix in cpufreq-cpu0
2. Fix in i.MX driver and platform file
3. Patch below

Regards,
Sudeep

>
> ---8<----------
>
> diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
> index c3cfa41..c6b40f3 100644
> --- a/arch/arm/mach-imx/clk-imx27.c
> +++ b/arch/arm/mach-imx/clk-imx27.c
> @@ -285,7 +285,7 @@ int __init mx27_clocks_init(unsigned long fref)
> clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
> clk_register_clkdev(clk[rtc_ipg_gate], NULL, "imx21-rtc");
> clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
> - clk_register_clkdev(clk[cpu_div], NULL, "cpufreq-cpu0.0");
> + clk_register_clkdev(clk[cpu_div], NULL, "cpu0");
> clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
>
> mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
> diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
> index 1a56a33..de1964c 100644
> --- a/arch/arm/mach-imx/clk-imx51-imx53.c
> +++ b/arch/arm/mach-imx/clk-imx51-imx53.c
> @@ -328,7 +328,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
> clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
> clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
> clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
> - clk_register_clkdev(clk[cpu_podf], NULL, "cpufreq-cpu0.0");
> + clk_register_clkdev(clk[cpu_podf], NULL, "cpu0");
> clk_register_clkdev(clk[iim_gate], "iim", NULL);
> clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
> clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
> diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
> index 8ea5ef6..5bd2e85 100644
> --- a/arch/arm/mach-shmobile/clock-r8a73a4.c
> +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
> @@ -555,7 +555,7 @@ static struct clk_lookup lookups[] = {
> CLKDEV_CON_ID("pll2h", &pll2h_clk),
>
> /* CPU clock */
> - CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk),
> + CLKDEV_DEV_ID("cpu0", &z_clk),
>
> /* DIV6 */
> CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),
> diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
> index 1942eae..c92c023 100644
> --- a/arch/arm/mach-shmobile/clock-sh73a0.c
> +++ b/arch/arm/mach-shmobile/clock-sh73a0.c
> @@ -616,7 +616,7 @@ static struct clk_lookup lookups[] = {
> CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
>
> /* DIV4 clocks */
> - CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
> + CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
>
> /* DIV6 clocks */
> CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
>
>

2013-09-10 11:19:51

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH v4 12/19] cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes

On Tue, Sep 10, 2013 at 11:56:17AM +0100, Sudeep KarkadaNagesha wrote:
> > So we only need to change all clkdev registration to use "cpu0" as
> > dev_id intstead of "cpufreq-cpu0.0", something like below.
> >
> > And for imx, it should work even without the changes, because we have
> > device tree lookup ready there, and those clk_register_clkdev() calls
> > can just be removed now. But I prefer to include the change and leave
> > the cleanup to another patch for keeping the change log clear.
> >
> Ok makes sense, do you want me to include this patch also as fix.
> I can send a series to fix this if you OK:
> 1. Fix in cpufreq-cpu0
> 2. Fix in i.MX driver and platform file
> 3. Patch below

Yes, please. Thanks.

Shawn