From: Finley Xiao Date: Wed, 12 Apr 2017 10:38:58 +0000 (+0800) Subject: cpufreq: dt: support checking initial rate X-Git-Tag: release-20171130_firefly~4^2~793 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3f48f9795cbc98d8b08a109f9c3d6699411d8ef2;p=firefly-linux-kernel-4.4.55.git cpufreq: dt: support checking initial rate Bootloader or kernel sets CPU frequency to an initial value before cpufreq starts on rockchip platform, if cpu's opp table is modified to a specified value, it will cause an issue. For example, the initial frequency is 816MHz and voltage set by hardware is 900mV: 1. there is only one opp whose frequency is 816MHz and voltage is 850mV in opp table list, as they frequency is equal, the voltage will not be changed, it is still 900mV and a little too large relative to 850mV. 2. there is only one opp whose frequency is 1200MHz and voltage is 1100mV in opp table list, as it doesn't set voltage to 1100mV before set frequency to 1200MHz in the dev_pm_opp_set_rate function, the initial voltage 900mV cann't supply for 1200MHz, the system crash. Change-Id: Iba41536367ba5802dd8f7f37e245f0e5781eb643 Signed-off-by: Finley Xiao --- diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 37604c72c9b9..4202e81de3a5 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -29,6 +29,8 @@ #include #include +#define MAX_CLUSTERS 2 + struct private_data { struct device *cpu_dev; struct thermal_cooling_device *cdev; @@ -153,9 +155,11 @@ static int cpufreq_init(struct cpufreq_policy *policy) struct cpumask cpus; #endif unsigned int transition_latency; + unsigned long cur_freq; bool opp_v1 = false; const char *name; int ret; + static int check_init; cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -297,6 +301,13 @@ static int cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = transition_latency; + if (check_init < MAX_CLUSTERS) { + ret = dev_pm_opp_check_initial_rate(cpu_dev, &cur_freq); + if (!ret) + policy->cur = cur_freq / 1000; + check_init++; + } + return 0; out_free_cpufreq_table: @@ -373,11 +384,8 @@ static void cpufreq_ready(struct cpufreq_policy *policy) } static struct cpufreq_driver dt_cpufreq_driver = { -#ifdef CONFIG_ARCH_ROCKCHIP - .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY, -#else - .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, -#endif + .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK | + CPUFREQ_HAVE_GOVERNOR_PER_POLICY, .verify = cpufreq_generic_frequency_table_verify, .target_index = set_target, .get = cpufreq_generic_get,