> > > > > +#include <linux/kernel.h> > > + > > +static struct cpu_op mx51_cpu_op[] = { > > + { > > + .cpu_rate = 160000000,}, > > + { > > + .cpu_rate = 800000000,}, > > +}; > > Why did you remove the values between 800MHz and 160MHz? 400MHz and > 200Mhz should work also, no? > > It proved that those operating points don't work well.
> > + > > +struct cpu_op *mx51_get_cpu_op(int *op) > > +{ > > + *op = ARRAY_SIZE(mx51_cpu_op); > > + return mx51_cpu_op; > > +} > > diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h > b/arch/arm/mach-mx5/cpu_op-mx51.h > > new file mode 100644 > > index 0000000..97477fe > > --- /dev/null > > +++ b/arch/arm/mach-mx5/cpu_op-mx51.h > > @@ -0,0 +1,14 @@ > > +/* > > + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. > > + */ > > + > > +/* > > + * The code contained herein is licensed under the GNU General Public > > + * License. You may obtain a copy of the GNU General Public License > > + * Version 2 or later at the following locations: > > + * > > + * http://www.opensource.org/licenses/gpl-license.html > > + * http://www.gnu.org/copyleft/gpl.html > > + */ > > + > > +extern struct cpu_op *mx51_get_cpu_op(int *op); > > diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile > > index 78d405e..a833d38 100644 > > --- a/arch/arm/plat-mxc/Makefile > > +++ b/arch/arm/plat-mxc/Makefile > > @@ -16,6 +16,7 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o > > obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o > > obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o > > obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o > > +obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o > > ifdef CONFIG_SND_IMX_SOC > > obj-y += ssi-fiq.o > > obj-y += ssi-fiq-ksym.o > > diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c > > new file mode 100644 > > index 0000000..9cabeb9 > > --- /dev/null > > +++ b/arch/arm/plat-mxc/cpufreq.c > > @@ -0,0 +1,202 @@ > > +/* > > + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. > > + */ > > + > > +/* > > + * The code contained herein is licensed under the GNU General Public > > + * License. You may obtain a copy of the GNU General Public License > > + * Version 2 or later at the following locations: > > + * > > + * http://www.opensource.org/licenses/gpl-license.html > > + * http://www.gnu.org/copyleft/gpl.html > > + */ > > + > > +/* > > + * A driver for the Freescale Semiconductor i.MXC CPUfreq module. > > + * The CPUFREQ driver is for controling CPU frequency. It allows you to > change > > + * the CPU clock speed on the fly. > > + */ > > + > > +#include <linux/cpufreq.h> > > +#include <linux/clk.h> > > +#include <linux/err.h> > > +#include <linux/slab.h> > > +#include <mach/hardware.h> > > +#include <mach/clock.h> > > + > > +#define CLK32_FREQ 32768 > > +#define NANOSECOND (1000 * 1000 * 1000) > > + > > +static int cpu_freq_khz_min; > > +static int cpu_freq_khz_max; > > +static int arm_normal_clk; > > + > > +static struct clk *cpu_clk; > > +static struct cpufreq_frequency_table *imx_freq_table; > > + > > +static int cpu_op_nr; > > +static struct cpu_op *cpu_op_tbl; > > + > > +static int set_cpu_freq(int freq) > > +{ > > + int ret = 0; > > + int org_cpu_rate; > > + > > + org_cpu_rate = clk_get_rate(cpu_clk); > > + if (org_cpu_rate == freq) > > + return ret; > > You already checked this in mxc_set_target. Once is enough. > Well, this fucntion is not only used in mxc_set_target, so it is safer to still keep checking here. > > > + > > + ret = clk_set_rate(cpu_clk, freq); > > + if (ret != 0) { > > + printk(KERN_DEBUG "cannot set CPU clock rate\n"); > > + return ret; > > + } > > + > > + return ret; > > +} > > + > > +static int mxc_verify_speed(struct cpufreq_policy *policy) > > +{ > > + if (policy->cpu != 0) > > + return -EINVAL; > > + > > + return cpufreq_frequency_table_verify(policy, imx_freq_table); > > +} > > + > > +static unsigned int mxc_get_speed(unsigned int cpu) > > +{ > > + if (cpu) > > + return 0; > > + > > + return clk_get_rate(cpu_clk) / 1000; > > +} > > + > > +static int mxc_set_target(struct cpufreq_policy *policy, > > + unsigned int target_freq, unsigned int relation) > > +{ > > + struct cpufreq_freqs freqs; > > + int freq_Hz; > > + int ret = 0; > > + unsigned int index; > > + > > + cpufreq_frequency_table_target(policy, imx_freq_table, > > + target_freq, relation, &index); > > + freq_Hz = imx_freq_table[index].frequency * 1000; > > + > > + freqs.old = clk_get_rate(cpu_clk) / 1000; > > + freqs.new = freq_Hz / 1000; > > + freqs.cpu = 0; > > + freqs.flags = 0; > > + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); > > + > > + if (freqs.old != freqs.new) > > + ret = set_cpu_freq(freq_Hz); > > + > > + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); > > + > > + return ret; > > +} > > + > > +static int __init mxc_cpufreq_init(struct cpufreq_policy *policy) > > +{ > > + int ret; > > + int i; > > + > > + printk(KERN_INFO "i.MXC CPU frequency driver\n"); > > + > > + if (policy->cpu != 0) > > + return -EINVAL; > > + > > + cpu_clk = clk_get(NULL, "cpu_clk"); > > + if (IS_ERR(cpu_clk)) { > > + printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); > > + return PTR_ERR(cpu_clk); > > + } > > + > > + cpu_op_tbl = get_cpu_op(&cpu_op_nr); > > This will crash every board except the babbage board which happens to > set this function pointer. > Add a checking here should avoid that.
_______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev