Skip to contentSkip to conversation

CPUFreq: Initialize CPU's OPP tables from CPU core

PATCH Superseded Viresh Kumar 4 participants 21 messages May 21, 2014 – May 22, 2014

Subsystems (10)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Viresh Kumar

author maintainer
#0 lore raw

v2 cover CPUFreq: Initialize CPU's OPP tables from CPU core

This is second attempt to initialize CPU's OPPs from CPU core code. First one was here: https://lkml.org/lkml/2014/5/19/57

All drivers expecting CPU's OPPs from device tree initialize OPP table using of_init_opp_table() and there is nothing driver specific in that. They all do it in the same way adding to code redundancy.

It would be better if we can get rid of code redundancy by initializing CPU OPPs from core code for all CPUs that have a "operating-points" property defined in their node.

This patchset is all about that.

The idea was initially discussed here: https://lkml.org/lkml/2014/5/17/123

V1->V2:
- Addition of two new patches: 1/2 & 2/2
- Created separate routine of_init_cpu_opp_table() which wouldn't add any overhead for the platforms which don't have OPP or OF enabled.
- Added a print for success case as well
- Added Acks from Shawn
- Got rid of extra indentation level by returning early from register_cpu().

Cc Greg Kroah-Hartman <[email protected]>
Cc Amit Daniel Kachhap <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Shawn Guo <[email protected]>

Viresh Kumar (7):
opp: remove -ENOSYS from dummy implementation of of_init_opp_table()
opp: handle of_node_{get|put}() inside of_init_opp_table() driver/core: cpu: initialize opp table
cpufreq: arm_big_little: don't initialize opp table
cpufreq: imx6q: don't initialize opp table
cpufreq: cpufreq-cpu0: don't initialize opp table
cpufreq: exynos5440: don't initialize opp table

 arch/arm/mach-imx/mach-imx6q.c       | 36 ++++++++----------------------------
 drivers/base/cpu.c                   | 30 ++++++++++++++++++++++++++----
 drivers/base/power/opp.c             |  4 ++++
 drivers/cpufreq/arm_big_little.c     | 12 +++++++-----
 drivers/cpufreq/arm_big_little_dt.c  | 18 ------------------
 drivers/cpufreq/cpufreq-cpu0.c       |  6 ------
 drivers/cpufreq/exynos5440-cpufreq.c |  6 ------
 drivers/cpufreq/imx6q-cpufreq.c      | 20 +-------------------
 include/linux/pm_opp.h               |  2 +-
 9 files changed, 47 insertions(+), 87 deletions(-)
Signature · 1 line
2.0.0.rc2
author maintainer
#1 lore raw

PATCH v2 1/7 opp: remove -ENOSYS from dummy implementation of of_init_opp_table()

When any of CONFIG_PM_OPP or CONFIG_OF isn't enabled we have a dummy implementation of of_init_opp_table() routine, it returns -EINVAL currently. -EINVAL can be returned from other places within the real implementations of of_init_opp_table() and so caller wouldn't be able to differentiate between those two cases.

Make it return -ENOSYS instead for better handling.

---
 include/linux/pm_opp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/pm_opp.h +1 -1
index 0330217..6668150 100644
@@ -112,7 +112,7 @@ int of_init_opp_table(struct device *dev);
 #else
 static inline int of_init_opp_table(struct device *dev)
 {
-	return -EINVAL;
+	return -ENOSYS;
 }
 #endif
 
Signature · 1 line
2.0.0.rc2
Reviewed-by on v2 1/7
#2 lore raw

Re: [PATCH V2 1/7] opp: remove -ENOSYS from dummy implementation of of_init_opp_table()

Hi Viresh,

$subject perhaps should be "replace/remove -EINVAL.." instead of "remove -ENOSYS ..."

Quoted 8 lines · Viresh Kumar

When any of CONFIG_PM_OPP or CONFIG_OF isn't enabled we have a dummy implementation of of_init_opp_table() routine, it returns -EINVAL currently. -EINVAL can be returned from other places within the real implementations of of_init_opp_table() and so caller wouldn't be able to differentiate between those two cases.

Make it return -ENOSYS instead for better handling.

[Nit] How about "it's more appropriate to return -ENOSYS as since the function is not implemented" ?

Otherwise it looks fine to me.

