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

Merge branch 'pm-cpufreq'

* pm-cpufreq: (31 commits)
  cpufreq: Fix cpufreq_online() return value on errors
  cpufreq: Fix up several kerneldoc comments
  cpufreq: stats: Use local_clock() instead of jiffies
  cpufreq: schedutil: Simplify sugov_update_next_freq()
  cpufreq: intel_pstate: Simplify intel_cpufreq_update_pstate()
  cpufreq: arm_scmi: Discover the power scale in performance protocol
  firmware: arm_scmi: Add power_scale_mw_get() interface
  cpufreq: tegra194: Rename tegra194_get_speed_common function
  cpufreq: tegra194: Remove unnecessary frequency calculation
  cpufreq: tegra186: Simplify cluster information lookup
  cpufreq: tegra186: Fix sparse 'incorrect type in assignment' warning
  cpufreq: imx: fix NVMEM_IMX_OCOTP dependency
  cpufreq: vexpress-spc: Add missing MODULE_ALIAS
  cpufreq: scpi: Add missing MODULE_ALIAS
  cpufreq: loongson1: Add missing MODULE_ALIAS
  cpufreq: sun50i: Add missing MODULE_DEVICE_TABLE
  cpufreq: st: Add missing MODULE_DEVICE_TABLE
  cpufreq: qcom: Add missing MODULE_DEVICE_TABLE
  cpufreq: mediatek: Add missing MODULE_DEVICE_TABLE
  cpufreq: highbank: Add missing MODULE_DEVICE_TABLE
  ...
parents f0f6dbaf 30c76882
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ config ARM_IMX6Q_CPUFREQ
	tristate "Freescale i.MX6 cpufreq support"
	depends on ARCH_MXC
	depends on REGULATOR_ANATOP
	select NVMEM_IMX_OCOTP
	depends on NVMEM_IMX_OCOTP || COMPILE_TEST
	select PM_OPP
	help
	  This adds cpufreq driver support for Freescale i.MX6 series SoCs.
+6 −0
Original line number Diff line number Diff line
@@ -204,6 +204,12 @@ static void __exit armada_8k_cpufreq_exit(void)
}
module_exit(armada_8k_cpufreq_exit);

static const struct of_device_id __maybe_unused armada_8k_cpufreq_of_match[] = {
	{ .compatible = "marvell,ap806-cpu-clock" },
	{ },
};
MODULE_DEVICE_TABLE(of, armada_8k_cpufreq_of_match);

MODULE_AUTHOR("Gregory Clement <gregory.clement@bootlin.com>");
MODULE_DESCRIPTION("Armada 8K cpufreq driver");
MODULE_LICENSE("GPL");
+82 −81
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
/* Minimum struct length needed for the DMI processor entry we want */
#define DMI_ENTRY_PROCESSOR_MIN_LENGTH	48

/* Offest in the DMI processor structure for the max frequency */
/* Offset in the DMI processor structure for the max frequency */
#define DMI_PROCESSOR_MAX_SPEED		0x14

/*
@@ -96,11 +96,11 @@ static u64 cppc_get_dmi_max_khz(void)
 * and extrapolate the rest
 * For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion
 */
static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu,
static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu_data,
					     unsigned int perf)
{
	struct cppc_perf_caps *caps = &cpu_data->perf_caps;
	static u64 max_khz;
	struct cppc_perf_caps *caps = &cpu->perf_caps;
	u64 mul, div;

	if (caps->lowest_freq && caps->nominal_freq) {
@@ -120,11 +120,11 @@ static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu,
	return (u64)perf * mul / div;
}

static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu,
static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data,
					     unsigned int freq)
{
	struct cppc_perf_caps *caps = &cpu_data->perf_caps;
	static u64 max_khz;
	struct cppc_perf_caps *caps = &cpu->perf_caps;
	u64  mul, div;

	if (caps->lowest_freq && caps->nominal_freq) {
@@ -149,29 +149,27 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
				   unsigned int target_freq,
				   unsigned int relation)
{
	struct cppc_cpudata *cpu;
	struct cppc_cpudata *cpu_data = all_cpu_data[policy->cpu];
	struct cpufreq_freqs freqs;
	u32 desired_perf;
	int ret = 0;

	cpu = all_cpu_data[policy->cpu];

	desired_perf = cppc_cpufreq_khz_to_perf(cpu, target_freq);
	desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq);
	/* Return if it is exactly the same perf */
	if (desired_perf == cpu->perf_ctrls.desired_perf)
	if (desired_perf == cpu_data->perf_ctrls.desired_perf)
		return ret;

	cpu->perf_ctrls.desired_perf = desired_perf;
	cpu_data->perf_ctrls.desired_perf = desired_perf;
	freqs.old = policy->cur;
	freqs.new = target_freq;

	cpufreq_freq_transition_begin(policy, &freqs);
	ret = cppc_set_perf(cpu->cpu, &cpu->perf_ctrls);
	ret = cppc_set_perf(cpu_data->cpu, &cpu_data->perf_ctrls);
	cpufreq_freq_transition_end(policy, &freqs, ret != 0);

	if (ret)
		pr_debug("Failed to set target on CPU:%d. ret:%d\n",
				cpu->cpu, ret);
			 cpu_data->cpu, ret);

	return ret;
}
@@ -184,28 +182,29 @@ static int cppc_verify_policy(struct cpufreq_policy_data *policy)

static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy)
{
	int cpu_num = policy->cpu;
	struct cppc_cpudata *cpu = all_cpu_data[cpu_num];
	struct cppc_cpudata *cpu_data = all_cpu_data[policy->cpu];
	struct cppc_perf_caps *caps = &cpu_data->perf_caps;
	unsigned int cpu = policy->cpu;
	int ret;

	cpu->perf_ctrls.desired_perf = cpu->perf_caps.lowest_perf;
	cpu_data->perf_ctrls.desired_perf = caps->lowest_perf;

	ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
	ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
	if (ret)
		pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
				cpu->perf_caps.lowest_perf, cpu_num, ret);
			 caps->lowest_perf, cpu, ret);
}

/*
 * The PCC subspace describes the rate at which platform can accept commands
 * on the shared PCC channel (including READs which do not count towards freq
 * trasition requests), so ideally we need to use the PCC values as a fallback
 * transition requests), so ideally we need to use the PCC values as a fallback
 * if we don't have a platform specific transition_delay_us
 */
#ifdef CONFIG_ARM64
#include <asm/cputype.h>

static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
{
	unsigned long implementor = read_cpuid_implementor();
	unsigned long part_num = read_cpuid_part_number();
@@ -233,7 +232,7 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)

#else

static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
{
	return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
}
@@ -241,54 +240,57 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)

