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

Commit c0ff1bbe authored by Viresh Kumar's avatar Viresh Kumar Committed by Junjie Wu
Browse files

cpufreq: move freq change notifications to cpufreq core



Most of the drivers do following in their ->target_index() routines:

	struct cpufreq_freqs freqs;
	freqs.old = old freq...
	freqs.new = new freq...

	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

	/* Change rate here */

	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

This is replicated over all cpufreq drivers today and there doesn't exists a
good enough reason why this shouldn't be moved to cpufreq core instead.

There are few special cases though, like exynos5440, which doesn't do everything
on the call to ->target_index() routine and call some kind of bottom halves for
doing this work, work/tasklet/etc..

They may continue doing notification from their own code as flag:
CPUFREQ_ASYNC_NOTIFICATION is already set for them.

All drivers are also modified in this patch to avoid breaking 'git bisect', as
double notification would happen otherwise.

Acked-by: default avatarHans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: default avatarJesper Nilsson <jesper.nilsson@axis.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarRussell King <linux@arm.linux.org.uk>
Acked-by: default avatarStephen Warren <swarren@nvidia.com>
Tested-by: default avatarAndrew Lunn <andrew@lunn.ch>
Tested-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
Reviewed-by: default avatarLan Tianyu <tianyu.lan@intel.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Git-commit: d4019f0a92ab802f385cc9c8ad3ab7b5449712cb
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[junjiew@codeaurora.org: dropped all conflicted changes in arch specific
 cpufreq files that we don't use]
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent a6a73212
Loading
Loading
Loading
Loading
+5 −19
Original line number Original line Diff line number Diff line
@@ -192,39 +192,25 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
static int bL_cpufreq_set_target(struct cpufreq_policy *policy,
static int bL_cpufreq_set_target(struct cpufreq_policy *policy,
		unsigned int index)
		unsigned int index)
{
{
	struct cpufreq_freqs freqs;
	u32 cpu = policy->cpu, cur_cluster, new_cluster, actual_cluster;
	u32 cpu = policy->cpu, cur_cluster, new_cluster, actual_cluster;
	int ret = 0;
	unsigned int freqs_new;


	cur_cluster = cpu_to_cluster(cpu);
	cur_cluster = cpu_to_cluster(cpu);
	new_cluster = actual_cluster = per_cpu(physical_cluster, cpu);
	new_cluster = actual_cluster = per_cpu(physical_cluster, cpu);


	freqs.old = bL_cpufreq_get_rate(cpu);
	freqs_new = freq_table[cur_cluster][index].frequency;
	freqs.new = freq_table[cur_cluster][index].frequency;

	pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n",
			__func__, cpu, cur_cluster, freqs.old, freqs.new,
			freqs.new);


	if (is_bL_switching_enabled()) {
	if (is_bL_switching_enabled()) {
		if ((actual_cluster == A15_CLUSTER) &&
		if ((actual_cluster == A15_CLUSTER) &&
				(freqs.new < clk_big_min)) {
				(freqs_new < clk_big_min)) {
			new_cluster = A7_CLUSTER;
			new_cluster = A7_CLUSTER;
		} else if ((actual_cluster == A7_CLUSTER) &&
		} else if ((actual_cluster == A7_CLUSTER) &&
				(freqs.new > clk_little_max)) {
				(freqs_new > clk_little_max)) {
			new_cluster = A15_CLUSTER;
			new_cluster = A15_CLUSTER;
		}
		}
	}
	}


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	return bL_cpufreq_set_rate(cpu, actual_cluster, new_cluster, freqs_new);

	ret = bL_cpufreq_set_rate(cpu, actual_cluster, new_cluster, freqs.new);
	if (ret)
		freqs.new = freqs.old;

	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

	return ret;
}
}