Quoted 20 lines
---
  include/linux/pm_opp.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/pm_opp.h +1 -1
index 0330217..6668150 100644
@@ -112,7 +112,7 @@ int of_init_opp_table(struct device *dev);
  #else
  static inline int of_init_opp_table(struct device *dev)
  {
-	return -EINVAL;
+	return -ENOSYS;
  }
  #endif
 
author maintainer
#3 lore raw

Re: [PATCH V2 1/7] opp: remove -ENOSYS from dummy implementation of of_init_opp_table()

Quoted 4 lines · Sudeep Holla

Hi Viresh,

$subject perhaps should be "replace/remove -EINVAL.." instead of "remove -ENOSYS ..."

What's going on with my logs? Really annoying for me as well..

author maintainer
#4 lore raw

PATCH v2 2/7 opp: handle of_node_{get|put}() inside of_init_opp_table()

In reply to Viresh Kumar

All callers of of_init_opp_table() are required to call of_node_{get|put}() before and after calling it. It would be better if this can be handled within of_init_opp_table().

---
 drivers/base/power/opp.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/base/power/opp.c +4 -0
index faae9cf..2b615b9 100644
@@ -622,6 +622,9 @@ int of_init_opp_table(struct device *dev)
 	const __be32 *val;
 	int nr;
 
+	if (!of_node_get(dev->of_node))
+		return -ENODEV;
+
 	prop = of_find_property(dev->of_node, "operating-points", NULL);
 	if (!prop)
 		return -ENODEV;
@@ -649,6 +652,7 @@ int of_init_opp_table(struct device *dev)
 		nr -= 2;
 	}
 
+	of_node_put(dev->of_node);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_init_opp_table);
Signature · 1 line
2.0.0.rc2
author maintainer
#5 lore raw

PATCH v2 3/7 driver/core: cpu: initialize opp table

In reply to Viresh Kumar

All drivers expecting CPU's OPPs from device tree initialize OPP table using of_init_opp_table() and there is nothing driver specific in that. They all do it in the same way adding to code redundancy.

It would be better if we can get rid of code redundancy by initializing CPU OPPs from core code for all CPUs that have a "operating-points" property defined in their node.

This patch initializes OPPs as soon as CPU device is registered in register_cpu().

Cc Greg Kroah-Hartman <[email protected]>
Cc Amit Daniel Kachhap <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Shawn Guo <[email protected]>
---
 drivers/base/cpu.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)
drivers/base/cpu.c +26 -4
index 006b1bc..853e99e 100644
@@ -16,6 +16,7 @@
 #include <linux/acpi.h>
 #include <linux/of.h>
 #include <linux/cpufeature.h>
+#include <linux/pm_opp.h>
 
 #include "base.h"
 
@@ -322,6 +323,25 @@ static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
 }
 #endif
 
+#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
+static inline void of_init_cpu_opp_table(struct cpu *cpu)
+{
+	int error;
+
+	/* Initialize CPU's OPP table */
+	error = of_init_opp_table(&cpu->dev);
+	if (!error)
+		dev_info(&cpu->dev, "%s: created OPP table for cpu: %d\n",
+			 __func__, cpu->dev.id);
+	/* Print error only if there is an issue with OPP table */
+	else if (error != -ENOSYS && error != -ENODEV)
+		dev_err(&cpu->dev, "%s: failed to init OPP table for cpu%d, err: %d\n",
+			__func__, cpu->dev.id, error);
+}
+#else
+static inline void of_init_cpu_opp_table(struct cpu *cpu) {}
+#endif
+
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -349,10 +369,12 @@ int register_cpu(struct cpu *cpu, int num)
 	if (cpu->hotpluggable)
 		cpu->dev.groups = hotplugable_cpu_attr_groups;
 	error = device_register(&cpu->dev);
-	if (!error)
-		per_cpu(cpu_sys_devices, num) = &cpu->dev;
-	if (!error)
-		register_cpu_under_node(num, cpu_to_node(num));
+	if (error)
+		return error;
+
+	per_cpu(cpu_sys_devices, num) = &cpu->dev;
+	register_cpu_under_node(num, cpu_to_node(num));
+	of_init_cpu_opp_table(cpu);
 
 	return error;
 }
Signature · 1 line
2.0.0.rc2
#6 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