static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
	struct cppc_cpudata *cpu;
	unsigned int cpu_num = policy->cpu;
	struct cppc_cpudata *cpu_data = all_cpu_data[policy->cpu];
	struct cppc_perf_caps *caps = &cpu_data->perf_caps;
	unsigned int cpu = policy->cpu;
	int ret = 0;

	cpu = all_cpu_data[policy->cpu];

	cpu->cpu = cpu_num;
	ret = cppc_get_perf_caps(policy->cpu, &cpu->perf_caps);
	cpu_data->cpu = cpu;
	ret = cppc_get_perf_caps(cpu, caps);

	if (ret) {
		pr_debug("Err reading CPU%d perf capabilities. ret:%d\n",
				cpu_num, ret);
			 cpu, ret);
		return ret;
	}

	/* Convert the lowest and nominal freq from MHz to KHz */
	cpu->perf_caps.lowest_freq *= 1000;
	cpu->perf_caps.nominal_freq *= 1000;
	caps->lowest_freq *= 1000;
	caps->nominal_freq *= 1000;

	/*
	 * Set min to lowest nonlinear perf to avoid any efficiency penalty (see
	 * Section 8.4.7.1.1.5 of ACPI 6.1 spec)
	 */
	policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf);
	policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
	policy->min = cppc_cpufreq_perf_to_khz(cpu_data,
					       caps->lowest_nonlinear_perf);
	policy->max = cppc_cpufreq_perf_to_khz(cpu_data,
					       caps->nominal_perf);

	/*
	 * Set cpuinfo.min_freq to Lowest to make the full range of performance
	 * available if userspace wants to use any perf between lowest & lowest
	 * nonlinear perf
	 */
	policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf);
	policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
	policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu_data,
							    caps->lowest_perf);
	policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu_data,
							    caps->nominal_perf);

	policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
	policy->shared_type = cpu->shared_type;
	policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
	policy->shared_type = cpu_data->shared_type;

	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
		int i;

		cpumask_copy(policy->cpus, cpu->shared_cpu_map);
		cpumask_copy(policy->cpus, cpu_data->shared_cpu_map);

		for_each_cpu(i, policy->cpus) {
			if (unlikely(i == policy->cpu))
			if (unlikely(i == cpu))
				continue;

			memcpy(&all_cpu_data[i]->perf_caps, &cpu->perf_caps,
			       sizeof(cpu->perf_caps));
			memcpy(&all_cpu_data[i]->perf_caps, caps,
			       sizeof(cpu_data->perf_caps));
		}
	} else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
		/* Support only SW_ANY for now. */
@@ -296,24 +298,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
		return -EFAULT;
	}

	cpu->cur_policy = policy;
	cpu_data->cur_policy = policy;

	/*
	 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
	 * is supported.
	 */
	if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf)
	if (caps->highest_perf > caps->nominal_perf)
		boost_supported = true;

	/* Set policy->cur to max now. The governors will adjust later. */
	policy->cur = cppc_cpufreq_perf_to_khz(cpu,
					cpu->perf_caps.highest_perf);
	cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf;
	policy->cur = cppc_cpufreq_perf_to_khz(cpu_data, caps->highest_perf);
	cpu_data->perf_ctrls.desired_perf =  caps->highest_perf;

	ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
	ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
	if (ret)
		pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
				cpu->perf_caps.highest_perf, cpu_num, ret);
			 caps->highest_perf, cpu, ret);

	return ret;
}
@@ -326,7 +327,7 @@ static inline u64 get_delta(u64 t1, u64 t0)
	return (u32)t1 - (u32)t0;
}

static int cppc_get_rate_from_fbctrs(struct cppc_cpudata *cpu,
static int cppc_get_rate_from_fbctrs(struct cppc_cpudata *cpu_data,
				     struct cppc_perf_fb_ctrs fb_ctrs_t0,
				     struct cppc_perf_fb_ctrs fb_ctrs_t1)
{
@@ -345,33 +346,34 @@ static int cppc_get_rate_from_fbctrs(struct cppc_cpudata *cpu,
		delivered_perf = (reference_perf * delta_delivered) /
					delta_reference;
	else
		delivered_perf = cpu->perf_ctrls.desired_perf;
		delivered_perf = cpu_data->perf_ctrls.desired_perf;

	return cppc_cpufreq_perf_to_khz(cpu, delivered_perf);
	return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf);
}

static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
{
	struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0};
	struct cppc_cpudata *cpu = all_cpu_data[cpunum];
	struct cppc_cpudata *cpu_data = all_cpu_data[cpu];
	int ret;

	ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t0);
	ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0);
	if (ret)
		return ret;

	udelay(2); /* 2usec delay between sampling */

	ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t1);
	ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
	if (ret)
		return ret;

	return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
	return cppc_get_rate_from_fbctrs(cpu_data, fb_ctrs_t0, fb_ctrs_t1);
}