static inline u32 get_table_count(struct cpufreq_frequency_table *table)
static inline u32 get_table_count(struct cpufreq_frequency_table *table)
+37 −3
Original line number Original line Diff line number Diff line
@@ -1698,6 +1698,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
		retval = cpufreq_driver->target(policy, target_freq, relation);
		retval = cpufreq_driver->target(policy, target_freq, relation);
	else if (cpufreq_driver->target_index) {
	else if (cpufreq_driver->target_index) {
		struct cpufreq_frequency_table *freq_table;
		struct cpufreq_frequency_table *freq_table;
		struct cpufreq_freqs freqs;
		bool notify;
		int index;
		int index;


		freq_table = cpufreq_frequency_get_table(policy->cpu);
		freq_table = cpufreq_frequency_get_table(policy->cpu);
@@ -1713,10 +1715,42 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
			goto out;
			goto out;
		}
		}


		if (freq_table[index].frequency == policy->cur)
		if (freq_table[index].frequency == policy->cur) {
			retval = 0;
			retval = 0;
		else
			goto out;
		}

		notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);

		if (notify) {
			freqs.old = policy->cur;
			freqs.new = freq_table[index].frequency;
			freqs.flags = 0;

			pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
					__func__, policy->cpu, freqs.old,
					freqs.new);

			cpufreq_notify_transition(policy, &freqs,
					CPUFREQ_PRECHANGE);
		}

		retval = cpufreq_driver->target_index(policy, index);
		retval = cpufreq_driver->target_index(policy, index);
		if (retval)
			pr_err("%s: Failed to change cpu frequency: %d\n",
					__func__, retval);

		if (notify) {
			/*
			 * Notify with old freq in case we failed to change
			 * frequency
			 */
			if (retval)
				freqs.new = freqs.old;

			cpufreq_notify_transition(policy, &freqs,
					CPUFREQ_POSTCHANGE);
		}
	}
	}