Quoted 36 lines · Viresh Kumar

All drivers expecting CPU's OPPs from device tree initialize OPP table using of_init_opp_table() and there is nothing driver specific in that. They all do it in the same way adding to code redundancy.

It would be better if we can get rid of code redundancy by initializing CPU OPPs from core code for all CPUs that have a "operating-points" property defined in their node.

This patch initializes OPPs as soon as CPU device is registered in register_cpu().

Cc Greg Kroah-Hartman <[email protected]>
Cc Amit Daniel Kachhap <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Shawn Guo <[email protected]>
---
  drivers/base/cpu.c | 30 ++++++++++++++++++++++++++----
  1 file changed, 26 insertions(+), 4 deletions(-)
drivers/base/cpu.c +1 -0
index 006b1bc..853e99e 100644
@@ -16,6 +16,7 @@
  #include <linux/acpi.h>
  #include <linux/of.h>
  #include <linux/cpufeature.h>
+#include <linux/pm_opp.h>
 
  #include "base.h"
 
@@ -322,6 +323,25 @@ static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  }
  #endif
 

drivers/base/cpu.c static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) · line 335

Quoted 10 lines
drivers/base/cpu.c +10 -0
+#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
+static inline void of_init_cpu_opp_table(struct cpu *cpu)
+{
+	int error;
+
+	/* Initialize CPU's OPP table */
+	error = of_init_opp_table(&cpu->dev);
+	if (!error)
+		dev_info(&cpu->dev, "%s: created OPP table for cpu: %d\n",
+			 __func__, cpu->dev.id);

[Nit] Not sure if we need this logging on each cpu, may be dev_dbg if you still fancy one ? :)

drivers/base/cpu.c static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) · line 344

Quoted 9 lines
drivers/base/cpu.c +9 -0
+	/* Print error only if there is an issue with OPP table */
+	else if (error != -ENOSYS && error != -ENODEV)
+		dev_err(&cpu->dev, "%s: failed to init OPP table for cpu%d, err: %d\n",
+			__func__, cpu->dev.id, error);
+}
+#else
+static inline void of_init_cpu_opp_table(struct cpu *cpu) {}
+#endif
+

IMO this could be more generic and applicable for any device if you replace "struct cpu" with "struct device". I know this is currently used by cpu but we can extend it's use for any device if needed in future. You can then move this to pm_opp.h as of_init_dev_opp_table may be.

Regards,
Sudeep

author maintainer
#7 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

Quoted 3 lines · Sudeep Holla

[Nit] Not sure if we need this logging on each cpu, may be dev_dbg if you still
fancy one ? :)

It wouldn't happen on each CPU, but one CPU per policy as others would return -ENODEV.

I added dev_dbg earlier but then I thought dev_info is better as we may better show this to everybody as it about the most important device, i.e. CPU :)

Quoted 8 lines
Quoted 8 lines
drivers/base/cpu.c +3 -0
+       /* Print error only if there is an issue with OPP table */
+       else if (error != -ENOSYS && error != -ENODEV)
+               dev_err(&cpu->dev, "%s: failed to init OPP table for

cpu%d, err: %d\n",

drivers/base/cpu.c +4 -0
+                       __func__, cpu->dev.id, error);
+}
+#else
+static inline void of_init_cpu_opp_table(struct cpu *cpu) {}
Quoted 8 lines

drivers/base/cpu.c static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) · line 344

Quoted 2 lines
drivers/base/cpu.c +2 -0
+#endif
+

IMO this could be more generic and applicable for any device if you replace "struct cpu" with "struct device". I know this is currently used by cpu but we can extend it's use for any device if needed in future. You can then move this to pm_opp.h as of_init_dev_opp_table may be.

Probably we will call of_init_opp_table() directly for other devices, as this function doesn't do anything else, apart from some prints.. So, probably leave is as is for now, unless a real need arises ?

#8 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

Quoted 8 lines · Viresh Kumar
Quoted 3 lines · Sudeep Holla

[Nit] Not sure if we need this logging on each cpu, may be dev_dbg if you still
fancy one ? :)

It wouldn't happen on each CPU, but one CPU per policy as others would return -ENODEV.

Hmm agreed, but there are SoCs that support per CPU DVFS ;)

Quoted 21 lines

