diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index b78bc35973ba..e37cdaedbb5b 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -68,8 +68,6 @@ static int imx6q_set_target(struct cpufreq_policy *policy, if (freqs.old == freqs.new) return 0; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - rcu_read_lock(); opp = opp_find_freq_ceil(cpu_dev, &freq_hz); if (IS_ERR(opp)) { @@ -86,13 +84,16 @@ static int imx6q_set_target(struct cpufreq_policy *policy, freqs.old / 1000, volt_old / 1000, freqs.new / 1000, volt / 1000); + cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); + /* scaling up? scale voltage before frequency */ if (freqs.new > freqs.old) { ret = regulator_set_voltage_tol(arm_reg, volt, 0); if (ret) { dev_err(cpu_dev, "failed to scale vddarm up: %d\n", ret); - return ret; + freqs.new = freqs.old; + goto post_notify; } /* @@ -145,15 +146,18 @@ static int imx6q_set_target(struct cpufreq_policy *policy, if (ret) { dev_err(cpu_dev, "failed to set clock rate: %d\n", ret); regulator_set_voltage_tol(arm_reg, volt_old, 0); - return ret; + freqs.new = freqs.old; + goto post_notify; } /* scaling down? scale voltage after frequency */ if (freqs.new < freqs.old) { ret = regulator_set_voltage_tol(arm_reg, volt, 0); - if (ret) + if (ret) { dev_warn(cpu_dev, "failed to scale vddarm down: %d\n", ret); + ret = 0; + } if (freqs.old == FREQ_1P2_GHZ / 1000) { regulator_set_voltage_tol(pu_reg, @@ -163,9 +167,10 @@ static int imx6q_set_target(struct cpufreq_policy *policy, } } +post_notify: cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - return 0; + return ret; } static int imx6q_cpufreq_init(struct cpufreq_policy *policy)