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

Merge branch 'pm-cpufreq'

* pm-cpufreq:
  cpufreq: Make cpufreq_notify_transition & cpufreq_notify_post_transition static
  cpufreq: Convert existing drivers to use cpufreq_freq_transition_{begin|end}
  cpufreq: Make sure frequency transitions are serialized
  intel_pstate: Use del_timer_sync in intel_pstate_cpu_stop
  cpufreq: resume drivers before enabling governors
parents f01a5865 236a9800
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -270,7 +270,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
	pr_debug("Old CPU frequency %d kHz, new %d kHz\n",
	pr_debug("Old CPU frequency %d kHz, new %d kHz\n",
	       freqs.old, freqs.new);
	       freqs.old, freqs.new);


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	cpufreq_freq_transition_begin(policy, &freqs);


	/* Disable IRQs */
	/* Disable IRQs */
	/* local_irq_save(flags); */
	/* local_irq_save(flags); */
@@ -285,7 +285,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
	/* Enable IRQs */
	/* Enable IRQs */
	/* local_irq_restore(flags); */
	/* local_irq_restore(flags); */


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
	cpufreq_freq_transition_end(policy, &freqs, 0);


	return 0;
	return 0;
}
}
+47 −14
Original line number Original line Diff line number Diff line
@@ -331,16 +331,15 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
 * function. It is called twice on all CPU frequency changes that have
 * function. It is called twice on all CPU frequency changes that have
 * external effects.
 * external effects.
 */
 */
void cpufreq_notify_transition(struct cpufreq_policy *policy,
static void cpufreq_notify_transition(struct cpufreq_policy *policy,
		struct cpufreq_freqs *freqs, unsigned int state)
		struct cpufreq_freqs *freqs, unsigned int state)
{
{
	for_each_cpu(freqs->cpu, policy->cpus)
	for_each_cpu(freqs->cpu, policy->cpus)
		__cpufreq_notify_transition(policy, freqs, state);
		__cpufreq_notify_transition(policy, freqs, state);
}
}
EXPORT_SYMBOL_GPL(cpufreq_notify_transition);


/* Do post notifications when there are chances that transition has failed */
/* Do post notifications when there are chances that transition has failed */
void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
		struct cpufreq_freqs *freqs, int transition_failed)
		struct cpufreq_freqs *freqs, int transition_failed)
{
{
	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
@@ -351,7 +350,41 @@ void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
}
}
EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);

void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
		struct cpufreq_freqs *freqs)
{
wait:
	wait_event(policy->transition_wait, !policy->transition_ongoing);

	spin_lock(&policy->transition_lock);

	if (unlikely(policy->transition_ongoing)) {
		spin_unlock(&policy->transition_lock);
		goto wait;
	}

	policy->transition_ongoing = true;

	spin_unlock(&policy->transition_lock);

	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
}
EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);

void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
		struct cpufreq_freqs *freqs, int transition_failed)
{
	if (unlikely(WARN_ON(!policy->transition_ongoing)))
		return;

	cpufreq_notify_post_transition(policy, freqs, transition_failed);

	policy->transition_ongoing = false;

	wake_up(&policy->transition_wait);
}
EXPORT_SYMBOL_GPL(cpufreq_freq_transition_end);