I added dev_dbg earlier but then I thought dev_info is better as we may better show this to everybody as it about the most important device, i.e. CPU :)

Quoted 8 lines
Quoted 8 lines
drivers/base/cpu.c +3 -0
+       /* Print error only if there is an issue with OPP table */
+       else if (error != -ENOSYS && error != -ENODEV)
+               dev_err(&cpu->dev, "%s: failed to init OPP table for

cpu%d, err: %d\n",

drivers/base/cpu.c +4 -0
+                       __func__, cpu->dev.id, error);
+}
+#else
+static inline void of_init_cpu_opp_table(struct cpu *cpu) {}
Quoted 8 lines

drivers/base/cpu.c static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) · line 344

Quoted 2 lines
drivers/base/cpu.c +2 -0
+#endif
+

IMO this could be more generic and applicable for any device if you replace "struct cpu" with "struct device". I know this is currently used by cpu but we can extend it's use for any device if needed in future. You can then move this to pm_opp.h as of_init_dev_opp_table may be.

Quoted 4 lines

Probably we will call of_init_opp_table() directly for other devices, as this function doesn't do anything else, apart from some prints.. So, probably leave is as is for now, unless a real need arises ?

I don't see anything cpu specific there, but that's just my opinion.

Regards,
Sudeep

author maintainer
#9 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

Quoted 1 line · Sudeep Holla

Hmm agreed, but there are SoCs that support per CPU DVFS ;)

Lets see what's Nishanth/Rafael's view on this. I am more or less in favor of it. But isn't a big thing. Can convert it to dbg if it annoys you :)

Quoted 6 lines
Quoted 4 lines

Probably we will call of_init_opp_table() directly for other devices, as this
function doesn't do anything else, apart from some prints.. So, probably leave is as is for now, unless a real need arises ?

I don't see anything cpu specific there, but that's just my opinion.

I never said that it has anything cpu specific.. What I said was that this routine wouldn't have existed if Rafael wouldn't have asked for it. It is just a wrapper over of_init_opp_table, which also has a dummy implementation when its not supported.

So, it might not be worth enough for any other code to use it. :) But in case it is, we can add it later.

#10 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

In reply to Viresh Kumar
Quoted 43 lines · Viresh Kumar

All drivers expecting CPU's OPPs from device tree initialize OPP table using of_init_opp_table() and there is nothing driver specific in that. They all do it in the same way adding to code redundancy.

It would be better if we can get rid of code redundancy by initializing CPU OPPs from core code for all CPUs that have a "operating-points" property defined in their node.

This patch initializes OPPs as soon as CPU device is registered in register_cpu().

Cc Greg Kroah-Hartman <[email protected]>
Cc Amit Daniel Kachhap <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Shawn Guo <[email protected]>
---
  drivers/base/cpu.c | 30 ++++++++++++++++++++++++++----
  1 file changed, 26 insertions(+), 4 deletions(-)
drivers/base/cpu.c +8 -0
index 006b1bc..853e99e 100644
@@ -16,6 +16,7 @@
  #include <linux/acpi.h>
  #include <linux/of.h>
  #include <linux/cpufeature.h>
+#include <linux/pm_opp.h>
 
  #include "base.h"
 
@@ -322,6 +323,25 @@ static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  }
  #endif
 
+#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
+static inline void of_init_cpu_opp_table(struct cpu *cpu)
+{
+	int error;
+
+	/* Initialize CPU's OPP table */
+	error = of_init_opp_table(&cpu->dev);

drivers/base/cpu.c static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) · line 342

Quoted 10 lines
drivers/base/cpu.c +10 -0
+	if (!error)
+		dev_info(&cpu->dev, "%s: created OPP table for cpu: %d\n",
+			 __func__, cpu->dev.id);
+	/* Print error only if there is an issue with OPP table */
+	else if (error != -ENOSYS && error != -ENODEV)
+		dev_err(&cpu->dev, "%s: failed to init OPP table for cpu%d, err: %d\n",
+			__func__, cpu->dev.id, error);
+}
+#else
+static inline void of_init_cpu_opp_table(struct cpu *cpu) {}

Sorry I missed this earlier, main idea of this wrapper is not to have any config dependency and hide error handling details for non-DT platforms. Since of_init_opp_table has dummy implementation, you really don't need this dummy implementation again here.

