* [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:53 ` Tony Lindgren
2011-09-23 9:21 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support,move " Vishwanath Sripathy
2011-09-22 21:07 ` [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+ Kevin Hilman
` (9 subsequent siblings)
10 siblings, 2 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Move OMAP cpufreq driver from arch/arm/mach-omap2 into
drivers/cpufreq, along with a few cleanups:
- generalize support for better handling of different SoCs in the OMAP
- use OPP layer instead of OMAP clock internals for frequency table init
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[khilman at ti.com: move to drivers]
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
arch/arm/plat-omap/Makefile | 1 -
arch/arm/plat-omap/cpu-omap.c | 171 ------------------------------------
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/omap-cpufreq.c | 188 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 189 insertions(+), 172 deletions(-)
delete mode 100644 arch/arm/plat-omap/cpu-omap.c
create mode 100644 drivers/cpufreq/omap-cpufreq.c
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index f0233e6..4ef7493 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
deleted file mode 100644
index da4f68d..0000000
--- a/arch/arm/plat-omap/cpu-omap.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/cpu-omap.c
- *
- * CPU frequency scaling for OMAP
- *
- * Copyright (C) 2005 Nokia Corporation
- * Written by Tony Lindgren <tony@atomide.com>
- *
- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/cpufreq.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <plat/clock.h>
-#include <asm/system.h>
-
-#define VERY_HI_RATE 900000000
-
-static struct cpufreq_frequency_table *freq_table;
-
-#ifdef CONFIG_ARCH_OMAP1
-#define MPU_CLK "mpu"
-#else
-#define MPU_CLK "virt_prcm_set"
-#endif
-
-static struct clk *mpu_clk;
-
-/* TODO: Add support for SDRAM timing changes */
-
-static int omap_verify_speed(struct cpufreq_policy *policy)
-{
- if (freq_table)
- return cpufreq_frequency_table_verify(policy, freq_table);
-
- if (policy->cpu)
- return -EINVAL;
-
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
- return 0;
-}
-
-static unsigned int omap_getspeed(unsigned int cpu)
-{
- unsigned long rate;
-
- if (cpu)
- return 0;
-
- rate = clk_get_rate(mpu_clk) / 1000;
- return rate;
-}
-
-static int omap_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- struct cpufreq_freqs freqs;
- int ret = 0;
-
- /* Ensure desired rate is within allowed range. Some govenors
- * (ondemand) will just pass target_freq=0 to get the minimum. */
- if (target_freq < policy->min)
- target_freq = policy->min;
- if (target_freq > policy->max)
- target_freq = policy->max;
-
- freqs.old = omap_getspeed(0);
- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
- freqs.cpu = 0;
-
- if (freqs.old == freqs.new)
- return ret;
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-#ifdef CONFIG_CPU_FREQ_DEBUG
- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
- freqs.old, freqs.new);
-#endif
- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
- return ret;
-}
-
-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
-{
- int result = 0;
-
- mpu_clk = clk_get(NULL, MPU_CLK);
- if (IS_ERR(mpu_clk))
- return PTR_ERR(mpu_clk);
-
- if (policy->cpu != 0)
- return -EINVAL;
-
- policy->cur = policy->min = policy->max = omap_getspeed(0);
-
- clk_init_cpufreq_table(&freq_table);
- if (freq_table) {
- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
- if (!result)
- cpufreq_frequency_table_get_attr(freq_table,
- policy->cpu);
- } else {
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
- VERY_HI_RATE) / 1000;
- }
-
- /* FIXME: what's the actual transition time? */
- policy->cpuinfo.transition_latency = 300 * 1000;
-
- return 0;
-}
-
-static int omap_cpu_exit(struct cpufreq_policy *policy)
-{
- clk_exit_cpufreq_table(&freq_table);
- clk_put(mpu_clk);
- return 0;
-}
-
-static struct freq_attr *omap_cpufreq_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static struct cpufreq_driver omap_driver = {
- .flags = CPUFREQ_STICKY,
- .verify = omap_verify_speed,
- .target = omap_target,
- .get = omap_getspeed,
- .init = omap_cpu_init,
- .exit = omap_cpu_exit,
- .name = "omap",
- .attr = omap_cpufreq_attr,
-};
-
-static int __init omap_cpufreq_init(void)
-{
- return cpufreq_register_driver(&omap_driver);
-}
-
-arch_initcall(omap_cpufreq_init);
-
-/*
- * if ever we want to remove this, upon cleanup call:
- *
- * cpufreq_unregister_driver()
- * cpufreq_frequency_table_put_attr()
- */
-
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index a48bc02..ce75fcb 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
+obj-$(CONFIG_ARCH_OMAP2PLUS) += omap-cpufreq.o
##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
new file mode 100644
index 0000000..a6b2be7
--- /dev/null
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -0,0 +1,188 @@
+/*
+ * CPU frequency scaling for OMAP
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
+ * - OMAP3/4 support by Rajendra Nayak, Santosh Shilimkar
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+
+#include <asm/system.h>
+#include <asm/smp_plat.h>
+
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+#include <plat/common.h>
+
+#include <mach/hardware.h>
+
+#define VERY_HI_RATE 900000000
+
+static struct cpufreq_frequency_table *freq_table;
+static struct clk *mpu_clk;
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
+ freqs.old = omap_getspeed(0);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+#endif
+
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+ struct device *mpu_dev;
+
+ if (cpu_is_omap24xx())
+ mpu_clk = clk_get(NULL, "virt_prcm_set");
+ else if (cpu_is_omap34xx())
+ mpu_clk = clk_get(NULL, "dpll1_ck");
+ else if (cpu_is_omap44xx())
+ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
+
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
+
+ mpu_dev = omap2_get_mpuss_device();
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+ opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(0);
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ clk_exit_cpufreq_table(&freq_table);
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&omap_driver);
+}
+
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for OMAP SoCs");
+MODULE_LICENSE("GPL");
+module_init(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq
2011-09-22 21:07 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq Kevin Hilman
@ 2011-09-22 21:53 ` Tony Lindgren
2011-09-23 9:21 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support,move " Vishwanath Sripathy
1 sibling, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2011-09-22 21:53 UTC (permalink / raw)
To: linux-arm-kernel
* Kevin Hilman <khilman@ti.com> [110922 13:35]:
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>
> Move OMAP cpufreq driver from arch/arm/mach-omap2 into
> drivers/cpufreq, along with a few cleanups:
>
> - generalize support for better handling of different SoCs in the OMAP
> - use OPP layer instead of OMAP clock internals for frequency table init
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [khilman at ti.com: move to drivers]
> Signed-off-by: Kevin Hilman <khilman@ti.com>
Nice to see this happening:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support,move into drivers/cpufreq
2011-09-22 21:07 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq Kevin Hilman
2011-09-22 21:53 ` Tony Lindgren
@ 2011-09-23 9:21 ` Vishwanath Sripathy
2011-09-23 14:02 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move " Kevin Hilman
1 sibling, 1 reply; 26+ messages in thread
From: Vishwanath Sripathy @ 2011-09-23 9:21 UTC (permalink / raw)
To: linux-arm-kernel
Kevin,
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-
> arm-kernel-bounces at lists.infradead.org] On Behalf Of Kevin Hilman
> Sent: Friday, September 23, 2011 2:37 AM
> To: cpufreq at vger.kernel.org; Dave Jones
> Cc: Nishanth Menon; linux-omap at vger.kernel.org; Santosh Shilimkar;
> linux-arm-kernel at lists.infradead.org; Rajendra Nayak
> Subject: [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC
> support,move into drivers/cpufreq
>
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>
> Move OMAP cpufreq driver from arch/arm/mach-omap2 into
> drivers/cpufreq, along with a few cleanups:
>
> - generalize support for better handling of different SoCs in the
> OMAP
> - use OPP layer instead of OMAP clock internals for frequency table
> init
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [khilman at ti.com: move to drivers]
> Signed-off-by: Kevin Hilman <khilman@ti.com>
> ---
> arch/arm/plat-omap/Makefile | 1 -
> arch/arm/plat-omap/cpu-omap.c | 171 -----------------------------
> -------
> drivers/cpufreq/Makefile | 1 +
> drivers/cpufreq/omap-cpufreq.c | 188
> ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 189 insertions(+), 172 deletions(-)
> delete mode 100644 arch/arm/plat-omap/cpu-omap.c
> create mode 100644 drivers/cpufreq/omap-cpufreq.c
>
> diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-
> omap/Makefile
> index f0233e6..4ef7493 100644
> --- a/arch/arm/plat-omap/Makefile
> +++ b/arch/arm/plat-omap/Makefile
> @@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
> obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
> obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
>
> -obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
> obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
> obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
> obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
> diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-
> omap.c
> deleted file mode 100644
> index da4f68d..0000000
> --- a/arch/arm/plat-omap/cpu-omap.c
> +++ /dev/null
> @@ -1,171 +0,0 @@
> -/*
> - * linux/arch/arm/plat-omap/cpu-omap.c
> - *
> - * CPU frequency scaling for OMAP
> - *
> - * Copyright (C) 2005 Nokia Corporation
> - * Written by Tony Lindgren <tony@atomide.com>
> - *
> - * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2
> as
> - * published by the Free Software Foundation.
> - */
> -#include <linux/types.h>
> -#include <linux/kernel.h>
> -#include <linux/sched.h>
> -#include <linux/cpufreq.h>
> -#include <linux/delay.h>
> -#include <linux/init.h>
> -#include <linux/err.h>
> -#include <linux/clk.h>
> -#include <linux/io.h>
> -
> -#include <mach/hardware.h>
> -#include <plat/clock.h>
> -#include <asm/system.h>
> -
> -#define VERY_HI_RATE 900000000
> -
> -static struct cpufreq_frequency_table *freq_table;
> -
> -#ifdef CONFIG_ARCH_OMAP1
> -#define MPU_CLK "mpu"
> -#else
> -#define MPU_CLK "virt_prcm_set"
> -#endif
> -
> -static struct clk *mpu_clk;
> -
> -/* TODO: Add support for SDRAM timing changes */
> -
> -static int omap_verify_speed(struct cpufreq_policy *policy)
> -{
> - if (freq_table)
> - return cpufreq_frequency_table_verify(policy,
> freq_table);
> -
> - if (policy->cpu)
> - return -EINVAL;
> -
> - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
> - policy->cpuinfo.max_freq);
> -
> - policy->min = clk_round_rate(mpu_clk, policy->min * 1000) /
> 1000;
> - policy->max = clk_round_rate(mpu_clk, policy->max * 1000) /
> 1000;
> - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
> - policy->cpuinfo.max_freq);
> - return 0;
> -}
> -
> -static unsigned int omap_getspeed(unsigned int cpu)
> -{
> - unsigned long rate;
> -
> - if (cpu)
> - return 0;
> -
> - rate = clk_get_rate(mpu_clk) / 1000;
> - return rate;
> -}
> -
> -static int omap_target(struct cpufreq_policy *policy,
> - unsigned int target_freq,
> - unsigned int relation)
> -{
> - struct cpufreq_freqs freqs;
> - int ret = 0;
> -
> - /* Ensure desired rate is within allowed range. Some govenors
> - * (ondemand) will just pass target_freq=0 to get the minimum.
> */
> - if (target_freq < policy->min)
> - target_freq = policy->min;
> - if (target_freq > policy->max)
> - target_freq = policy->max;
> -
> - freqs.old = omap_getspeed(0);
> - freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) /
> 1000;
> - freqs.cpu = 0;
> -
> - if (freqs.old == freqs.new)
> - return ret;
> -
> - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> -#ifdef CONFIG_CPU_FREQ_DEBUG
> - printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
> - freqs.old, freqs.new);
> -#endif
> - ret = clk_set_rate(mpu_clk, freqs.new * 1000);
> - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> -
> - return ret;
> -}
> -
> -static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
> -{
> - int result = 0;
> -
> - mpu_clk = clk_get(NULL, MPU_CLK);
> - if (IS_ERR(mpu_clk))
> - return PTR_ERR(mpu_clk);
> -
> - if (policy->cpu != 0)
> - return -EINVAL;
> -
> - policy->cur = policy->min = policy->max = omap_getspeed(0);
> -
> - clk_init_cpufreq_table(&freq_table);
> - if (freq_table) {
> - result = cpufreq_frequency_table_cpuinfo(policy,
> freq_table);
> - if (!result)
> - cpufreq_frequency_table_get_attr(freq_table,
> - policy->cpu);
> - } else {
> - policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) /
> 1000;
> - policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
> - VERY_HI_RATE) /
1000;
> - }
> -
> - /* FIXME: what's the actual transition time? */
> - policy->cpuinfo.transition_latency = 300 * 1000;
> -
> - return 0;
> -}
> -
> -static int omap_cpu_exit(struct cpufreq_policy *policy)
> -{
> - clk_exit_cpufreq_table(&freq_table);
> - clk_put(mpu_clk);
> - return 0;
> -}
> -
> -static struct freq_attr *omap_cpufreq_attr[] = {
> - &cpufreq_freq_attr_scaling_available_freqs,
> - NULL,
> -};
> -
> -static struct cpufreq_driver omap_driver = {
> - .flags = CPUFREQ_STICKY,
> - .verify = omap_verify_speed,
> - .target = omap_target,
> - .get = omap_getspeed,
> - .init = omap_cpu_init,
> - .exit = omap_cpu_exit,
> - .name = "omap",
> - .attr = omap_cpufreq_attr,
> -};
> -
> -static int __init omap_cpufreq_init(void)
> -{
> - return cpufreq_register_driver(&omap_driver);
> -}
> -
> -arch_initcall(omap_cpufreq_init);
> -
> -/*
> - * if ever we want to remove this, upon cleanup call:
> - *
> - * cpufreq_unregister_driver()
> - * cpufreq_frequency_table_put_attr()
> - */
> -
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index a48bc02..ce75fcb 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -43,6 +43,7 @@ obj-$(CONFIG_UX500_SOC_DB8500) +=
> db8500-cpufreq.o
> obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
> obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
> obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
> +obj-$(CONFIG_ARCH_OMAP2PLUS) += omap-cpufreq.o
>
>
> ####################################################################
> ##############
> # PowerPC platform drivers
> diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-
> cpufreq.c
> new file mode 100644
> index 0000000..a6b2be7
> --- /dev/null
> +++ b/drivers/cpufreq/omap-cpufreq.c
> @@ -0,0 +1,188 @@
> +/*
> + * CPU frequency scaling for OMAP
> + *
> + * Copyright (C) 2005 Nokia Corporation
> + * Written by Tony Lindgren <tony@atomide.com>
> + *
> + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
> + *
> + * Copyright (C) 2007-2011 Texas Instruments, Inc.
> + * - OMAP3/4 support by Rajendra Nayak, Santosh Shilimkar
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2
> as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/cpufreq.h>
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/opp.h>
> +
> +#include <asm/system.h>
> +#include <asm/smp_plat.h>
> +
> +#include <plat/clock.h>
> +#include <plat/omap-pm.h>
> +#include <plat/common.h>
> +
> +#include <mach/hardware.h>
> +
> +#define VERY_HI_RATE 900000000
> +
> +static struct cpufreq_frequency_table *freq_table;
> +static struct clk *mpu_clk;
> +
> +static int omap_verify_speed(struct cpufreq_policy *policy)
> +{
> + if (freq_table)
> + return cpufreq_frequency_table_verify(policy,
> freq_table);
> +
> + if (policy->cpu)
> + return -EINVAL;
> +
> + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
> + policy->cpuinfo.max_freq);
> +
> + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) /
> 1000;
> + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) /
> 1000;
> + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
> + policy->cpuinfo.max_freq);
> + return 0;
> +}
> +
> +static unsigned int omap_getspeed(unsigned int cpu)
> +{
> + unsigned long rate;
> +
> + if (cpu)
> + return 0;
> +
> + rate = clk_get_rate(mpu_clk) / 1000;
> + return rate;
> +}
> +
> +static int omap_target(struct cpufreq_policy *policy,
> + unsigned int target_freq,
> + unsigned int relation)
> +{
> + int ret = 0;
> + struct cpufreq_freqs freqs;
> +
> + /* Ensure desired rate is within allowed range. Some govenors
> + * (ondemand) will just pass target_freq=0 to get the minimum.
> */
> + if (target_freq < policy->min)
> + target_freq = policy->min;
> + if (target_freq > policy->max)
> + target_freq = policy->max;
> +
> + freqs.old = omap_getspeed(0);
> + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) /
> 1000;
> + freqs.cpu = 0;
> +
> + if (freqs.old == freqs.new)
> + return ret;
> +
> + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> +
> +#ifdef CONFIG_CPU_FREQ_DEBUG
> + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old,
> freqs.new);
> +#endif
> +
> + ret = clk_set_rate(mpu_clk, freqs.new * 1000);
Do you plan to post follow up patches to scale voltage along with Clock?
Otherwise this will lead to crash on OMAP if voltage set by bootloader is
not good enough for an OPP.
Vishwa
Setting the clock rate w/o voltage scaling would
> +
> + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> +
> + return ret;
> +}
> +
> +static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
> +{
> + int result = 0;
> + struct device *mpu_dev;
> +
> + if (cpu_is_omap24xx())
> + mpu_clk = clk_get(NULL, "virt_prcm_set");
> + else if (cpu_is_omap34xx())
> + mpu_clk = clk_get(NULL, "dpll1_ck");
> + else if (cpu_is_omap44xx())
> + mpu_clk = clk_get(NULL, "dpll_mpu_ck");
> +
> + if (IS_ERR(mpu_clk))
> + return PTR_ERR(mpu_clk);
> +
> + if (policy->cpu != 0)
> + return -EINVAL;
> +
> + policy->cur = policy->min = policy->max = omap_getspeed(0);
> +
> + mpu_dev = omap2_get_mpuss_device();
> + if (!mpu_dev) {
> + pr_warning("%s: unable to get the mpu device\n",
> __func__);
> + return -EINVAL;
> + }
> + opp_init_cpufreq_table(mpu_dev, &freq_table);
> +
> + if (freq_table) {
> + result = cpufreq_frequency_table_cpuinfo(policy,
> freq_table);
> + if (!result)
> + cpufreq_frequency_table_get_attr(freq_table,
> + policy->cpu);
> + } else {
> + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) /
> 1000;
> + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
> + VERY_HI_RATE) /
1000;
> + }
> +
> + policy->min = policy->cpuinfo.min_freq;
> + policy->max = policy->cpuinfo.max_freq;
> + policy->cur = omap_getspeed(0);
> +
> + /* FIXME: what's the actual transition time? */
> + policy->cpuinfo.transition_latency = 300 * 1000;
> +
> + return 0;
> +}
> +
> +static int omap_cpu_exit(struct cpufreq_policy *policy)
> +{
> + clk_exit_cpufreq_table(&freq_table);
> + clk_put(mpu_clk);
> + return 0;
> +}
> +
> +static struct freq_attr *omap_cpufreq_attr[] = {
> + &cpufreq_freq_attr_scaling_available_freqs,
> + NULL,
> +};
> +
> +static struct cpufreq_driver omap_driver = {
> + .flags = CPUFREQ_STICKY,
> + .verify = omap_verify_speed,
> + .target = omap_target,
> + .get = omap_getspeed,
> + .init = omap_cpu_init,
> + .exit = omap_cpu_exit,
> + .name = "omap",
> + .attr = omap_cpufreq_attr,
> +};
> +
> +static int __init omap_cpufreq_init(void)
> +{
> + return cpufreq_register_driver(&omap_driver);
> +}
> +
> +static void __exit omap_cpufreq_exit(void)
> +{
> + cpufreq_unregister_driver(&omap_driver);
> +}
> +
> +MODULE_DESCRIPTION("cpufreq driver for OMAP SoCs");
> +MODULE_LICENSE("GPL");
> +module_init(omap_cpufreq_init);
> +module_exit(omap_cpufreq_exit);
> --
> 1.7.6
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 26+ messages in thread* [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq
2011-09-23 9:21 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support,move " Vishwanath Sripathy
@ 2011-09-23 14:02 ` Kevin Hilman
0 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-23 14:02 UTC (permalink / raw)
To: linux-arm-kernel
Vishwanath Sripathy <vishwanath.bs@ti.com> writes:
[...]
>> +#ifdef CONFIG_CPU_FREQ_DEBUG
>> + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old,
>> freqs.new);
>> +#endif
>> +
>> + ret = clk_set_rate(mpu_clk, freqs.new * 1000);
>
> Do you plan to post follow up patches to scale voltage along with Clock?
Yes.
This series is just a move of existing code + minor cleanups.
The next step is to finalize/merge Tero's regulator driver and use
that to scale voltage along with frequency here.
Now that the voltage domain cleanups are merged, I hope to have
regulator series + voltage scaling changes in this driver ready next week.
Kevin
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
2011-09-22 21:07 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 23:11 ` Kevin Hilman
2013-08-29 10:02 ` Viresh Kumar
2011-09-22 21:07 ` [PATCH 03/10] cpufreq: OMAP: Enable all CPUs in shared policy mask Kevin Hilman
` (8 subsequent siblings)
10 siblings, 2 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Russell King <rmk+kernel@arm.linux.org.uk>
On OMAP SMP configuartion, both processors share the voltage
and clock. So both CPUs needs to be scaled together and hence
needs software co-ordination.
Also, update lpj with reference value to avoid progressive error.
Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate
them with with reference to the initial values to avoid a
progressively bigger and bigger error in the value over time.
While at this, re-use the notifiers for UP/SMP since on UP machine or
UP_ON_SMP policy->cpus mask would contain only the boot CPU.
Based on initial SMP support by Santosh Shilimkar.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[khilman at ti.com: due to overlap/rework, combined original Santosh patch
and Russell's rework]
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 80 +++++++++++++++++++++++++++++++++++-----
1 files changed, 70 insertions(+), 10 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index a6b2be7..f9b4c4d 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -23,6 +23,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/opp.h>
+#include <linux/cpu.h>
#include <asm/system.h>
#include <asm/smp_plat.h>
@@ -35,6 +36,16 @@
#define VERY_HI_RATE 900000000
+#ifdef CONFIG_SMP
+struct lpj_info {
+ unsigned long ref;
+ unsigned int freq;
+};
+
+static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
+static struct lpj_info global_lpj_ref;
+#endif
+
static struct cpufreq_frequency_table *freq_table;
static struct clk *mpu_clk;
@@ -60,7 +71,7 @@ static unsigned int omap_getspeed(unsigned int cpu)
{
unsigned long rate;
- if (cpu)
+ if (cpu >= NR_CPUS)
return 0;
rate = clk_get_rate(mpu_clk) / 1000;
@@ -71,7 +82,7 @@ static int omap_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
- int ret = 0;
+ int i, ret = 0;
struct cpufreq_freqs freqs;
/* Ensure desired rate is within allowed range. Some govenors
@@ -81,22 +92,57 @@ static int omap_target(struct cpufreq_policy *policy,
if (target_freq > policy->max)
target_freq = policy->max;
- freqs.old = omap_getspeed(0);
+ freqs.old = omap_getspeed(policy->cpu);
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
- freqs.cpu = 0;
+ freqs.cpu = policy->cpu;
if (freqs.old == freqs.new)
return ret;
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
#ifdef CONFIG_CPU_FREQ_DEBUG
pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+ freqs.new = omap_getspeed(policy->cpu);
+
+#ifdef CONFIG_SMP
+ /*
+ * Note that loops_per_jiffy is not updated on SMP systems in
+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
+ * on frequency transition. We need to update all dependent CPUs.
+ */
+ for_each_cpu(i, policy->cpus) {
+ struct lpj_info *lpj = &per_cpu(lpj_ref, i);
+ if (!lpj->freq) {
+ lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy;
+ lpj->freq = freqs.old;
+ }
+
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(lpj->ref, lpj->freq, freqs.new);
+ }
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ /* And don't forget to adjust the global one */
+ if (!global_lpj_ref.freq) {
+ global_lpj_ref.ref = loops_per_jiffy;
+ global_lpj_ref.freq = freqs.old;
+ }
+ loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
+ freqs.new);
+#endif
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
return ret;
}
@@ -105,6 +151,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
struct device *mpu_dev;
+ static cpumask_var_t cpumask;
if (cpu_is_omap24xx())
mpu_clk = clk_get(NULL, "virt_prcm_set");
@@ -116,12 +163,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
- if (policy->cpu != 0)
+ if (policy->cpu >= NR_CPUS)
return -EINVAL;
- policy->cur = policy->min = policy->max = omap_getspeed(0);
-
+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
mpu_dev = omap2_get_mpuss_device();
+
if (!mpu_dev) {
pr_warning("%s: unable to get the mpu device\n", __func__);
return -EINVAL;
@@ -141,7 +188,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
- policy->cur = omap_getspeed(0);
+ policy->cur = omap_getspeed(policy->cpu);
+
+ /*
+ * On OMAP SMP configuartion, both processors share the voltage
+ * and clock. So both CPUs needs to be scaled together and hence
+ * needs software co-ordination. Use cpufreq affected_cpus
+ * interface to handle this scenario. Additional is_smp() check
+ * is to keep SMP_ON_UP build working.
+ */
+ if (is_smp()) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
+ cpumask_copy(policy->cpus, cpumask);
+ }
/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 300 * 1000;
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2011-09-22 21:07 ` [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+ Kevin Hilman
@ 2011-09-22 23:11 ` Kevin Hilman
2013-08-29 10:02 ` Viresh Kumar
1 sibling, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 23:11 UTC (permalink / raw)
To: linux-arm-kernel
Kevin Hilman <khilman@ti.com> writes:
> From: Russell King <rmk+kernel@arm.linux.org.uk>
>
> On OMAP SMP configuartion, both processors share the voltage
> and clock. So both CPUs needs to be scaled together and hence
> needs software co-ordination.
[...]
> diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
> index a6b2be7..f9b4c4d 100644
> --- a/drivers/cpufreq/omap-cpufreq.c
> +++ b/drivers/cpufreq/omap-cpufreq.c
> @@ -23,6 +23,7 @@
> #include <linux/clk.h>
> #include <linux/io.h>
> #include <linux/opp.h>
> +#include <linux/cpu.h>
>
> #include <asm/system.h>
> #include <asm/smp_plat.h>
Thanks to checkpatch, I blindly removed an "#include <asm/cpu.h>" here
without re-testing. Turns out it was important.
Added it back, and updated the version available in my
for_3.2/omap-cpufreq branch.
Kevin
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2011-09-22 21:07 ` [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+ Kevin Hilman
2011-09-22 23:11 ` Kevin Hilman
@ 2013-08-29 10:02 ` Viresh Kumar
2013-08-29 13:37 ` Santosh Shilimkar
1 sibling, 1 reply; 26+ messages in thread
From: Viresh Kumar @ 2013-08-29 10:02 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Sep 23, 2011 at 2:37 AM, Kevin Hilman <khilman@ti.com> wrote:
> From: Russell King <rmk+kernel@arm.linux.org.uk>
>
> On OMAP SMP configuartion, both processors share the voltage
> and clock. So both CPUs needs to be scaled together and hence
> needs software co-ordination.
>
> Also, update lpj with reference value to avoid progressive error.
>
> Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate
> them with with reference to the initial values to avoid a
> progressively bigger and bigger error in the value over time.
>
> While at this, re-use the notifiers for UP/SMP since on UP machine or
> UP_ON_SMP policy->cpus mask would contain only the boot CPU.
>
> Based on initial SMP support by Santosh Shilimkar.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [khilman at ti.com: due to overlap/rework, combined original Santosh patch
> and Russell's rework]
> Signed-off-by: Kevin Hilman <khilman@ti.com>
> ---
> drivers/cpufreq/omap-cpufreq.c | 80 +++++++++++++++++++++++++++++++++++-----
> 1 files changed, 70 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
> + /*
> + * On OMAP SMP configuartion, both processors share the voltage
> + * and clock. So both CPUs needs to be scaled together and hence
> + * needs software co-ordination. Use cpufreq affected_cpus
> + * interface to handle this scenario. Additional is_smp() check
> + * is to keep SMP_ON_UP build working.
> + */
> + if (is_smp()) {
> + policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
> + cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
> + cpumask_copy(policy->cpus, cpumask);
> + }
Does somebody remember importance of is_smp() here??
Current code looks like:
if (is_smp())
cpumask_setall(policy->cpus);
And I was looking to remove this check if it is no more useful.. And
so simply do
cpumask_setall(policy->cpus);
^ permalink raw reply [flat|nested] 26+ messages in thread* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2013-08-29 10:02 ` Viresh Kumar
@ 2013-08-29 13:37 ` Santosh Shilimkar
2013-08-29 13:39 ` Viresh Kumar
0 siblings, 1 reply; 26+ messages in thread
From: Santosh Shilimkar @ 2013-08-29 13:37 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 29 August 2013 06:02 AM, Viresh Kumar wrote:
> On Fri, Sep 23, 2011 at 2:37 AM, Kevin Hilman <khilman@ti.com> wrote:
>> From: Russell King <rmk+kernel@arm.linux.org.uk>
>>
>> On OMAP SMP configuartion, both processors share the voltage
>> and clock. So both CPUs needs to be scaled together and hence
>> needs software co-ordination.
>>
>> Also, update lpj with reference value to avoid progressive error.
>>
>> Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate
>> them with with reference to the initial values to avoid a
>> progressively bigger and bigger error in the value over time.
>>
>> While at this, re-use the notifiers for UP/SMP since on UP machine or
>> UP_ON_SMP policy->cpus mask would contain only the boot CPU.
>>
>> Based on initial SMP support by Santosh Shilimkar.
>>
>> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> [khilman at ti.com: due to overlap/rework, combined original Santosh patch
>> and Russell's rework]
>> Signed-off-by: Kevin Hilman <khilman@ti.com>
>> ---
>> drivers/cpufreq/omap-cpufreq.c | 80 +++++++++++++++++++++++++++++++++++-----
>> 1 files changed, 70 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
>
>> + /*
>> + * On OMAP SMP configuartion, both processors share the voltage
>> + * and clock. So both CPUs needs to be scaled together and hence
>> + * needs software co-ordination. Use cpufreq affected_cpus
>> + * interface to handle this scenario. Additional is_smp() check
>> + * is to keep SMP_ON_UP build working.
>> + */
>> + if (is_smp()) {
>> + policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
>> + cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
>> + cpumask_copy(policy->cpus, cpumask);
>> + }
>
> Does somebody remember importance of is_smp() here??
>
Above code was under #ifdef CONFIG_SMP and SMP_ON_UP where config
SMP was enabled as well above steps were not needed.
> Current code looks like:
>
> if (is_smp())
> cpumask_setall(policy->cpus);
>
> And I was looking to remove this check if it is no more useful.. And
> so simply do
>
> cpumask_setall(policy->cpus);
>
Thats should work I guess. Infact I changed this i downstream kernel
a while back but forgot to send a patch. Just see if for some reason
above can break UP machine since this driver is used on UP machines
as well. Other than that, it should be fine
Regards,
Santosh
^ permalink raw reply [flat|nested] 26+ messages in thread* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2013-08-29 13:37 ` Santosh Shilimkar
@ 2013-08-29 13:39 ` Viresh Kumar
2013-08-29 13:42 ` Santosh Shilimkar
0 siblings, 1 reply; 26+ messages in thread
From: Viresh Kumar @ 2013-08-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
On 29 August 2013 19:07, Santosh Shilimkar <santosh.shilimkar@ti.com> wrote:
> On Thursday 29 August 2013 06:02 AM, Viresh Kumar wrote:
>> cpumask_setall(policy->cpus);
>>
> Thats should work I guess. Infact I changed this i downstream kernel
> a while back but forgot to send a patch. Just see if for some reason
> above can break UP machine since this driver is used on UP machines
> as well. Other than that, it should be fine
Atleast I can't see why it will break on UP machines as that should set
masks to individual CPUs then...
Okay I will fix that in my longest patchset ever... 230+ patches already :)
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
2013-08-29 13:39 ` Viresh Kumar
@ 2013-08-29 13:42 ` Santosh Shilimkar
[not found] ` <CAKohpomco=TodaosVbvAhFSxrth9aZ1gh+VOHftG1w6nYWBsPg@mail.gmail.com>
0 siblings, 1 reply; 26+ messages in thread
From: Santosh Shilimkar @ 2013-08-29 13:42 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 29 August 2013 09:39 AM, Viresh Kumar wrote:
> On 29 August 2013 19:07, Santosh Shilimkar <santosh.shilimkar@ti.com> wrote:
>> On Thursday 29 August 2013 06:02 AM, Viresh Kumar wrote:
>
>>> cpumask_setall(policy->cpus);
>>>
>> Thats should work I guess. Infact I changed this i downstream kernel
>> a while back but forgot to send a patch. Just see if for some reason
>> above can break UP machine since this driver is used on UP machines
>> as well. Other than that, it should be fine
>
> Atleast I can't see why it will break on UP machines as that should set
> masks to individual CPUs then...
>
> Okay I will fix that in my longest patchset ever... 230+ patches already :)
>
WoW !!
Looks like you re-wrote most of the CPUFREQ drivers ;-)
Regards,
Santosh
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 03/10] cpufreq: OMAP: Enable all CPUs in shared policy mask
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
2011-09-22 21:07 ` [PATCH 01/10] cpufreq: OMAP: cleanup for multi-SoC support, move into drivers/cpufreq Kevin Hilman
2011-09-22 21:07 ` [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+ Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 04/10] cpufreq: OMAP: notify even with bad boot frequency Kevin Hilman
` (7 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Todd Poynor <toddpoynor@google.com>
Enable all CPUs in the shared policy in the CPU init callback.
Otherwise, the governor CPUFREQ_GOV_START event is invoked with
a policy that only includes the first CPU, leaving other CPUs
uninitialized by the governor.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index f9b4c4d..5e2f05a 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -151,7 +151,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
struct device *mpu_dev;
- static cpumask_var_t cpumask;
if (cpu_is_omap24xx())
mpu_clk = clk_get(NULL, "virt_prcm_set");
@@ -199,8 +198,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
*/
if (is_smp()) {
policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
- cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
- cpumask_copy(policy->cpus, cpumask);
+ cpumask_setall(policy->cpus);
}
/* FIXME: what's the actual transition time? */
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 04/10] cpufreq: OMAP: notify even with bad boot frequency
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (2 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 03/10] cpufreq: OMAP: Enable all CPUs in shared policy mask Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 05/10] cpufreq: OMAP: move clk name decision to init Kevin Hilman
` (6 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Colin Cross <ccross@google.com>
Sometimes, bootloaders starts up with a frequency which is not
in the OPP table. At cpu_init, policy->cur contains the frequency
we pick at boot. It is possible that system might have fixed
it's boot frequency later on as part of power initialization.
After this condition, the first call to omap_target results in the
following:
omap_getspeed(actual device frequency) != policy->cur(frequency that
cpufreq thinks that the system is at), and it is possible that
freqs.old == freqs.new (because the governor requested a scale down).
We exit without triggering the notifiers in the current code, which
does'nt let code which depends on cpufreq_notify_transition to have
accurate information as to what the system frequency is.
Instead, we do a normal transition if policy->cur is wrong, then,
freqs.old will be the actual cpu frequency, freqs.new will be the
actual new cpu frequency and all required notifiers have the accurate
information.
Acked-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Colin Cross <ccross@google.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5e2f05a..724d36c 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -96,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy,
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = policy->cpu;
- if (freqs.old == freqs.new)
+ if (freqs.old == freqs.new && policy->cur == freqs.new)
return ret;
/* notifiers */
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 05/10] cpufreq: OMAP: move clk name decision to init
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (3 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 04/10] cpufreq: OMAP: notify even with bad boot frequency Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 06/10] cpufreq: OMAP: deny initialization if no mpudev Kevin Hilman
` (5 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
Clk name does'nt need to dynamically detected during clk init.
move them off to driver initialization, if we dont have a clk name,
there is no point in registering the driver anyways. The actual clk
get and put is left at cpu_init and exit functions.
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 724d36c..07e835d 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -48,6 +48,7 @@ static struct lpj_info global_lpj_ref;
static struct cpufreq_frequency_table *freq_table;
static struct clk *mpu_clk;
+static char *mpu_clk_name;
static int omap_verify_speed(struct cpufreq_policy *policy)
{
@@ -152,13 +153,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
int result = 0;
struct device *mpu_dev;
- if (cpu_is_omap24xx())
- mpu_clk = clk_get(NULL, "virt_prcm_set");
- else if (cpu_is_omap34xx())
- mpu_clk = clk_get(NULL, "dpll1_ck");
- else if (cpu_is_omap44xx())
- mpu_clk = clk_get(NULL, "dpll_mpu_ck");
-
+ mpu_clk = clk_get(NULL, mpu_clk_name);
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
@@ -232,6 +227,17 @@ static struct cpufreq_driver omap_driver = {
static int __init omap_cpufreq_init(void)
{
+ if (cpu_is_omap24xx())
+ mpu_clk_name = "virt_prcm_set";
+ else if (cpu_is_omap34xx())
+ mpu_clk_name = "dpll1_ck";
+ else if (cpu_is_omap44xx())
+ mpu_clk_name = "dpll_mpu_ck";
+
+ if (!mpu_clk_name) {
+ pr_err("%s: unsupported Silicon?\n", __func__);
+ return -EINVAL;
+ }
return cpufreq_register_driver(&omap_driver);
}
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 06/10] cpufreq: OMAP: deny initialization if no mpudev
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (4 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 05/10] cpufreq: OMAP: move clk name decision to init Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 07/10] cpufreq: OMAP: dont support !freq_table Kevin Hilman
` (4 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
if we do not have mpu_dev we normally fail in cpu_init. It is better
to fail driver registration if the devices are not available.
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 07e835d..fe943b3 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -49,6 +49,7 @@ static struct lpj_info global_lpj_ref;
static struct cpufreq_frequency_table *freq_table;
static struct clk *mpu_clk;
static char *mpu_clk_name;
+static struct device *mpu_dev;
static int omap_verify_speed(struct cpufreq_policy *policy)
{
@@ -151,7 +152,6 @@ static int omap_target(struct cpufreq_policy *policy,
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
- struct device *mpu_dev;
mpu_clk = clk_get(NULL, mpu_clk_name);
if (IS_ERR(mpu_clk))
@@ -161,12 +161,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
return -EINVAL;
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
- mpu_dev = omap2_get_mpuss_device();
-
- if (!mpu_dev) {
- pr_warning("%s: unable to get the mpu device\n", __func__);
- return -EINVAL;
- }
opp_init_cpufreq_table(mpu_dev, &freq_table);
if (freq_table) {
@@ -238,6 +232,13 @@ static int __init omap_cpufreq_init(void)
pr_err("%s: unsupported Silicon?\n", __func__);
return -EINVAL;
}
+
+ mpu_dev = omap2_get_mpuss_device();
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+
return cpufreq_register_driver(&omap_driver);
}
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 07/10] cpufreq: OMAP: dont support !freq_table
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (5 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 06/10] cpufreq: OMAP: deny initialization if no mpudev Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 08/10] cpufreq: OMAP: only supports OPP library Kevin Hilman
` (3 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
OMAP2+ all have frequency tables, hence the hacks we had for older
silicon do not need to be carried forward. As part of this change,
use cpufreq_frequency_table_target to find the best match for
frequency requested.
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 67 +++++++++++++++++++--------------------
1 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index fe943b3..635778d 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -34,8 +34,6 @@
#include <mach/hardware.h>
-#define VERY_HI_RATE 900000000
-
#ifdef CONFIG_SMP
struct lpj_info {
unsigned long ref;
@@ -53,20 +51,9 @@ static struct device *mpu_dev;
static int omap_verify_speed(struct cpufreq_policy *policy)
{
- if (freq_table)
- return cpufreq_frequency_table_verify(policy, freq_table);
-
- if (policy->cpu)
+ if (!freq_table)
return -EINVAL;
-
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
- return 0;
+ return cpufreq_frequency_table_verify(policy, freq_table);
}
static unsigned int omap_getspeed(unsigned int cpu)
@@ -84,18 +71,31 @@ static int omap_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
- int i, ret = 0;
+ unsigned int i;
+ int ret = 0;
struct cpufreq_freqs freqs;
- /* Ensure desired rate is within allowed range. Some govenors
- * (ondemand) will just pass target_freq=0 to get the minimum. */
- if (target_freq < policy->min)
- target_freq = policy->min;
- if (target_freq > policy->max)
- target_freq = policy->max;
+ if (!freq_table) {
+ dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
+ policy->cpu);
+ return -EINVAL;
+ }
+
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &i);
+ if (ret) {
+ dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
+ __func__, policy->cpu, target_freq, ret);
+ return ret;
+ }
+ freqs.new = freq_table[i].frequency;
+ if (!freqs.new) {
+ dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
+ policy->cpu, target_freq);
+ return -EINVAL;
+ }
freqs.old = omap_getspeed(policy->cpu);
- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = policy->cpu;
if (freqs.old == freqs.new && policy->cur == freqs.new)
@@ -161,19 +161,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
return -EINVAL;
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
- opp_init_cpufreq_table(mpu_dev, &freq_table);
-
- if (freq_table) {
- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
- if (!result)
- cpufreq_frequency_table_get_attr(freq_table,
- policy->cpu);
- } else {
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
- VERY_HI_RATE) / 1000;
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (result) {
+ dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
+ __func__, policy->cpu, result);
+ return result;
}
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
policy->cur = omap_getspeed(policy->cpu);
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 08/10] cpufreq: OMAP: only supports OPP library
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (6 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 07/10] cpufreq: OMAP: dont support !freq_table Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 09/10] cpufreq: OMAP: put clk if cpu_init failed Kevin Hilman
` (2 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
OMAP2 is the only family using clk_[init|exit]_cpufreq_table, however,
the cpufreq code does not currently use clk_init_cpufreq_table. As a
result, it is unusuable for OMAP2 and only usable only on platforms
using OPP library.
Remove the unbalanced clk_exit_cpufreq_table(). Any platforms where
OPPs are not availble will fail on init because a freq table will not
be properly initialized.
Signed-off-by: Nishanth Menon <nm@ti.com>
[khilman at ti.com: changelog edits, and graceful failure mode changes]
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 635778d..ce82d50 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -1,5 +1,5 @@
/*
- * CPU frequency scaling for OMAP
+ * CPU frequency scaling for OMAP using OPP information
*
* Copyright (C) 2005 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
@@ -197,7 +197,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
static int omap_cpu_exit(struct cpufreq_policy *policy)
{
- clk_exit_cpufreq_table(&freq_table);
clk_put(mpu_clk);
return 0;
}
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 09/10] cpufreq: OMAP: put clk if cpu_init failed
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (7 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 08/10] cpufreq: OMAP: only supports OPP library Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-09-22 21:07 ` [PATCH 10/10] cpufreq: OMAP: fix freq_table leak Kevin Hilman
2011-11-02 22:02 ` [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
Release the mpu_clk in fail paths.
Reported-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index ce82d50..a66c8b5 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -157,8 +157,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
- if (policy->cpu >= NR_CPUS)
- return -EINVAL;
+ if (policy->cpu >= NR_CPUS) {
+ result = -EINVAL;
+ goto fail_ck;
+ }
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
result = opp_init_cpufreq_table(mpu_dev, &freq_table);
@@ -166,12 +168,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
if (result) {
dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
__func__, policy->cpu, result);
- return result;
+ goto fail_ck;
}
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+ else
+ goto fail_ck;
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
@@ -193,6 +197,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = 300 * 1000;
return 0;
+
+fail_ck:
+ clk_put(mpu_clk);
+ return result;
}
static int omap_cpu_exit(struct cpufreq_policy *policy)
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 10/10] cpufreq: OMAP: fix freq_table leak
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (8 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 09/10] cpufreq: OMAP: put clk if cpu_init failed Kevin Hilman
@ 2011-09-22 21:07 ` Kevin Hilman
2011-11-02 22:02 ` [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
10 siblings, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-09-22 21:07 UTC (permalink / raw)
To: linux-arm-kernel
From: Nishanth Menon <nm@ti.com>
We use a single frequency table for multiple CPUs. But, with
OMAP4, since we have multiple CPUs, the cpu_init call for CPU1
causes freq_table previously allocated for CPU0 to be overwritten.
In addition, we dont free the table on exit path.
We solve this by maintaining an atomic type counter to ensure
just a single table exists at a given time.
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
drivers/cpufreq/omap-cpufreq.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index a66c8b5..90918e1 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -45,6 +45,7 @@ static struct lpj_info global_lpj_ref;
#endif
static struct cpufreq_frequency_table *freq_table;
+static atomic_t freq_table_users = ATOMIC_INIT(0);
static struct clk *mpu_clk;
static char *mpu_clk_name;
static struct device *mpu_dev;
@@ -149,6 +150,12 @@ static int omap_target(struct cpufreq_policy *policy,
return ret;
}
+static inline void freq_table_free(void)
+{
+ if (atomic_dec_and_test(&freq_table_users))
+ opp_free_cpufreq_table(mpu_dev, &freq_table);
+}
+
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
@@ -163,7 +170,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
}
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
- result = opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (atomic_inc_return(&freq_table_users) == 1)
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
if (result) {
dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
@@ -172,10 +181,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
}
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
- if (!result)
- cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
- else
- goto fail_ck;
+ if (result)
+ goto fail_table;
+
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
@@ -198,6 +207,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
return 0;
+fail_table:
+ freq_table_free();
fail_ck:
clk_put(mpu_clk);
return result;
@@ -205,6 +216,7 @@ fail_ck:
static int omap_cpu_exit(struct cpufreq_policy *policy)
{
+ freq_table_free();
clk_put(mpu_clk);
return 0;
}
--
1.7.6
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2
2011-09-22 21:07 [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
` (9 preceding siblings ...)
2011-09-22 21:07 ` [PATCH 10/10] cpufreq: OMAP: fix freq_table leak Kevin Hilman
@ 2011-11-02 22:02 ` Kevin Hilman
2011-11-02 22:08 ` Dave Jones
10 siblings, 1 reply; 26+ messages in thread
From: Kevin Hilman @ 2011-11-02 22:02 UTC (permalink / raw)
To: linux-arm-kernel
Hi Dave,
On 09/22/2011 02:07 PM, Kevin Hilman wrote:
> This series moves the OMAP CPUfreq driver into drivers/cpufreq, add
> support for SMP devices (OMAP4+) and includes several cleanups and
> fixes from Nishanth Menon.
>
> This series applies to v3.1-rc6, and is available here:
>
> git://github.com/khilman/linux-omap-pm.git for_3.2/omap-cpufreq
>
> Kevin
Any chance of this making it in for v3.2?
Kevin
> Colin Cross (1):
> cpufreq: OMAP: notify even with bad boot frequency
>
> Nishanth Menon (6):
> cpufreq: OMAP: move clk name decision to init
> cpufreq: OMAP: deny initialization if no mpudev
> cpufreq: OMAP: dont support !freq_table
> cpufreq: OMAP: only supports OPP library
> cpufreq: OMAP: put clk if cpu_init failed
> cpufreq: OMAP: fix freq_table leak
>
> Russell King (1):
> cpufreq: OMAP: Add SMP support for OMAP4+
>
> Santosh Shilimkar (1):
> cpufreq: OMAP: cleanup for multi-SoC support, move into
> drivers/cpufreq
>
> Todd Poynor (1):
> cpufreq: OMAP: Enable all CPUs in shared policy mask
>
> arch/arm/plat-omap/Makefile | 1 -
> arch/arm/plat-omap/cpu-omap.c | 171 -------------------------
> drivers/cpufreq/Makefile | 1 +
> drivers/cpufreq/omap-cpufreq.c | 271 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 272 insertions(+), 172 deletions(-)
> delete mode 100644 arch/arm/plat-omap/cpu-omap.c
> create mode 100644 drivers/cpufreq/omap-cpufreq.c
>
^ permalink raw reply [flat|nested] 26+ messages in thread* [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2
2011-11-02 22:02 ` [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2 Kevin Hilman
@ 2011-11-02 22:08 ` Dave Jones
2011-11-02 23:37 ` Kevin Hilman
2011-11-08 19:48 ` Kevin Hilman
0 siblings, 2 replies; 26+ messages in thread
From: Dave Jones @ 2011-11-02 22:08 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Nov 02, 2011 at 03:02:37PM -0700, Kevin Hilman wrote:
> Hi Dave,
>
> On 09/22/2011 02:07 PM, Kevin Hilman wrote:
> > This series moves the OMAP CPUfreq driver into drivers/cpufreq, add
> > support for SMP devices (OMAP4+) and includes several cleanups and
> > fixes from Nishanth Menon.
> >
> > This series applies to v3.1-rc6, and is available here:
> >
> > git://github.com/khilman/linux-omap-pm.git for_3.2/omap-cpufreq
> >
> > Kevin
>
> Any chance of this making it in for v3.2?
My kernel.org account being created is blocking on Ted uploading my
signed gpg key. If you want to ask Linus to pull directly until I get
that sorted, feel free. (Though I understand he has a dislike for github trees)
Dave
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2
2011-11-02 22:08 ` Dave Jones
@ 2011-11-02 23:37 ` Kevin Hilman
2011-11-08 19:48 ` Kevin Hilman
1 sibling, 0 replies; 26+ messages in thread
From: Kevin Hilman @ 2011-11-02 23:37 UTC (permalink / raw)
To: linux-arm-kernel
Dave Jones <davej@redhat.com> writes:
> On Wed, Nov 02, 2011 at 03:02:37PM -0700, Kevin Hilman wrote:
> > Hi Dave,
> >
> > On 09/22/2011 02:07 PM, Kevin Hilman wrote:
> > > This series moves the OMAP CPUfreq driver into drivers/cpufreq, add
> > > support for SMP devices (OMAP4+) and includes several cleanups and
> > > fixes from Nishanth Menon.
> > >
> > > This series applies to v3.1-rc6, and is available here:
> > >
> > > git://github.com/khilman/linux-omap-pm.git for_3.2/omap-cpufreq
> > >
> > > Kevin
> >
> > Any chance of this making it in for v3.2?
>
> My kernel.org account being created is blocking on Ted uploading my
> signed gpg key. If you want to ask Linus to pull directly until I get
> that sorted, feel free. (Though I understand he has a dislike for github trees)
Can I take that as an Ack from you for this series?
With your ack, we can maybe merge this via the OMAP tree, or the arm-soc
tree (although it's probably too late now for v3.2.)
Kevin
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2
2011-11-02 22:08 ` Dave Jones
2011-11-02 23:37 ` Kevin Hilman
@ 2011-11-08 19:48 ` Kevin Hilman
2011-11-08 19:59 ` Dave Jones
1 sibling, 1 reply; 26+ messages in thread
From: Kevin Hilman @ 2011-11-08 19:48 UTC (permalink / raw)
To: linux-arm-kernel
On 11/02/2011 03:08 PM, Dave Jones wrote:
> On Wed, Nov 02, 2011 at 03:02:37PM -0700, Kevin Hilman wrote:
> > Hi Dave,
> >
> > On 09/22/2011 02:07 PM, Kevin Hilman wrote:
> > > This series moves the OMAP CPUfreq driver into drivers/cpufreq, add
> > > support for SMP devices (OMAP4+) and includes several cleanups and
> > > fixes from Nishanth Menon.
> > >
> > > This series applies to v3.1-rc6, and is available here:
> > >
> > > git://github.com/khilman/linux-omap-pm.git for_3.2/omap-cpufreq
> > >
> > > Kevin
> >
> > Any chance of this making it in for v3.2?
>
> My kernel.org account being created is blocking on Ted uploading my
> signed gpg key. If you want to ask Linus to pull directly until I get
> that sorted, feel free. (Though I understand he has a dislike for github trees)
OK, due to some other changes in v3.2 (including the module.h stuff) I
need to refresh this against v3.2-rc1.
I see the cpufreq tree is now back on kernel.org, so I'll send you and
updated pull request for this series targeted for inclusion in v3.3.
Thanks,
Kevin
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 00/10] cpufreq: OMAP: move into drivers, cleanups/fixes for v3.2
2011-11-08 19:48 ` Kevin Hilman
@ 2011-11-08 19:59 ` Dave Jones
0 siblings, 0 replies; 26+ messages in thread
From: Dave Jones @ 2011-11-08 19:59 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 08, 2011 at 11:48:44AM -0800, Kevin Hilman wrote:
> OK, due to some other changes in v3.2 (including the module.h stuff) I
> need to refresh this against v3.2-rc1.
>
> I see the cpufreq tree is now back on kernel.org, so I'll send you and
> updated pull request for this series targeted for inclusion in v3.3.
Sharp eyes ;) I'm still getting the hang of the new setup there,
but I'm ready to start queuing stuff up again.
Dave
^ permalink raw reply [flat|nested] 26+ messages in thread