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

Commit 589e18a9 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-cpufreq'

* pm-cpufreq:
  cpufreq: cpufreq-cpu0: remove dependency on THERMAL and REGULATOR
  cpufreq: tegra: update comment for clarity
  cpufreq: intel_pstate: Remove duplicate CPU ID check
  cpufreq: Mark CPU0 driver with CPUFREQ_NEED_INITIAL_FREQ_CHECK flag
  cpufreq: governor: remove copy_prev_load from 'struct cpu_dbs_common_info'
  cpufreq: governor: Be friendly towards latency-sensitive bursty workloads
  cpufreq: ppc-corenet-cpu-freq: do_div use quotient
  Revert "cpufreq: Enable big.LITTLE cpufreq driver on arm64"
  cpufreq: Tegra: implement intermediate frequency callbacks
  cpufreq: add support for intermediate (stable) frequencies
parents de815a6d 5fbfbcd3
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ Contents:
1.4  target/target_index or setpolicy?
1.5  target/target_index
1.6  setpolicy
1.7  get_intermediate and target_intermediate
2.   Frequency Table Helpers


@@ -79,6 +80,10 @@ cpufreq_driver.attr - A pointer to a NULL-terminated list of
				"struct freq_attr" which allow to
				export values to sysfs.

cpufreq_driver.get_intermediate
and target_intermediate		Used to switch to stable frequency while
				changing CPU frequency.


1.2 Per-CPU Initialization
--------------------------
@@ -151,7 +156,7 @@ Some cpufreq-capable processors switch the frequency between certain
limits on their own. These shall use the ->setpolicy call


1.4. target/target_index
1.5. target/target_index
-------------

The target_index call has two arguments: struct cpufreq_policy *policy,
@@ -160,6 +165,9 @@ and unsigned int index (into the exposed frequency table).
The CPUfreq driver must set the new frequency when called here. The
actual frequency must be determined by freq_table[index].frequency.

It should always restore to earlier frequency (i.e. policy->restore_freq) in
case of errors, even if we switched to intermediate frequency earlier.

Deprecated:
----------
The target call has three arguments: struct cpufreq_policy *policy,
@@ -179,7 +187,7 @@ Here again the frequency table helper might assist you - see section 2
for details.


1.5 setpolicy
1.6 setpolicy
---------------

The setpolicy call only takes a struct cpufreq_policy *policy as
@@ -190,6 +198,23 @@ setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
the reference implementation in drivers/cpufreq/longrun.c

1.7 get_intermediate and target_intermediate
--------------------------------------------

Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.

get_intermediate should return a stable intermediate frequency platform wants to
switch to, and target_intermediate() should set CPU to to that frequency, before
jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().

Drivers can return '0' from get_intermediate() in case they don't wish to switch
to intermediate frequency for some target frequency. In that case core will
directly call ->target_index().

NOTE: ->target_index() should restore to policy->restore_freq in case of
failures as core would send notifications for that.


2. Frequency Table Helpers
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE

config GENERIC_CPUFREQ_CPU0
	tristate "Generic CPU0 cpufreq driver"
	depends on HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL
	depends on HAVE_CLK && OF
	select PM_OPP
	help
	  This adds a generic cpufreq driver for CPU0 frequency management.
+1 −2
Original line number Diff line number Diff line
@@ -5,8 +5,7 @@
# big LITTLE core layer and glue drivers
config ARM_BIG_LITTLE_CPUFREQ
	tristate "Generic ARM big LITTLE CPUfreq driver"
	depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)
	depends on HAVE_CLK
	depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
	select PM_OPP
	help
	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
}

static struct cpufreq_driver cpu0_cpufreq_driver = {
	.flags = CPUFREQ_STICKY,
	.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
	.verify = cpufreq_generic_frequency_table_verify,
	.target_index = cpu0_set_target,
	.get = cpufreq_generic_get,
+60 −7
Original line number Diff line number Diff line
@@ -1816,20 +1816,55 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
 *                              GOVERNORS                            *
 *********************************************************************/

/* Must set freqs->new to intermediate frequency */
static int __target_intermediate(struct cpufreq_policy *policy,
				 struct cpufreq_freqs *freqs, int index)
{
	int ret;

	freqs->new = cpufreq_driver->get_intermediate(policy, index);

	/* We don't need to switch to intermediate freq */
	if (!freqs->new)
		return 0;

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

	cpufreq_freq_transition_begin(policy, freqs);
	ret = cpufreq_driver->target_intermediate(policy, index);
	cpufreq_freq_transition_end(policy, freqs, ret);

	if (ret)
		pr_err("%s: Failed to change to intermediate frequency: %d\n",
		       __func__, ret);

	return ret;
}

static int __target_index(struct cpufreq_policy *policy,
			  struct cpufreq_frequency_table *freq_table, int index)
{
	struct cpufreq_freqs freqs;
	struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};
	unsigned int intermediate_freq = 0;
	int retval = -EINVAL;
	bool notify;

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

	if (notify) {
		freqs.old = policy->cur;
		freqs.new = freq_table[index].frequency;
		freqs.flags = 0;
		/* Handle switching to intermediate frequency */
		if (cpufreq_driver->get_intermediate) {
			retval = __target_intermediate(policy, &freqs, index);
			if (retval)
				return retval;

			intermediate_freq = freqs.new;
			/* Set old freq to intermediate */
			if (intermediate_freq)
				freqs.old = freqs.new;
		}

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

@@ -1841,9 +1876,23 @@ static int __target_index(struct cpufreq_policy *policy,
		pr_err("%s: Failed to change cpu frequency: %d\n", __func__,
		       retval);

	if (notify)
	if (notify) {
		cpufreq_freq_transition_end(policy, &freqs, retval);

		/*
		 * Failed after setting to intermediate freq? Driver should have
		 * reverted back to initial frequency and so should we. Check
		 * here for intermediate_freq instead of get_intermediate, in
		 * case we have't switched to intermediate freq at all.
		 */
		if (unlikely(retval && intermediate_freq)) {
			freqs.old = intermediate_freq;
			freqs.new = policy->restore_freq;
			cpufreq_freq_transition_begin(policy, &freqs);
			cpufreq_freq_transition_end(policy, &freqs, 0);
		}
	}

	return retval;
}

@@ -1875,6 +1924,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
	if (target_freq == policy->cur)
		return 0;

	/* Save last value to restore later on errors */
	policy->restore_freq = policy->cur;

	if (cpufreq_driver->target)
		retval = cpufreq_driver->target(policy, target_freq, relation);
	else if (cpufreq_driver->target_index) {
@@ -2361,7 +2413,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
	    !(driver_data->setpolicy || driver_data->target_index ||
		    driver_data->target) ||
	     (driver_data->setpolicy && (driver_data->target_index ||
		    driver_data->target)))
		    driver_data->target)) ||
	     (!!driver_data->get_intermediate != !!driver_data->target_intermediate))
		return -EINVAL;

	pr_debug("trying to register driver %s\n", driver_data->name);
Loading