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>
This commit is contained in:
Abhijeet Dharmapurikar 2012-08-31 20:42:53 -07:00 committed by Stephen Boyd
parent 0a3ed737d2
commit f66d89e397
3 changed files with 23 additions and 2 deletions

View file

@ -152,4 +152,11 @@ extern int msm_dcvs_freq_sink_register(struct msm_dcvs_freq *drv);
*/
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

View file

@ -635,6 +635,17 @@ bail:
}
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;

View file

@ -36,11 +36,13 @@ static char core_name[NR_CPUS][10];
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 @@ static void msm_gov_check_limits(struct cpufreq_policy *policy)
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 @@ static unsigned int msm_dcvs_freq_get(struct msm_dcvs_freq *self)
* 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,