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

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

Merge branch 'pm-cpufreq'

* pm-cpufreq:
  cpufreq: Acquire the lock in cpufreq_policy_restore() for reading
  cpufreq: Prevent problems in update_policy_cpu() if last_cpu == new_cpu
  cpufreq: Restructure if/else block to avoid unintended behavior
  cpufreq: Fix crash in cpufreq-stats during suspend/resume
parents 0df03a30 44871c9c
Loading
Loading
Loading
Loading
+32 −17
Original line number Diff line number Diff line
@@ -906,11 +906,11 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
	struct cpufreq_policy *policy;
	unsigned long flags;

	write_lock_irqsave(&cpufreq_driver_lock, flags);
	read_lock_irqsave(&cpufreq_driver_lock, flags);

	policy = per_cpu(cpufreq_cpu_data_fallback, cpu);

	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
	read_unlock_irqrestore(&cpufreq_driver_lock, flags);

	return policy;
}
@@ -947,6 +947,21 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
	kfree(policy);
}

static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
{
	if (cpu == policy->cpu)
		return;

	policy->last_cpu = policy->cpu;
	policy->cpu = cpu;

#ifdef CONFIG_CPU_FREQ_TABLE
	cpufreq_frequency_table_update_policy_cpu(policy);
#endif
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
			CPUFREQ_UPDATE_POLICY_CPU, policy);
}

static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
			     bool frozen)
{
@@ -1000,7 +1015,18 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
	if (!policy)
		goto nomem_out;


	/*
	 * In the resume path, since we restore a saved policy, the assignment
	 * to policy->cpu is like an update of the existing policy, rather than
	 * the creation of a brand new one. So we need to perform this update
	 * by invoking update_policy_cpu().
	 */
	if (frozen && cpu != policy->cpu)
		update_policy_cpu(policy, cpu);
	else
		policy->cpu = cpu;

	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
	cpumask_copy(policy->cpus, cpumask_of(cpu));

@@ -1092,18 +1118,6 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
	return __cpufreq_add_dev(dev, sif, false);
}

static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
{
	policy->last_cpu = policy->cpu;
	policy->cpu = cpu;

#ifdef CONFIG_CPU_FREQ_TABLE
	cpufreq_frequency_table_update_policy_cpu(policy);
#endif
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
			CPUFREQ_UPDATE_POLICY_CPU, policy);
}

static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
					   unsigned int old_cpu, bool frozen)
{
@@ -1182,7 +1196,8 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
		cpumask_clear_cpu(cpu, policy->cpus);
	unlock_policy_rwsem_write(cpu);

	if (cpu != policy->cpu && !frozen) {
	if (cpu != policy->cpu) {
		if (!frozen)
			sysfs_remove_link(&dev->kobj, "cpufreq");
	} else if (cpus > 1) {