Regards,
Sudeep

author maintainer
#11 lore raw

Re: [PATCH V2 3/7] driver/core: cpu: initialize opp table

Quoted 5 lines · Sudeep Holla

Sorry I missed this earlier, main idea of this wrapper is not to have any config dependency and hide error handling details for non-DT platforms. Since
of_init_opp_table has dummy implementation, you really don't need this dummy implementation again here.

x-( (That's my angry face ..)

I still added it so that the next few conditional statements (error checking) also go away for non-DT platforms.. So, lets keep for now. We may have more additions into it in future..

author maintainer
#12 lore raw

PATCH v2 4/7 cpufreq: arm_big_little: don't initialize opp table

In reply to Viresh Kumar

OPP tables are already initialized for all CPUs by cpufreq core and so we don't need to reinitialize them from arm_big_little_dt driver.

Also, as the arm_big_little_dt driver doesn't have a .init_opp_table() callback anymore, make it optional in arm_big_little driver.

---
 drivers/cpufreq/arm_big_little.c    | 12 +++++++-----
 drivers/cpufreq/arm_big_little_dt.c | 18 ------------------
 2 files changed, 7 insertions(+), 23 deletions(-)
drivers/cpufreq/arm_big_little.c +7 -5
index 1f4d4e3..561261e 100644
@@ -325,11 +325,13 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
 	if (freq_table[cluster])
 		return 0;
 
-	ret = arm_bL_ops->init_opp_table(cpu_dev);
-	if (ret) {
-		dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n",
+	if (arm_bL_ops->init_opp_table) {
+		ret = arm_bL_ops->init_opp_table(cpu_dev);
+		if (ret) {
+			dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n",
 				__func__, cpu_dev->id, ret);
-		goto out;
+			goto out;
+		}
 	}
 
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]);
@@ -542,7 +544,7 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
 		return -EBUSY;
 	}
 
-	if (!ops || !strlen(ops->name) || !ops->init_opp_table) {
+	if (!ops || !strlen(ops->name)) {
 		pr_err("%s: Invalid arm_bL_ops, exiting\n", __func__);
 		return -ENODEV;
 	}
drivers/cpufreq/arm_big_little_dt.c +0 -18
index 8d9d591..502182d 100644
@@ -43,23 +43,6 @@ static struct device_node *get_cpu_node_with_valid_op(int cpu)
 	return np;
 }
 
-static int dt_init_opp_table(struct device *cpu_dev)
-{
-	struct device_node *np;
-	int ret;
-
-	np = of_node_get(cpu_dev->of_node);
-	if (!np) {
-		pr_err("failed to find cpu%d node\n", cpu_dev->id);
-		return -ENOENT;
-	}
-
-	ret = of_init_opp_table(cpu_dev);
-	of_node_put(np);
-
-	return ret;
-}
-
 static int dt_get_transition_latency(struct device *cpu_dev)
 {
 	struct device_node *np;
@@ -81,7 +64,6 @@ static int dt_get_transition_latency(struct device *cpu_dev)
 static struct cpufreq_arm_bL_ops dt_bL_ops = {
 	.name	= "dt-bl",
 	.get_transition_latency = dt_get_transition_latency,
-	.init_opp_table = dt_init_opp_table,
 };
 
 static int generic_bL_probe(struct platform_device *pdev)
Signature · 1 line
2.0.0.rc2
#13 lore raw

Re: [PATCH V2 4/7] cpufreq: arm_big_little: don't initialize opp table

Quoted 3 lines · Viresh Kumar

OPP tables are already initialized for all CPUs by cpufreq core and so we don't need to reinitialize them from arm_big_little_dt driver.

I guess you wanted to say "cpu core code" instead of "cpufreq core". Correction may be needed here and in the subsequent patches as well.

Quoted 84 lines

Also, as the arm_big_little_dt driver doesn't have a .init_opp_table() callback anymore, make it optional in arm_big_little driver.

---
 drivers/cpufreq/arm_big_little.c    | 12 +++++++-----
 drivers/cpufreq/arm_big_little_dt.c | 18 ------------------
 2 files changed, 7 insertions(+), 23 deletions(-)
drivers/cpufreq/arm_big_little.c +7 -5
index 1f4d4e3..561261e 100644
@@ -325,11 +325,13 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
        if (freq_table[cluster])
                return 0;
 
-       ret = arm_bL_ops->init_opp_table(cpu_dev);
-       if (ret) {
-               dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n",
+       if (arm_bL_ops->init_opp_table) {
+               ret = arm_bL_ops->init_opp_table(cpu_dev);
+               if (ret) {
+                       dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n",
                                __func__, cpu_dev->id, ret);
-               goto out;
+                       goto out;
+               }
        }
 
        ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]);
