From: chenxing Date: Thu, 14 Jun 2012 08:01:00 +0000 (+0800) Subject: rk30:sdk: add interface to freeze cpufreq when earlysuspend X-Git-Tag: firefly_0821_release~9092 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f5fbeecdfee0a0cd7002299d6c4318ab9d3d42ec;p=firefly-linux-kernel-4.4.55.git rk30:sdk: add interface to freeze cpufreq when earlysuspend --- diff --git a/arch/arm/mach-rk30/cpufreq.c b/arch/arm/mach-rk30/cpufreq.c index d503495b9d77..007867f2afb8 100755 --- a/arch/arm/mach-rk30/cpufreq.c +++ b/arch/arm/mach-rk30/cpufreq.c @@ -26,7 +26,11 @@ #include #include #include - +#include +#include +#include +#include +#include #ifdef DEBUG #define FREQ_PRINTK_DBG(fmt, args...) pr_debug(fmt, ## args) #define FREQ_PRINTK_LOG(fmt, args...) pr_debug(fmt, ## args) @@ -303,6 +307,170 @@ static struct freq_attr *rk30_cpufreq_attr[] = { NULL, }; +/**************************earlysuspend freeze cpu frequency******************************/ +static struct early_suspend ff_early_suspend; + +#define FILE_GOV_MODE "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" +#define FILE_SETSPEED "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" +#define FILE_CUR_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" + +#define FF_DEBUG(fmt, args...) printk(KERN_DEBUG "FREEZE FREQ DEBUG:\t"fmt, ##args) +#define FF_ERROR(fmt, args...) printk(KERN_ERR "FREEZE FREQ ERROR:\t"fmt, ##args) + +static int ff_read(char *file_path, char *buf) +{ + struct file *file = NULL; + mm_segment_t old_fs; + loff_t offset = 0; + + FF_DEBUG("read %s\n", file_path); + file = filp_open(file_path, O_RDONLY, 0); + + if (IS_ERR(file)) { + FF_ERROR("%s error open file %s\n", __func__, file_path); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + file->f_op->read(file, (char *)buf, 32, &offset); + sscanf(buf, "%s", buf); + + set_fs(old_fs); + filp_close(file, NULL); + + file = NULL; + + return 0; + +} + +static int ff_write(char *file_path, char *buf) +{ + struct file *file = NULL; + mm_segment_t old_fs; + loff_t offset = 0; + + FF_DEBUG("write %s %s size = %d\n", file_path, buf, strlen(buf)); + file = filp_open(file_path, O_RDWR, 0); + + if (IS_ERR(file)) { + FF_ERROR("%s error open file %s\n", __func__, file_path); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + file->f_op->write(file, (char *)buf, strlen(buf), &offset); + + set_fs(old_fs); + filp_close(file, NULL); + + file = NULL; + + return 0; + +} + +static void ff_scale_votlage(char *name, int volt) +{ + struct regulator* regulator; + int ret = 0; + + FF_DEBUG("enter %s\n", __func__); + regulator = dvfs_get_regulator(name); + if (!regulator) { + FF_ERROR("get regulator %s ERROR\n", name); + return ; + } + + ret = regulator_set_voltage(regulator, volt, volt); + if (ret != 0) { + FF_ERROR("set voltage error %s %d, ret = %d\n", name, volt, ret); + } + +} + +static void ff_early_suspend_func(struct early_suspend *h) +{ + char buf[32]; + FF_DEBUG("enter %s\n", __func__); + if (ff_read(FILE_GOV_MODE, buf) != 0) { + FF_ERROR("read current governor error\n"); + return ; + } else { + FF_DEBUG("current governor = %s\n", buf); + } + + strcpy(buf, "userspace"); + if (ff_write(FILE_GOV_MODE, buf) != 0) { + FF_ERROR("set current governor error\n"); + return ; + } + + strcpy(buf, "252000"); + if (ff_write(FILE_SETSPEED, buf) != 0) { + FF_ERROR("set speed to 252MHz error\n"); + return ; + } + + //ff_scale_votlage("vdd_cpu", 1000000); + //ff_scale_votlage("vdd_core", 1000000); + cpu_down(1); +} + +static void ff_early_resume_func(struct early_suspend *h) +{ + char buf[32]; + FF_DEBUG("enter %s\n", __func__); + + cpu_up(1); + if (ff_read(FILE_GOV_MODE, buf) != 0) { + FF_ERROR("read current governor error\n"); + return ; + } else { + FF_DEBUG("current governor = %s\n", buf); + } + + if (ff_read(FILE_CUR_FREQ, buf) != 0) { + FF_ERROR("read current frequency error\n"); + return ; + } else { + FF_DEBUG("current frequency = %s\n", buf); + } + + strcpy(buf, "interactive"); + if (ff_write(FILE_GOV_MODE, buf) != 0) { + FF_ERROR("set current governor error\n"); + return ; + } + + strcpy(buf, "interactive"); + if (ff_write(FILE_GOV_MODE, buf) != 0) { + FF_ERROR("set current governor error\n"); + return ; + } +} + +static int __init ff_init(void) +{ + FF_DEBUG("enter %s\n", __func__); + ff_early_suspend.suspend = ff_early_suspend_func; + ff_early_suspend.resume = ff_early_resume_func; + ff_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 100; + register_early_suspend(&ff_early_suspend); + return 0; +} + +static void __exit ff_exit(void) +{ + FF_DEBUG("enter %s\n", __func__); + unregister_early_suspend(&ff_early_suspend); +} + + /**************************target freq******************************/ static unsigned int cpufreq_scale_limt(unsigned int target_freq, struct cpufreq_policy *policy) {