From 8df0a6637767474989022b93230a8615f11fb53b Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 2 Oct 2012 15:39:03 -0700 Subject: cpufreq: OMAP: ensure valid clock rate before scaling Ensure the clock rate that will be used is a valid one before attempting to scale the voltage. Currently the driver assumes it has a valid frequency from the OPP table, but boards using different system oscillators might not have exact matches with the OPP table, and result in a failing call to clk_set_rate(). This is particularily bad because the voltage may be scaled even though the frequency is not. This will obviously lead to some unpredictable behavior, especially if the frequency is high and the voltage is dropped. Thanks to Joni Lapilainen for reporting crashes seen on 3430/n900. Reported-by: Joni Lapilainen Acked-by: Rafael J. Wysocki Signed-off-by: Kevin Hilman diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 65f8e9a..0fe395a 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -108,6 +108,14 @@ static int omap_target(struct cpufreq_policy *policy, } freq = freqs.new * 1000; + ret = clk_round_rate(mpu_clk, freq); + if (IS_ERR_VALUE(ret)) { + dev_warn(mpu_dev, + "CPUfreq: Cannot find matching frequency for %lu\n", + freq); + return ret; + } + freq = ret; if (mpu_reg) { opp = opp_find_freq_ceil(mpu_dev, &freq); -- cgit v0.10.2 From 4075944b4c724ca70bdc5086527b55e73db546b4 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 26 Sep 2012 16:45:29 -0700 Subject: cpufreq: OMAP: remove unused The headers are going away, and this one is not used. remove it. Acked-by: Rafael J. Wysocki Signed-off-by: Kevin Hilman diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 0fe395a..7d4d455 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -31,7 +31,6 @@ #include #include -#include #include #include -- cgit v0.10.2 From e2ee1b4d86f53c49c06a14dc10616f6d8aa05ea9 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 7 Sep 2012 18:16:35 +0000 Subject: cpufreq: OMAP: fix clock usage to be SoC independent, remove plat/ includes OMAP core code now has SoC-independent clock alias for the scalable CPU clock. Using it means driver is SoC independent and will work for AM3xxx SoCs as well as OMAP1/3/4. While here, remove some unnecessary plat/ includes that are interfering with multi-subarch ARM kernels. Signed-off-by: Paul Walmsley [tony@atomide.com: updated already changed clock aliases] Signed-off-by: Tony Lindgren [khilman@ti.com: minor shortlog/changelog updates] Acked-by: Rafael J. Wysocki Signed-off-by: Kevin Hilman diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 7d4d455..5d1f5e4 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -30,19 +30,14 @@ #include #include -#include -#include #include -#include - /* OPP tolerance in percentage */ #define OPP_TOLERANCE 4 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; static struct regulator *mpu_reg; @@ -179,7 +174,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) { int result = 0; - mpu_clk = clk_get(NULL, mpu_clk_name); + mpu_clk = clk_get(NULL, "cpufreq_ck"); if (IS_ERR(mpu_clk)) return PTR_ERR(mpu_clk); @@ -260,18 +255,6 @@ 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; - } - mpu_dev = omap_device_get_by_hwmod_name("mpu"); if (IS_ERR(mpu_dev)) { pr_warning("%s: unable to get the mpu device\n", __func__); -- cgit v0.10.2 From 747a7f64201b8ffa8654c8767c5f794fdfa4239e Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 6 Sep 2012 14:22:44 -0700 Subject: cpufreq: OMAP: use get_cpu_device() instead of omap_device API OMAP PM core code has moved to using the existing, generic CPU devices for attaching OPPs, so the CPUfreq driver can now use the generic get_cpu_device() API instead of the OMAP-specific omap_device API. This allows us to remove the last include from this driver. Cc: Paul Walmsley Acked-by: Rafael J. Wysocki Signed-off-by: Kevin Hilman diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 5d1f5e4..1f3417a 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -30,8 +30,6 @@ #include #include -#include - /* OPP tolerance in percentage */ #define OPP_TOLERANCE 4 @@ -255,10 +253,10 @@ static struct cpufreq_driver omap_driver = { static int __init omap_cpufreq_init(void) { - mpu_dev = omap_device_get_by_hwmod_name("mpu"); - if (IS_ERR(mpu_dev)) { + mpu_dev = get_cpu_device(0); + if (!mpu_dev) { pr_warning("%s: unable to get the mpu device\n", __func__); - return PTR_ERR(mpu_dev); + return -EINVAL; } mpu_reg = regulator_get(mpu_dev, "vcc"); -- cgit v0.10.2 From 24d7b40a60cf19008334bcbcbd98da374d4d9c64 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 6 Sep 2012 14:03:08 -0700 Subject: ARM: OMAP2+: PM: MPU DVFS: use generic CPU device for MPU-SS Currently, a dummy omap_device is created for the MPU sub-system so that a device node exists for MPU DVFS. Specifically, for the association of MPU OPPs to a device node, and so that a voltage regulator can be mapped to a device node. For drivers to get a handle to this device node, an OMAP-specific API has been used. However, the kernel already has device nodes for the CPU(s) in the system, so we can use those instead of an OMAP-specific dummy device and then drivers (like OMAP CPUfreq) can use generic APIs. To use the existing CPU device nodes, modify the OPP creation and regulator registration to use the CPU0 device node for registraion. NOTE: this patch always uses CPU0 as the device node. On all OMAPs today, MPU DVFS scales all CPUs together, so this will not be a problem, but this assumption will need to be changed if independently scalable CPUs are introduced. Cc: Paul Walmsley Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index 45ad7f7..58e16ae 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -18,6 +18,7 @@ */ #include #include +#include #include @@ -62,13 +63,23 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, __func__, i); return -EINVAL; } - oh = omap_hwmod_lookup(opp_def->hwmod_name); - if (!oh || !oh->od) { - pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", - __func__, opp_def->hwmod_name, i); - continue; + + if (!strncmp(opp_def->hwmod_name, "mpu", 3)) { + /* + * All current OMAPs share voltage rail and + * clock source, so CPU0 is used to represent + * the MPU-SS. + */ + dev = get_cpu_device(0); + } else { + oh = omap_hwmod_lookup(opp_def->hwmod_name); + if (!oh || !oh->od) { + pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", + __func__, opp_def->hwmod_name, i); + continue; + } + dev = &oh->od->pdev->dev; } - dev = &oh->od->pdev->dev; r = opp_add(dev, opp_def->freq, opp_def->u_volt); if (r) { diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 939bd6f..173c2be 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -168,7 +169,15 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, goto exit; } - dev = omap_device_get_by_hwmod_name(oh_name); + if (!strncmp(oh_name, "mpu", 3)) + /* + * All current OMAPs share voltage rail and clock + * source, so CPU0 is used to represent the MPU-SS. + */ + dev = get_cpu_device(0); + else + dev = omap_device_get_by_hwmod_name(oh_name); + if (IS_ERR(dev)) { pr_err("%s: Unable to get dev pointer for hwmod %s\n", __func__, oh_name); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 45f7741..3f5eacc 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -158,7 +158,7 @@ static struct regulator_init_data omap3_vpll2_idata = { }; static struct regulator_consumer_supply omap3_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "mpu.0"), + REGULATOR_SUPPLY("vcc", "cpu0"), }; static struct regulator_consumer_supply omap3_vdd2_supply[] = { -- cgit v0.10.2