out:
out:
+0 −19
Original line number Original line Diff line number Diff line
@@ -141,7 +141,6 @@ processor_set_freq (
{
{
	int			ret = 0;
	int			ret = 0;
	u32			value = 0;
	u32			value = 0;
	struct cpufreq_freqs    cpufreq_freqs;
	cpumask_t		saved_mask;
	cpumask_t		saved_mask;
	int			retval;
	int			retval;


@@ -168,13 +167,6 @@ processor_set_freq (
	pr_debug("Transitioning from P%d to P%d\n",
	pr_debug("Transitioning from P%d to P%d\n",
		data->acpi_data.state, state);
		data->acpi_data.state, state);


	/* cpufreq frequency struct */
	cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency;
	cpufreq_freqs.new = data->freq_table[state].frequency;

	/* notify cpufreq */
	cpufreq_notify_transition(policy, &cpufreq_freqs, CPUFREQ_PRECHANGE);

	/*
	/*
	 * First we write the target state's 'control' value to the
	 * First we write the target state's 'control' value to the
	 * control_register.
	 * control_register.
@@ -186,22 +178,11 @@ processor_set_freq (


	ret = processor_set_pstate(value);
	ret = processor_set_pstate(value);
	if (ret) {
	if (ret) {
		unsigned int tmp = cpufreq_freqs.new;
		cpufreq_notify_transition(policy, &cpufreq_freqs,
				CPUFREQ_POSTCHANGE);
		cpufreq_freqs.new = cpufreq_freqs.old;
		cpufreq_freqs.old = tmp;
		cpufreq_notify_transition(policy, &cpufreq_freqs,
				CPUFREQ_PRECHANGE);
		cpufreq_notify_transition(policy, &cpufreq_freqs,
				CPUFREQ_POSTCHANGE);
		printk(KERN_WARNING "Transition failed with error %d\n", ret);
		printk(KERN_WARNING "Transition failed with error %d\n", ret);
		retval = -ENODEV;
		retval = -ENODEV;
		goto migrate_end;
		goto migrate_end;
	}
	}


	cpufreq_notify_transition(policy, &cpufreq_freqs, CPUFREQ_POSTCHANGE);

	data->acpi_data.state = state;
	data->acpi_data.state = state;


	retval = 0;
	retval = 0;
+4 −17
Original line number Original line Diff line number Diff line
@@ -231,7 +231,7 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
				      unsigned int relation)
				      unsigned int relation)
{
{
	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
	struct cpufreq_freqs freqs;
	unsigned int new_freq;
	int idx, ret, to_dvs = 0;
	int idx, ret, to_dvs = 0;
	unsigned int i;
	unsigned int i;


@@ -256,25 +256,14 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
		goto out;
		goto out;
	}
	}


	freqs.flags = 0;
	freqs.old = s3c_freq->is_dvs ? FREQ_DVS
				     : clk_get_rate(s3c_freq->armclk) / 1000;

	/* When leavin dvs mode, always switch the armdiv to the hclk rate
	/* When leavin dvs mode, always switch the armdiv to the hclk rate
	 * The S3C2416 has stability issues when switching directly to
	 * The S3C2416 has stability issues when switching directly to
	 * higher frequencies.
	 * higher frequencies.
	 */
	 */
	freqs.new = (s3c_freq->is_dvs && !to_dvs)
	new_freq = (s3c_freq->is_dvs && !to_dvs)
				? clk_get_rate(s3c_freq->hclk) / 1000
				? clk_get_rate(s3c_freq->hclk) / 1000
				: s3c_freq->freq_table[i].frequency;
				: s3c_freq->freq_table[i].frequency;


	pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);

	if (!to_dvs && freqs.old == freqs.new)
		goto out;

	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

	if (to_dvs) {
	if (to_dvs) {
		pr_debug("cpufreq: enter dvs\n");
		pr_debug("cpufreq: enter dvs\n");
		ret = s3c2416_cpufreq_enter_dvs(s3c_freq, idx);
		ret = s3c2416_cpufreq_enter_dvs(s3c_freq, idx);
@@ -282,12 +271,10 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
		pr_debug("cpufreq: leave dvs\n");
		pr_debug("cpufreq: leave dvs\n");
		ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx);
		ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx);
	} else {
	} else {
		pr_debug("cpufreq: change armdiv to %dkHz\n", freqs.new);
		pr_debug("cpufreq: change armdiv to %dkHz\n", new_freq);
		ret = s3c2416_cpufreq_set_armdiv(s3c_freq, freqs.new);
		ret = s3c2416_cpufreq_set_armdiv(s3c_freq, new_freq);
	}
	}


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

out:
out:
	mutex_unlock(&cpufreq_lock);
	mutex_unlock(&cpufreq_lock);


+0 −7
Original line number Original line Diff line number Diff line
@@ -252,7 +252,6 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy,
	unsigned long new_bits, new_freq;
	unsigned long new_bits, new_freq;
	unsigned long clock_tick, divisor, old_divisor, estar;
	unsigned long clock_tick, divisor, old_divisor, estar;
	cpumask_t cpus_allowed;
	cpumask_t cpus_allowed;
	struct cpufreq_freqs freqs;


	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
	set_cpus_allowed_ptr(current, cpumask_of(cpu));
	set_cpus_allowed_ptr(current, cpumask_of(cpu));
@@ -266,16 +265,10 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy,


	old_divisor = estar_to_divisor(estar);
	old_divisor = estar_to_divisor(estar);


	freqs.old = clock_tick / old_divisor;
	freqs.new = new_freq;
	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

	if (old_divisor != divisor)
	if (old_divisor != divisor)
		us2e_transition(estar, new_bits, clock_tick * 1000,
		us2e_transition(estar, new_bits, clock_tick * 1000,
				old_divisor, divisor);
				old_divisor, divisor);


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

	set_cpus_allowed_ptr(current, &cpus_allowed);
	set_cpus_allowed_ptr(current, &cpus_allowed);
}
}


Loading