On Sat, Dec 19, 2009 at 1:34 AM, Wan ZongShun <mcuos.com@xxxxxxxxx> wrote: > Hi Jie, > > This is a good patch, thanks! > Some comments below: Hi Wan, Thanks for you comments, I'll send a new patch later. > > 2009/12/14 Li Jie <eltshanli@xxxxxxxxx>: >> Hi, Wan ZongShun: >> >> This patch add cpufreq support for nuc900 CPUs. >> >> Signed-off-by: lijie <eltshanli@xxxxxxxxx> >> --- >> arch/arm/Kconfig | 1 + >> arch/arm/mach-w90x900/Makefile | 2 +- >> arch/arm/mach-w90x900/cpu.c | 4 +- >> arch/arm/mach-w90x900/cpufreq.c | 146 +++++++++++++++++++++++++++++++++++++++ >> 4 files changed, 151 insertions(+), 2 deletions(-) >> create mode 100644 arch/arm/mach-w90x900/cpufreq.c >> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig >> index cf8a99f..60186fe 100644 >> --- a/arch/arm/Kconfig >> +++ b/arch/arm/Kconfig >> @@ -539,6 +539,7 @@ config ARCH_W90X900 >> select COMMON_CLKDEV >> select GENERIC_TIME >> select GENERIC_CLOCKEVENTS >> + select ARCH_HAS_CPUFREQ >> help >> Support for Nuvoton (Winbond logic dept.) ARM9 processor, >> At present, the w90x900 has been renamed nuc900, regarding >> diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile >> index 828c032..7f114fb 100644 >> --- a/arch/arm/mach-w90x900/Makefile >> +++ b/arch/arm/mach-w90x900/Makefile >> @@ -5,7 +5,7 @@ >> # Object file lists. >> >> obj-y := irq.o time.o mfp.o gpio.o clock.o >> -obj-y += clksel.o dev.o cpu.o >> +obj-y += clksel.o dev.o cpu.o cpufreq.o >> # W90X900 CPU support files >> >> obj-$(CONFIG_CPU_W90P910) += nuc910.o >> diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c >> index 921cef9..7b608b8 100644 >> --- a/arch/arm/mach-w90x900/cpu.c >> +++ b/arch/arm/mach-w90x900/cpu.c >> @@ -107,7 +107,7 @@ struct platform_device nuc900_serial_device = { >> }; >> >> /*Set NUC900 series cpu frequence*/ >> -static int __init nuc900_set_clkval(unsigned int cpufreq) >> +int nuc900_set_clkval(unsigned int cpufreq) >> { >> unsigned int pllclk, ahbclk, apbclk, val; >> >> @@ -156,6 +156,8 @@ static int __init nuc900_set_clkval(unsigned int cpufreq) >> >> return 0; >> } >> +EXPORT_SYMBOL(nuc900_set_clkval); >> + >> static int __init nuc900_set_cpufreq(char *str) >> { >> unsigned long cpufreq, val; >> diff --git a/arch/arm/mach-w90x900/cpufreq.c b/arch/arm/mach-w90x900/cpufreq.c >> new file mode 100644 >> index 0000000..07b8685 >> --- /dev/null >> +++ b/arch/arm/mach-w90x900/cpufreq.c >> @@ -0,0 +1,146 @@ >> +/* linux/arch/arm/mach-w90x900/cpufreq.c >> + * >> + * NUC900 CPUfreq Support >> + * >> + * Li Jie <eltshanli@xxxxxxxxx> >> + * >> + * 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/kernel.h> >> +#include <linux/types.h> >> +#include <linux/init.h> >> +#include <linux/cpufreq.h> >> +#include <linux/clk.h> >> +#include <linux/err.h> >> + >> +#include <asm/io.h> >> +#include <mach/hardware.h> >> +#include <mach/regs-clock.h> >> + >> +extern int nuc900_set_clkval(unsigned int cpufreq); >> + > > Please put this extern definition in cpu.h file and add include "cpu.h". > >> +static struct cpufreq_frequency_table nuc900_freq_table[] = { >> + { 0, 66000 }, >> + { 1, 100000 }, >> + { 2, 120000 }, >> + { 3, 166000 }, >> + { 4, 200000 }, >> + { 5, CPUFREQ_TABLE_END }, >> +}; >> + > > Please define those cpu frequncy number as clear Marco, such as: > > #define FREQ_66M 66000 > > and, the Macro can be re-used by below codes. > >> +static int nuc900_cpufreq_verify_speed(struct cpufreq_policy *policy) >> +{ >> + if (policy->cpu != 0) >> + return -EINVAL; >> + >> + return cpufreq_frequency_table_verify(policy, nuc900_freq_table); >> +} >> + >> +static unsigned int nuc900_cpufreq_get_speed(unsigned int cpu) >> +{ >> + int pllclk; >> + >> + if (cpu != 0) >> + return 0; >> + >> + pllclk = __raw_readl(REG_PLLCON0); >> + >> + switch (pllclk) { >> + case PLL_66MHZ: >> + return 66 * 1000; >> + case PLL_100MHZ: >> + return 100 * 1000; >> + case PLL_120MHZ: >> + return 120 * 1000; >> + case PLL_166MHZ: >> + return 166 * 1000; >> + case PLL_200MHZ: >> + return 200 * 1000; >> + } >> + >> + pr_err("cpufreq: Failed to get frequency: %X\n", pllclk); > > Though %X is right, but ,is lowercase more unanimous? > >> + return 0; >> +} >> + >> +static int nuc900_cpufreq_set_target(struct cpufreq_policy *policy, >> + unsigned int target_freq, >> + unsigned int relation) >> +{ >> + int ret; >> + unsigned int i; >> + struct cpufreq_freqs freqs; >> + >> + ret = cpufreq_frequency_table_target(policy, nuc900_freq_table, >> + target_freq, relation, &i); >> + if (ret != 0) >> + return ret; >> + >> + freqs.cpu = 0; >> + freqs.old = nuc900_cpufreq_get_speed(0); >> + freqs.new = nuc900_freq_table[i].frequency; >> + freqs.flags = 0; >> + >> + if (freqs.old == freqs.new) >> + return 0; >> + >> + pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); >> + >> + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); >> + >> + nuc900_set_clkval(freqs.new / 1000); >> + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); >> + >> + return 0; >> +} >> + >> +static int __init nuc900_cpufreq_driver_init(struct cpufreq_policy *policy) >> +{ >> + int ret; >> + >> + if (policy->cpu != 0) >> + return -EINVAL; >> + >> + policy->cur = nuc900_cpufreq_get_speed(0); >> + >> + policy->cpuinfo.transition_latency = 2 * 1000; /* FIXME, assumed */ >> + policy->cpuinfo.min_freq = 66000; /* khz */ >> + policy->cpuinfo.max_freq = 200000; >> + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; >> + >> + ret = cpufreq_frequency_table_cpuinfo(policy, nuc900_freq_table); >> + if (ret != 0) >> + pr_err("cpufreq: Failed to configure frequency table: %d\n", >> + ret); >> + >> + return ret; >> +} >> + >> +static struct cpufreq_driver nuc900_cpufreq_driver = { >> + .owner = THIS_MODULE, >> + .flags = 0, >> + .verify = nuc900_cpufreq_verify_speed, >> + .target = nuc900_cpufreq_set_target, >> + .get = nuc900_cpufreq_get_speed, >> + .init = nuc900_cpufreq_driver_init, >> + .name = "nuc900", >> +}; > > Don't name this cpufreq driver 'nuc900'. > >> +static int __init nuc900_cpufreq_init(void) >> +{ >> + return cpufreq_register_driver(&nuc900_cpufreq_driver); >> +} >> + >> +static void __exit nuc900_cpufreq_exit(void) >> +{ >> + cpufreq_unregister_driver(&nuc900_cpufreq_driver); >> +} >> + >> +MODULE_AUTHOR ("Li Jie <eltshanli@xxxxxxxxx>"); >> +MODULE_DESCRIPTION ("cpufreq driver for NUC900"); >> +MODULE_LICENSE ("GPL"); >> + >> +module_init(nuc900_cpufreq_init); >> +module_exit(nuc900_cpufreq_exit); >> -- >> 1.6.5.4 >> > > > > -- > linux-arm-kernel mailing list > linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > -- Regards Li Jie -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html