static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
{
	struct cppc_cpudata *cpudata;
	struct cppc_cpudata *cpu_data = all_cpu_data[policy->cpu];
	struct cppc_perf_caps *caps = &cpu_data->perf_caps;
	int ret;

	if (!boost_supported) {
@@ -379,13 +381,12 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
		return -EINVAL;
	}

	cpudata = all_cpu_data[policy->cpu];
	if (state)
		policy->max = cppc_cpufreq_perf_to_khz(cpudata,
					cpudata->perf_caps.highest_perf);
		policy->max = cppc_cpufreq_perf_to_khz(cpu_data,
						       caps->highest_perf);
	else
		policy->max = cppc_cpufreq_perf_to_khz(cpudata,
					cpudata->perf_caps.nominal_perf);
		policy->max = cppc_cpufreq_perf_to_khz(cpu_data,
						       caps->nominal_perf);
	policy->cpuinfo.max_freq = policy->max;

	ret = freq_qos_update_request(policy->max_freq_req, policy->max);
@@ -412,17 +413,17 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
 * platform specific mechanism. We reuse the desired performance register to
 * store the real performance calculated by the platform.
 */
static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpunum)
static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpu)
{
	struct cppc_cpudata *cpudata = all_cpu_data[cpunum];
	struct cppc_cpudata *cpu_data = all_cpu_data[cpu];
	u64 desired_perf;
	int ret;

	ret = cppc_get_desired_perf(cpunum, &desired_perf);
	ret = cppc_get_desired_perf(cpu, &desired_perf);
	if (ret < 0)
		return -EIO;

	return cppc_cpufreq_perf_to_khz(cpudata, desired_perf);
	return cppc_cpufreq_perf_to_khz(cpu_data, desired_perf);
}

static void cppc_check_hisi_workaround(void)
@@ -450,8 +451,8 @@ static void cppc_check_hisi_workaround(void)

static int __init cppc_cpufreq_init(void)
{
	struct cppc_cpudata *cpu_data;
	int i, ret = 0;
	struct cppc_cpudata *cpu;

	if (acpi_disabled)
		return -ENODEV;
@@ -466,8 +467,8 @@ static int __init cppc_cpufreq_init(void)
		if (!all_cpu_data[i])
			goto out;

		cpu = all_cpu_data[i];
		if (!zalloc_cpumask_var(&cpu->shared_cpu_map, GFP_KERNEL))
		cpu_data = all_cpu_data[i];
		if (!zalloc_cpumask_var(&cpu_data->shared_cpu_map, GFP_KERNEL))
			goto out;
	}

@@ -487,11 +488,11 @@ static int __init cppc_cpufreq_init(void)

out:
	for_each_possible_cpu(i) {
		cpu = all_cpu_data[i];
		if (!cpu)
		cpu_data = all_cpu_data[i];
		if (!cpu_data)
			break;
		free_cpumask_var(cpu->shared_cpu_map);
		kfree(cpu);
		free_cpumask_var(cpu_data->shared_cpu_map);
		kfree(cpu_data);
	}

	kfree(all_cpu_data);
@@ -500,15 +501,15 @@ out:

