msm: dcvs: update dcvs if the governor limits change.
We had seen issues where dcvs goes out of sync with the actual
freq the cpu is running at. The root cause was if the userspace
changes the limits on the governor, the governor ends up changing
the frequency without notifying dcvs.
Provide an api for the governor to call dcvs when a frequency change
happens.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
(cherry picked from commit 68c970e38fcb700d851301dbacc56da9387294c6)
Signed-off-by: Ram Kumar Chakravarthy Chebathini <rcheba@codeaurora.org>
(cherry picked from commit a7d720e513cfae2d3f9c03c25f2ce2f10c2e9de7)
Change-Id: I3f321df0270e997531d1a4cf3ee2251f86aef0bc
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/msm_dcvs.h b/arch/arm/mach-msm/include/mach/msm_dcvs.h
index e8908e8..fe99c0f 100644
--- a/arch/arm/mach-msm/include/mach/msm_dcvs.h
+++ b/arch/arm/mach-msm/include/mach/msm_dcvs.h
@@ -152,4 +152,11 @@
*/
extern int msm_dcvs_freq_sink_unregister(struct msm_dcvs_freq *drv);
+/**
+ * msm_dcvs_update_limits
+ * @drv: The sink driver
+ *
+ * Update the frequency known to dcvs when the limits are changed.
+ */
+extern void msm_dcvs_update_limits(struct msm_dcvs_freq *drv);
#endif
diff --git a/arch/arm/mach-msm/msm_dcvs.c b/arch/arm/mach-msm/msm_dcvs.c
index f761bf9..2181337 100644
--- a/arch/arm/mach-msm/msm_dcvs.c
+++ b/arch/arm/mach-msm/msm_dcvs.c
@@ -635,6 +635,17 @@
}
EXPORT_SYMBOL(msm_dcvs_register_core);
+void msm_dcvs_update_limits(struct msm_dcvs_freq *drv)
+{
+ struct dcvs_core *core;
+
+ if (!drv || !drv->core_name || !drv->get_frequency)
+ return;
+
+ core = msm_dcvs_get_core(drv->core_name, false);
+ core->actual_freq = drv->get_frequency(drv);
+}
+
int msm_dcvs_freq_sink_register(struct msm_dcvs_freq *drv)
{
int ret = -EINVAL;
diff --git a/drivers/cpufreq/cpufreq_gov_msm.c b/drivers/cpufreq/cpufreq_gov_msm.c
index 11eb9f5..f69cceb 100644
--- a/drivers/cpufreq/cpufreq_gov_msm.c
+++ b/drivers/cpufreq/cpufreq_gov_msm.c
@@ -36,11 +36,13 @@
static void msm_gov_check_limits(struct cpufreq_policy *policy)
{
struct msm_gov *gov = &per_cpu(msm_gov_info, policy->cpu);
+ struct msm_dcvs_freq *dcvs_notifier =
+ &(per_cpu(msm_gov_info, policy->cpu).gov_notifier);
if (policy->max < gov->cur_freq)
__cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H);
- else if (policy->min > gov->min_freq)
+ else if (policy->min > gov->cur_freq)
__cpufreq_driver_target(policy, policy->min,
CPUFREQ_RELATION_L);
else
@@ -50,6 +52,7 @@
gov->cur_freq = policy->cur;
gov->min_freq = policy->min;
gov->max_freq = policy->max;
+ msm_dcvs_update_limits(dcvs_notifier);
}
static int msm_dcvs_freq_set(struct msm_dcvs_freq *self,
@@ -91,7 +94,7 @@
* The policy->cur won't be updated in this case - so it is safe to
* access policy->cur
*/
- return gov->cur_freq;
+ return gov->policy->cur;
}
static int cpufreq_governor_msm(struct cpufreq_policy *policy,