@@ -542,7 +544,7 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
                return -EBUSY;
        }
 
-       if (!ops || !strlen(ops->name) || !ops->init_opp_table) {
+       if (!ops || !strlen(ops->name)) {
                pr_err("%s: Invalid arm_bL_ops, exiting\n", __func__);
                return -ENODEV;
        }
drivers/cpufreq/arm_big_little_dt.c +0 -19
index 8d9d591..502182d 100644
@@ -43,23 +43,6 @@ static struct device_node *get_cpu_node_with_valid_op(int cpu)
        return np;
 }
 
-static int dt_init_opp_table(struct device *cpu_dev)
-{
-       struct device_node *np;
-       int ret;
-
-       np = of_node_get(cpu_dev->of_node);
-       if (!np) {
-               pr_err("failed to find cpu%d node\n", cpu_dev->id);
-               return -ENOENT;
-       }
-
-       ret = of_init_opp_table(cpu_dev);
-       of_node_put(np);
-
-       return ret;
-}
-
 static int dt_get_transition_latency(struct device *cpu_dev)
 {
        struct device_node *np;
@@ -81,7 +64,6 @@ static int dt_get_transition_latency(struct device *cpu_dev)
 static struct cpufreq_arm_bL_ops dt_bL_ops = {
        .name   = "dt-bl",
        .get_transition_latency = dt_get_transition_latency,
-       .init_opp_table = dt_init_opp_table,
 };
 
 static int generic_bL_probe(struct platform_device *pdev)
--

2.0.0.rc2

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

author maintainer
#14 lore raw

Re: [PATCH V2 4/7] cpufreq: arm_big_little: don't initialize opp table

Quoted 2 lines · Inderpal Singh

I guess you wanted to say "cpu core code" instead of "cpufreq core". Correction may be needed here and in the subsequent patches as well.

When I started implementation, I added code to cpufreq core's init routine and later moved it to base/cpu.c .. And just forgot to update it later :(

Thanks for letting me know

author maintainer
#15 lore raw

PATCH v2 5/7 cpufreq: imx6q: don't initialize opp table

In reply to Viresh Kumar

OPP tables are already initialized for CPU0 by cpufreq core and so we don't need to reinitialize them from imx6q specific code.

---
 arch/arm/mach-imx/mach-imx6q.c  | 36 ++++++++----------------------------
 drivers/cpufreq/imx6q-cpufreq.c | 20 +-------------------
 2 files changed, 9 insertions(+), 47 deletions(-)
arch/arm/mach-imx/mach-imx6q.c +8 -28
index e60456d..03819e7 100644
@@ -290,12 +290,18 @@ static void __init imx6q_init_machine(void)
 #define OCOTP_CFG3_SPEED_996MHZ		0x2
 #define OCOTP_CFG3_SPEED_852MHZ		0x1
 
-static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
+static void __init imx6q_opp_check_speed_grading(void)
 {
+	struct device *cpu_dev = get_cpu_device(0);
 	struct device_node *np;
 	void __iomem *base;
 	u32 val;
 
+	if (!cpu_dev) {
+		pr_warn("failed to get cpu0 device\n");
+		return;
+	}
+
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
 	if (!np) {
 		pr_warn("failed to find ocotp node\n");
@@ -336,32 +342,6 @@ put_node:
 	of_node_put(np);
 }
 
-static void __init imx6q_opp_init(void)
-{
-	struct device_node *np;
-	struct device *cpu_dev = get_cpu_device(0);
-
-	if (!cpu_dev) {
-		pr_warn("failed to get cpu0 device\n");
-		return;
-	}
-	np = of_node_get(cpu_dev->of_node);
-	if (!np) {
-		pr_warn("failed to find cpu0 node\n");
-		return;
-	}
-
-	if (of_init_opp_table(cpu_dev)) {
-		pr_warn("failed to init OPP table\n");
-		goto put_node;
-	}
-
-	imx6q_opp_check_speed_grading(cpu_dev);
-
-put_node:
-	of_node_put(np);
-}
-
 static struct platform_device imx6q_cpufreq_pdev = {
 	.name = "imx6q-cpufreq",
 };
@@ -376,7 +356,7 @@ static void __init imx6q_init_late(void)
 		imx6q_cpuidle_init();
 
 	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
-		imx6q_opp_init();
+		imx6q_opp_check_speed_grading();
 		platform_device_register(&imx6q_cpufreq_pdev);
 	}
 }