static void __exit cppc_cpufreq_exit(void)
{
	struct cppc_cpudata *cpu;
	struct cppc_cpudata *cpu_data;
	int i;

	cpufreq_unregister_driver(&cppc_cpufreq_driver);

	for_each_possible_cpu(i) {
		cpu = all_cpu_data[i];
		free_cpumask_var(cpu->shared_cpu_map);
		kfree(cpu);
		cpu_data = all_cpu_data[i];
		free_cpumask_var(cpu_data->shared_cpu_map);
		kfree(cpu_data);
	}

	kfree(all_cpu_data);
+2 −0
Original line number Diff line number Diff line
@@ -119,10 +119,12 @@ static const struct of_device_id blacklist[] __initconst = {
	{ .compatible = "mediatek,mt2712", },
	{ .compatible = "mediatek,mt7622", },
	{ .compatible = "mediatek,mt7623", },
	{ .compatible = "mediatek,mt8167", },
	{ .compatible = "mediatek,mt817x", },
	{ .compatible = "mediatek,mt8173", },
	{ .compatible = "mediatek,mt8176", },
	{ .compatible = "mediatek,mt8183", },
	{ .compatible = "mediatek,mt8516", },

	{ .compatible = "nvidia,tegra20", },
	{ .compatible = "nvidia,tegra30", },
+44 −41
Original line number Diff line number Diff line
@@ -298,8 +298,10 @@ struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu)
 *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
 *********************************************************************/

/*
 * adjust_jiffies - adjust the system "loops_per_jiffy"
/**
 * adjust_jiffies - Adjust the system "loops_per_jiffy".
 * @val: CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
 * @ci: Frequency change information.
 *
 * This function alters the system "loops_per_jiffy" for the clock
 * speed change. Note that loops_per_jiffy cannot be updated on SMP
@@ -331,14 +333,14 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
}

/**
 * cpufreq_notify_transition - Notify frequency transition and adjust_jiffies.
 * cpufreq_notify_transition - Notify frequency transition and adjust jiffies.
 * @policy: cpufreq policy to enable fast frequency switching for.
 * @freqs: contain details of the frequency update.
 * @state: set to CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
 *
 * This function calls the transition notifiers and the "adjust_jiffies"
 * function. It is called twice on all CPU frequency changes that have
 * external effects.
 * This function calls the transition notifiers and adjust_jiffies().
 *
 * It is called twice on all CPU frequency changes that have external effects.
 */
static void cpufreq_notify_transition(struct cpufreq_policy *policy,
				      struct cpufreq_freqs *freqs,
@@ -1391,8 +1393,10 @@ static int cpufreq_online(unsigned int cpu)

		policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req),
					       GFP_KERNEL);
		if (!policy->min_freq_req)
		if (!policy->min_freq_req) {
			ret = -ENOMEM;
			goto out_destroy_policy;
		}

		ret = freq_qos_add_request(&policy->constraints,
					   policy->min_freq_req, FREQ_QOS_MIN,
@@ -1429,6 +1433,7 @@ static int cpufreq_online(unsigned int cpu)
	if (cpufreq_driver->get && has_target()) {
		policy->cur = cpufreq_driver->get(policy->cpu);
		if (!policy->cur) {
			ret = -EIO;
			pr_err("%s: ->get() failed\n", __func__);
			goto out_destroy_policy;
		}
@@ -1646,13 +1651,12 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
}

/**
 *	cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're
 *	in deep trouble.
 *	@policy: policy managing CPUs
 *	@new_freq: CPU frequency the CPU actually runs at
 * cpufreq_out_of_sync - Fix up actual and saved CPU frequency difference.
 * @policy: Policy managing CPUs.
 * @new_freq: New CPU frequency.
 *
 *	We adjust to current frequency first, and need to clean up later.
 *	So either call to cpufreq_update_policy() or schedule handle_update()).
 * Adjust to the current frequency first and clean up later by either calling
 * cpufreq_update_policy(), or scheduling handle_update().
 */
static void cpufreq_out_of_sync(struct cpufreq_policy *policy,
				unsigned int new_freq)
@@ -1832,7 +1836,7 @@ int cpufreq_generic_suspend(struct cpufreq_policy *policy)
EXPORT_SYMBOL(cpufreq_generic_suspend);

/**
 * cpufreq_suspend() - Suspend CPUFreq governors
 * cpufreq_suspend() - Suspend CPUFreq governors.
 *
 * Called during system wide Suspend/Hibernate cycles for suspending governors
 * as some platforms can't change frequency after this point in suspend cycle.
@@ -1868,7 +1872,7 @@ suspend:
}

/**
 * cpufreq_resume() - Resume CPUFreq governors
 * cpufreq_resume() - Resume CPUFreq governors.
 *
 * Called during system wide Suspend/Hibernate cycle for resuming governors that
 * are suspended with cpufreq_suspend().
@@ -1920,10 +1924,10 @@ bool cpufreq_driver_test_flags(u16 flags)
}

/**
 *	cpufreq_get_current_driver - return current driver's name
 * cpufreq_get_current_driver - Return the current driver's name.
 *
 *	Return the name string of the currently loaded cpufreq driver
 *	or NULL, if none.
 * Return the name string of the currently registered cpufreq driver or NULL if
 * none.
 */
const char *cpufreq_get_current_driver(void)
{
@@ -1935,10 +1939,10 @@ const char *cpufreq_get_current_driver(void)
EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);

/**
 *	cpufreq_get_driver_data - return current driver data
 * cpufreq_get_driver_data - Return current driver data.
 *
 *	Return the private data of the currently loaded cpufreq
 *	driver, or NULL if no cpufreq driver is loaded.
 * Return the private data of the currently registered cpufreq driver, or NULL
 * if no cpufreq driver has been registered.
 */
void *cpufreq_get_driver_data(void)
{
@@ -1954,17 +1958,16 @@ EXPORT_SYMBOL_GPL(cpufreq_get_driver_data);
 *********************************************************************/

/**
 *	cpufreq_register_notifier - register a driver with cpufreq
 *	@nb: notifier function to register
 *      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
 * cpufreq_register_notifier - Register a notifier with cpufreq.
 * @nb: notifier function to register.
 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER.
 *
 *	Add a driver to one of two lists: either a list of drivers that
 *      are notified about clock rate changes (once before and once after
 *      the transition), or a list of drivers that are notified about
 *      changes in cpufreq policy.
 * Add a notifier to one of two lists: either a list of notifiers that run on
 * clock rate changes (once before and once after every transition), or a list
 * of notifiers that ron on cpufreq policy changes.
 *
 *	This function may sleep, and has the same return conditions as
 *	blocking_notifier_chain_register.
 * This function may sleep and it has the same return values as
 * blocking_notifier_chain_register().
 */
int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
{
@@ -2001,14 +2004,14 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
EXPORT_SYMBOL(cpufreq_register_notifier);

/**
 *	cpufreq_unregister_notifier - unregister a driver with cpufreq
 *	@nb: notifier block to be unregistered
 *	@list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
 * cpufreq_unregister_notifier - Unregister a notifier from cpufreq.
 * @nb: notifier block to be unregistered.
 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER.
 *
 *	Remove a driver from the CPU frequency notifier list.
 * Remove a notifier from one of the cpufreq notifier lists.
 *
 *	This function may sleep, and has the same return conditions as
 *	blocking_notifier_chain_unregister.
 * This function may sleep and it has the same return values as
 * blocking_notifier_chain_unregister().
 */
int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
{
@@ -2123,7 +2126,7 @@ static int __target_intermediate(struct cpufreq_policy *policy,
static int __target_index(struct cpufreq_policy *policy, int index)
{
	struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};
	unsigned int intermediate_freq = 0;
	unsigned int restore_freq, intermediate_freq = 0;
	unsigned int newfreq = policy->freq_table[index].frequency;
	int retval = -EINVAL;
	bool notify;
@@ -2131,6 +2134,9 @@ static int __target_index(struct cpufreq_policy *policy, int index)
	if (newfreq == policy->cur)
		return 0;

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

	notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);
	if (notify) {
		/* Handle switching to intermediate frequency */
@@ -2168,7 +2174,7 @@ static int __target_index(struct cpufreq_policy *policy, int index)
		 */
		if (unlikely(retval && intermediate_freq)) {
			freqs.old = intermediate_freq;
			freqs.new = policy->restore_freq;
			freqs.new = restore_freq;
			cpufreq_freq_transition_begin(policy, &freqs);
			cpufreq_freq_transition_end(policy, &freqs, 0);
		}
@@ -2203,9 +2209,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
	    !(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS))
		return 0;

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

	if (cpufreq_driver->target)
		return cpufreq_driver->target(policy, target_freq, relation);

Loading