Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0672860 authored by Thomas Renninger's avatar Thomas Renninger Committed by Dave Jones
Browse files

[CPUFREQ] Get rid of userspace policy struct, make userspace gov _PPC safe.



Userspace governor need not to hold it's own cpufreq_policy,
better make use of the global core policy.
Also fixes a bug in case of frequency changes via _PPC.
Old min/max values have wrongly been passed to __cpufreq_driver_target()
(kind of buffered) and when max freq was available again, only the old
max(normally lowest freq) was still active.

Signed-off-by: default avatarThomas Renninger <trenn@suse.de>
Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarDave Jones <davej@redhat.com>

 cpufreq_userspace.c |   53 +++++++++++++++++++++++++++-------------------------
 1 files changed, 28 insertions(+), 25 deletions(-)
parent 0961dd0d
Loading
Loading
Loading
Loading
+28 −25
Original line number Original line Diff line number Diff line

/*
/*
 *  linux/drivers/cpufreq/cpufreq_userspace.c
 *  linux/drivers/cpufreq/cpufreq_userspace.c
 *
 *
@@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS];
static unsigned int	cpu_cur_freq[NR_CPUS]; /* current CPU freq */
static unsigned int	cpu_cur_freq[NR_CPUS]; /* current CPU freq */
static unsigned int	cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
static unsigned int	cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
static unsigned int	cpu_is_managed[NR_CPUS];
static unsigned int	cpu_is_managed[NR_CPUS];
static struct cpufreq_policy current_policy[NR_CPUS];


static DEFINE_MUTEX	(userspace_mutex);
static DEFINE_MUTEX	(userspace_mutex);


@@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
 *
 *
 * Sets the CPU frequency to freq.
 * Sets the CPU frequency to freq.
 */
 */
static int cpufreq_set(unsigned int freq, unsigned int cpu)
static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
{
{
	int ret = -EINVAL;
	int ret = -EINVAL;


	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);


	mutex_lock(&userspace_mutex);
	mutex_lock(&userspace_mutex);
	if (!cpu_is_managed[cpu])
	if (!cpu_is_managed[policy->cpu])
		goto err;
		goto err;


	cpu_set_freq[cpu] = freq;
	cpu_set_freq[policy->cpu] = freq;


	if (freq < cpu_min_freq[cpu])
	if (freq < cpu_min_freq[policy->cpu])
		freq = cpu_min_freq[cpu];
		freq = cpu_min_freq[policy->cpu];
	if (freq > cpu_max_freq[cpu])
	if (freq > cpu_max_freq[policy->cpu])
		freq = cpu_max_freq[cpu];
		freq = cpu_max_freq[policy->cpu];


	/*
	/*
	 * We're safe from concurrent calls to ->target() here
	 * We're safe from concurrent calls to ->target() here
@@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu)
	 * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
	 * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
	 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
	 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
	 */
	 */
	ret = __cpufreq_driver_target(&current_policy[cpu], freq, 
	ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
	      CPUFREQ_RELATION_L);


 err:
 err:
	mutex_unlock(&userspace_mutex);
	mutex_unlock(&userspace_mutex);
@@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
	if (ret != 1)
	if (ret != 1)
		return -EINVAL;
		return -EINVAL;


	cpufreq_set(freq, policy->cpu);
	cpufreq_set(freq, policy);


	return count;
	return count;
}
}
@@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
		cpu_cur_freq[cpu] = policy->cur;
		cpu_cur_freq[cpu] = policy->cur;
		cpu_set_freq[cpu] = policy->cur;
		cpu_set_freq[cpu] = policy->cur;
		sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
		sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
		dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
		dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
		mutex_unlock(&userspace_mutex);
		mutex_unlock(&userspace_mutex);
		break;
		break;
@@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
		break;
		break;
	case CPUFREQ_GOV_LIMITS:
	case CPUFREQ_GOV_LIMITS:
		mutex_lock(&userspace_mutex);
		mutex_lock(&userspace_mutex);
		cpu_min_freq[cpu] = policy->min;
		dprintk("limit event for cpu %u: %u - %u kHz,"
		cpu_max_freq[cpu] = policy->max;
			"currently %u kHz, last set to %u kHz\n",
		dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]);
			cpu, policy->min, policy->max,
			cpu_cur_freq[cpu], cpu_set_freq[cpu]);
		if (policy->max < cpu_set_freq[cpu]) {
		if (policy->max < cpu_set_freq[cpu]) {
			__cpufreq_driver_target(&current_policy[cpu], policy->max, 
			__cpufreq_driver_target(policy, policy->max,
						CPUFREQ_RELATION_H);
						CPUFREQ_RELATION_H);
		} else if (policy->min > cpu_set_freq[cpu]) {
		}
			__cpufreq_driver_target(&current_policy[cpu], policy->min, 
		else if (policy->min > cpu_set_freq[cpu]) {
			__cpufreq_driver_target(policy, policy->min,
						CPUFREQ_RELATION_L);
						CPUFREQ_RELATION_L);
		} else {
		}
			__cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
		else {
			__cpufreq_driver_target(policy, cpu_set_freq[cpu],
						CPUFREQ_RELATION_L);
						CPUFREQ_RELATION_L);
		}
		}
		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
		cpu_min_freq[cpu] = policy->min;
		cpu_max_freq[cpu] = policy->max;
		cpu_cur_freq[cpu] = policy->cur;
		mutex_unlock(&userspace_mutex);
		mutex_unlock(&userspace_mutex);
		break;
		break;
	}
	}