drivers/cpufreq/imx6q-cpufreq.c +1 -19
index af366c2..b72e94f 100644
@@ -190,26 +190,8 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
 		goto put_reg;
 	}
 
-	/*
-	 * We expect an OPP table supplied by platform.
-	 * Just, incase the platform did not supply the OPP
-	 * table, it will try to get it.
-	 */
 	num = dev_pm_opp_get_opp_count(cpu_dev);
-	if (num < 0) {
-		ret = of_init_opp_table(cpu_dev);
-		if (ret < 0) {
-			dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
-			goto put_reg;
-		}
-
-		num = dev_pm_opp_get_opp_count(cpu_dev);
-		if (num < 0) {
-			ret = num;
-			dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
-			goto put_reg;
-		}
-	}
+	WARN_ON(num < 0);
 
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
 	if (ret) {
Signature · 1 line
2.0.0.rc2
#16 lore raw

Re: [PATCH V2 5/7] cpufreq: imx6q: don't initialize opp table

Quoted 68 lines · Viresh Kumar

OPP tables are already initialized for CPU0 by cpufreq core and so we don't need to reinitialize them from imx6q specific code.

---
  arch/arm/mach-imx/mach-imx6q.c  | 36 ++++++++----------------------------
  drivers/cpufreq/imx6q-cpufreq.c | 20 +-------------------
  2 files changed, 9 insertions(+), 47 deletions(-)
arch/arm/mach-imx/mach-imx6q.c +7 -27
index e60456d..03819e7 100644
@@ -290,12 +290,18 @@ static void __init imx6q_init_machine(void)
  #define OCOTP_CFG3_SPEED_996MHZ		0x2
  #define OCOTP_CFG3_SPEED_852MHZ		0x1
 
-static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
+static void __init imx6q_opp_check_speed_grading(void)
  {
+	struct device *cpu_dev = get_cpu_device(0);
  	struct device_node *np;
  	void __iomem *base;
  	u32 val;
 
+	if (!cpu_dev) {
+		pr_warn("failed to get cpu0 device\n");
+		return;
+	}
+
  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
  	if (!np) {
  		pr_warn("failed to find ocotp node\n");
@@ -336,32 +342,6 @@ put_node:
  	of_node_put(np);
  }
 
-static void __init imx6q_opp_init(void)
-{
-	struct device_node *np;
-	struct device *cpu_dev = get_cpu_device(0);
-
-	if (!cpu_dev) {
-		pr_warn("failed to get cpu0 device\n");
-		return;
-	}
-	np = of_node_get(cpu_dev->of_node);
-	if (!np) {
-		pr_warn("failed to find cpu0 node\n");
-		return;
-	}
-
-	if (of_init_opp_table(cpu_dev)) {
-		pr_warn("failed to init OPP table\n");
-		goto put_node;
-	}
-
-	imx6q_opp_check_speed_grading(cpu_dev);
-
-put_node:
-	of_node_put(np);
-}
-
  static struct platform_device imx6q_cpufreq_pdev = {
  	.name = "imx6q-cpufreq",
  };

arch/arm/mach-imx/mach-imx6q.c static void __init imx6q_init_late(void) · line 359

Quoted 5 lines
arch/arm/mach-imx/mach-imx6q.c +1 -1
@@ -376,7 +356,7 @@ static void __init imx6q_init_late(void)
  		imx6q_cpuidle_init();
 
  	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
-		imx6q_opp_init();
+		imx6q_opp_check_speed_grading();

[Query] Not exactly related to this patch, but asking it here to get clarified.

This OPP limiting is done as part of late initcall and if the cpufreq driver is built in the kernel, there will be a small window where the OPPs not supported are still enabled ? Will that not be an issue if say performance governor is selected by default.

Regards,
Sudeep

#17 lore raw

Re: [PATCH V2 5/7] cpufreq: imx6q: don't initialize opp table

Quoted 9 lines · Sudeep Holla

arch/arm/mach-imx/mach-imx6q.c static void __init imx6q_init_late(void) · line 359

Quoted 6 lines
arch/arm/mach-imx/mach-imx6q.c +1 -1
@@ -376,7 +356,7 @@ static void __init imx6q_init_late(void)
 		imx6q_cpuidle_init();
 
 	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
-		imx6q_opp_init();
+		imx6q_opp_check_speed_grading();

[Query] Not exactly related to this patch, but asking it here to get clarified.

Quoted 4 lines

This OPP limiting is done as part of late initcall and if the cpufreq driver is built in the kernel, there will be a small window where the OPPs not supported are still enabled ? Will that not be an issue if say performance governor is selected by default.

Even if cpufreq driver is built in the kernel, it won't be probed until platform_device_register(&imx6q_cpufreq_pdev) is called. And we make this call only after the OPP limiting.

Shawn

#18 lore raw

Re: [PATCH V2 5/7] cpufreq: imx6q: don't initialize opp table

Quoted 10 lines · Shawn Guo
Quoted 9 lines · Sudeep Holla

arch/arm/mach-imx/mach-imx6q.c static void __init imx6q_init_late(void) · line 359

Quoted 6 lines
arch/arm/mach-imx/mach-imx6q.c +1 -1
@@ -376,7 +356,7 @@ static void __init imx6q_init_late(void)
  		imx6q_cpuidle_init();
 
  	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
-		imx6q_opp_init();
+		imx6q_opp_check_speed_grading();

[Query] Not exactly related to this patch, but asking it here to get clarified.

Quoted 9 lines
Quoted 4 lines

This OPP limiting is done as part of late initcall and if the cpufreq driver is built in the kernel, there will be a small window where the OPPs not supported are still enabled ? Will that not be an issue if say performance governor is selected by default.

Even if cpufreq driver is built in the kernel, it won't be probed until platform_device_register(&imx6q_cpufreq_pdev) is called. And we make this call only after the OPP limiting.

Ah right, I missed that. Thanks for clarifying.

Regards,
Sudeep

author maintainer
#19 lore raw

PATCH v2 6/7 cpufreq: cpufreq-cpu0: don't initialize opp table

In reply to Viresh Kumar

OPP tables are already initialized for CPU0 by cpufreq core and so we don't need to reinitialize them from cpufreq-cpu0 driver.

---
 drivers/cpufreq/cpufreq-cpu0.c | 6 ------
 1 file changed, 6 deletions(-)
drivers/cpufreq/cpufreq-cpu0.c +0 -6
index 1bf6bba..4301c7c 100644
@@ -152,12 +152,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
 		goto out_put_node;
 	}
 
-	ret = of_init_opp_table(cpu_dev);
-	if (ret) {
-		pr_err("failed to init OPP table: %d\n", ret);
-		goto out_put_node;
-	}
-
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
 	if (ret) {
 		pr_err("failed to init cpufreq table: %d\n", ret);
Signature · 1 line
2.0.0.rc2
author maintainer
#20 lore raw

PATCH v2 7/7 cpufreq: exynos5440: don't initialize opp table

In reply to Viresh Kumar

OPP tables are already initialized for CPU0 by cpufreq core and so we don't need to reinitialize them from exynos5440's driver.

Cd: Amit Daniel Kachhap <[email protected]>
Cd: Kukjin Kim <[email protected]>

---
 drivers/cpufreq/exynos5440-cpufreq.c | 6 ------
 1 file changed, 6 deletions(-)
drivers/cpufreq/exynos5440-cpufreq.c +0 -6
index f33f25b..72a4206 100644
@@ -360,12 +360,6 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
 		goto err_put_node;
 	}
 
-	ret = of_init_opp_table(dvfs_info->dev);
-	if (ret) {
-		dev_err(dvfs_info->dev, "failed to init OPP table: %d\n", ret);
-		goto err_put_node;
-	}
-
 	ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev,
 					    &dvfs_info->freq_table);
 	if (ret) {
Signature · 1 line
2.0.0.rc2