/*********************************************************************
/*********************************************************************
@@ -985,6 +1018,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)


	INIT_LIST_HEAD(&policy->policy_list);
	INIT_LIST_HEAD(&policy->policy_list);
	init_rwsem(&policy->rwsem);
	init_rwsem(&policy->rwsem);
	spin_lock_init(&policy->transition_lock);
	init_waitqueue_head(&policy->transition_wait);


	return policy;
	return policy;


@@ -1470,8 +1505,8 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
	policy = per_cpu(cpufreq_cpu_data, cpu);
	policy = per_cpu(cpufreq_cpu_data, cpu);
	read_unlock_irqrestore(&cpufreq_driver_lock, flags);
	read_unlock_irqrestore(&cpufreq_driver_lock, flags);


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	cpufreq_freq_transition_begin(policy, &freqs);
	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
	cpufreq_freq_transition_end(policy, &freqs, 0);
}
}


/**
/**
@@ -1652,14 +1687,13 @@ void cpufreq_resume(void)
	cpufreq_suspended = false;
	cpufreq_suspended = false;


	list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
	list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
		if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
		if (cpufreq_driver->resume && cpufreq_driver->resume(policy))
			pr_err("%s: Failed to resume driver: %p\n", __func__,
				policy);
		else if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
		    || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
		    || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
			pr_err("%s: Failed to start governor for policy: %p\n",
			pr_err("%s: Failed to start governor for policy: %p\n",
				__func__, policy);
				__func__, policy);
		else if (cpufreq_driver->resume
		    && cpufreq_driver->resume(policy))
			pr_err("%s: Failed to resume driver: %p\n", __func__,
				policy);


		/*
		/*
		 * schedule call cpufreq_update_policy() for boot CPU, i.e. last
		 * schedule call cpufreq_update_policy() for boot CPU, i.e. last
@@ -1832,8 +1866,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
			pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
			pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
				 __func__, policy->cpu, freqs.old, freqs.new);
				 __func__, policy->cpu, freqs.old, freqs.new);


			cpufreq_notify_transition(policy, &freqs,
			cpufreq_freq_transition_begin(policy, &freqs);
					CPUFREQ_PRECHANGE);
		}
		}


		retval = cpufreq_driver->target_index(policy, index);
		retval = cpufreq_driver->target_index(policy, index);
@@ -1842,7 +1875,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
			       __func__, retval);
			       __func__, retval);


		if (notify)
		if (notify)
			cpufreq_notify_post_transition(policy, &freqs, retval);
			cpufreq_freq_transition_end(policy, &freqs, retval);
	}
	}


out:
out:
+2 −2
Original line number Original line Diff line number Diff line
@@ -219,7 +219,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
	freqs.old = policy->cur;
	freqs.old = policy->cur;
	freqs.new = freq_table[index].frequency;
	freqs.new = freq_table[index].frequency;


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	cpufreq_freq_transition_begin(policy, &freqs);


	/* Set the target frequency in all C0_3_PSTATE register */
	/* Set the target frequency in all C0_3_PSTATE register */
	for_each_cpu(i, policy->cpus) {
	for_each_cpu(i, policy->cpus) {
@@ -258,7 +258,7 @@ static void exynos_cpufreq_work(struct work_struct *work)
		dev_crit(dvfs_info->dev, "New frequency out of range\n");
		dev_crit(dvfs_info->dev, "New frequency out of range\n");
		freqs.new = freqs.old;
		freqs.new = freqs.old;
	}
	}
	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
	cpufreq_freq_transition_end(policy, &freqs, 0);


	cpufreq_cpu_put(policy);
	cpufreq_cpu_put(policy);
	mutex_unlock(&cpufreq_lock);
	mutex_unlock(&cpufreq_lock);
+2 −2
Original line number Original line Diff line number Diff line
@@ -265,7 +265,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)


	freqs.new = new_khz;
	freqs.new = new_khz;


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	cpufreq_freq_transition_begin(policy, &freqs);
	local_irq_save(flags);
	local_irq_save(flags);


	if (new_khz != stock_freq) {
	if (new_khz != stock_freq) {
@@ -314,7 +314,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)


	gx_params->pci_suscfg = suscfg;
	gx_params->pci_suscfg = suscfg;


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
	cpufreq_freq_transition_end(policy, &freqs, 0);


	pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
	pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
		gx_params->on_duration * 32, gx_params->off_duration * 32);
		gx_params->on_duration * 32, gx_params->off_duration * 32);
+2 −2
Original line number Original line Diff line number Diff line
@@ -122,7 +122,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
		return 0;
		return 0;
	}
	}


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
	cpufreq_freq_transition_begin(policy, &freqs);


	cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
	cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);


@@ -143,7 +143,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
	 */
	 */
	set_cpus_allowed(current, cpus_allowed);
	set_cpus_allowed(current, cpus_allowed);


	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
	cpufreq_freq_transition_end(policy, &freqs, 0);


	return 0;
	return 0;
}
}
Loading