diff options
| author | Linus Torvalds <[email protected]> | 2009-03-28 14:03:14 -0700 | 
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2009-03-28 14:03:14 -0700 | 
| commit | 0fe41b8982001cd14ee2c77cd776735a5024e98b (patch) | |
| tree | 83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/plat-omap/cpu-omap.c | |
| parent | eedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff) | |
| parent | 9759d22c8348343b0da4e25d6150c41712686c14 (diff) | |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits)
  [ARM] 5435/1: fix compile warning in sanity_check_meminfo()
  [ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx
  [ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0
  [ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins
  imxfb: Fix TFT mode
  i.MX21/27: remove ifdef CONFIG_FB_IMX
  imxfb: add clock support
  mxc: add arch_reset() function
  clkdev: add possibility to get a clock based on the device name
  i.MX1: remove fb support from mach-imx
  [ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined
  Gemini: Add support for Teltonika RUT100
  Gemini: gpiolib based GPIO support v2
  MAINTAINERS: add myself as Gemini architecture maintainer
  ARM: Add Gemini architecture v3
  [ARM] OMAP: Fix compile for omap2_init_common_hw()
  MAINTAINERS: Add myself as Faraday ARM core variant maintainer
  ARM: Add support for FA526 v2
  [ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h
  [ARM] collie: fix two minor formatting nits
  ...
Diffstat (limited to 'arch/arm/plat-omap/cpu-omap.c')
| -rw-r--r-- | arch/arm/plat-omap/cpu-omap.c | 57 | 
1 files changed, 53 insertions, 4 deletions
| diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index b2690242a390..843e8af64066 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -23,10 +23,13 @@  #include <linux/io.h>  #include <mach/hardware.h> +#include <mach/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 @@ -39,6 +42,9 @@ static struct clk *mpu_clk;  int omap_verify_speed(struct cpufreq_policy *policy)  { +	if (freq_table) +		return cpufreq_frequency_table_verify(policy, freq_table); +  	if (policy->cpu)  		return -EINVAL; @@ -70,12 +76,26 @@ static int omap_target(struct cpufreq_policy *policy,  	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->cpuinfo.min_freq) +		target_freq = policy->cpuinfo.min_freq; +	if (target_freq > policy->cpuinfo.max_freq) +		target_freq = policy->cpuinfo.max_freq; +  	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); -	ret = clk_set_rate(mpu_clk, target_freq * 1000); +#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; @@ -83,16 +103,31 @@ static int omap_target(struct cpufreq_policy *policy,  static int __init 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); -	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->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + +	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 = 10 * 1000 * 1000;  	return 0;  } @@ -103,6 +138,11 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)  	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, @@ -111,6 +151,7 @@ static struct cpufreq_driver omap_driver = {  	.init		= omap_cpu_init,  	.exit		= omap_cpu_exit,  	.name		= "omap", +	.attr		= omap_cpufreq_attr,  };  static int __init omap_cpufreq_init(void) @@ -119,3 +160,11 @@ static int __init omap_cpufreq_init(void)  }  arch_initcall(omap_cpufreq_init); + +/* + * if ever we want to remove this, upon cleanup call: + * + * cpufreq_unregister_driver() + * cpufreq_frequency_table_put_attr() + */ + |