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

Merge back earlier 'pm-cpufreq' material.

parents e66c1768 1c0ca902
Loading
Loading
Loading
Loading
+44 −56
Original line number Original line Diff line number Diff line
@@ -2017,22 +2017,21 @@ EXPORT_SYMBOL(cpufreq_get_policy);
static int cpufreq_set_policy(struct cpufreq_policy *policy,
static int cpufreq_set_policy(struct cpufreq_policy *policy,
				struct cpufreq_policy *new_policy)
				struct cpufreq_policy *new_policy)
{
{
	int ret = 0, failed = 1;
	struct cpufreq_governor *old_gov;
	int ret;


	pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
	pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
		new_policy->min, new_policy->max);
		new_policy->min, new_policy->max);


	memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
	memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));


	if (new_policy->min > policy->max || new_policy->max < policy->min) {
	if (new_policy->min > policy->max || new_policy->max < policy->min)
		ret = -EINVAL;
		return -EINVAL;
		goto error_out;
	}


	/* verify the cpu speed can be set within this limit */
	/* verify the cpu speed can be set within this limit */
	ret = cpufreq_driver->verify(new_policy);
	ret = cpufreq_driver->verify(new_policy);
	if (ret)
	if (ret)
		goto error_out;
		return ret;


	/* adjust if necessary - all reasons */
	/* adjust if necessary - all reasons */
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
@@ -2048,7 +2047,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
	 */
	 */
	ret = cpufreq_driver->verify(new_policy);
	ret = cpufreq_driver->verify(new_policy);
	if (ret)
	if (ret)
		goto error_out;
		return ret;


	/* notification of the new policy */
	/* notification of the new policy */
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
@@ -2063,58 +2062,48 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
	if (cpufreq_driver->setpolicy) {
	if (cpufreq_driver->setpolicy) {
		policy->policy = new_policy->policy;
		policy->policy = new_policy->policy;
		pr_debug("setting range\n");
		pr_debug("setting range\n");
		ret = cpufreq_driver->setpolicy(new_policy);
		return cpufreq_driver->setpolicy(new_policy);
	} else {
	}
		if (new_policy->governor != policy->governor) {

			/* save old, working values */
	if (new_policy->governor == policy->governor)
			struct cpufreq_governor *old_gov = policy->governor;
		goto out;


	pr_debug("governor switch\n");
	pr_debug("governor switch\n");


	/* save old, working values */
	old_gov = policy->governor;
	/* end old governor */
	/* end old governor */
			if (policy->governor) {
	if (old_gov) {
		__cpufreq_governor(policy, CPUFREQ_GOV_STOP);
		__cpufreq_governor(policy, CPUFREQ_GOV_STOP);
		up_write(&policy->rwsem);
		up_write(&policy->rwsem);
				__cpufreq_governor(policy,
		__cpufreq_governor(policy,CPUFREQ_GOV_POLICY_EXIT);
						CPUFREQ_GOV_POLICY_EXIT);
		down_write(&policy->rwsem);
		down_write(&policy->rwsem);
	}
	}


	/* start new governor */
	/* start new governor */
	policy->governor = new_policy->governor;
	policy->governor = new_policy->governor;
	if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
	if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
				if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
		if (!__cpufreq_governor(policy, CPUFREQ_GOV_START))
					failed = 0;
			goto out;
				} else {

		up_write(&policy->rwsem);
		up_write(&policy->rwsem);
					__cpufreq_governor(policy,
		__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
							CPUFREQ_GOV_POLICY_EXIT);
		down_write(&policy->rwsem);
		down_write(&policy->rwsem);
	}
	}
			}


			if (failed) {
	/* new governor failed, so re-start old one */
	/* new governor failed, so re-start old one */
				pr_debug("starting governor %s failed\n",
	pr_debug("starting governor %s failed\n", policy->governor->name);
							policy->governor->name);
	if (old_gov) {
	if (old_gov) {
		policy->governor = old_gov;
		policy->governor = old_gov;
					__cpufreq_governor(policy,
		__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT);
							CPUFREQ_GOV_POLICY_INIT);
		__cpufreq_governor(policy, CPUFREQ_GOV_START);
					__cpufreq_governor(policy,
							   CPUFREQ_GOV_START);
				}
				ret = -EINVAL;
				goto error_out;
			}
			/* might be a policy change, too, so fall through */
		}
		pr_debug("governor: change or update limits\n");
		ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
	}
	}


error_out:
	return -EINVAL;
	return ret;

 out:
	pr_debug("governor: change or update limits\n");
	return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
}
}


/**
/**
@@ -2186,7 +2175,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb,
		switch (action & ~CPU_TASKS_FROZEN) {
		switch (action & ~CPU_TASKS_FROZEN) {
		case CPU_ONLINE:
		case CPU_ONLINE:
			__cpufreq_add_dev(dev, NULL, frozen);
			__cpufreq_add_dev(dev, NULL, frozen);
			cpufreq_update_policy(cpu);
			break;
			break;


		case CPU_DOWN_PREPARE:
		case CPU_DOWN_PREPARE: