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

Merge branches 'pm-cpufreq' and 'pm-acpi'

* pm-cpufreq:
  cpufreq: CPPC: add SW BOOST support
  cpufreq: change '.set_boost' to act on one policy
  cpufreq: tegra186: add CPUFREQ_NEED_INITIAL_FREQ_CHECK flag

* pm-acpi:
  ACPI: PM: Avoid using power resources if there are none for D0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
		 * possibly drop references to the power resources in use.
		 */
		state = ACPI_STATE_D3_HOT;
		/* If _PR3 is not available, use D3hot as the target state. */
		/* If D3cold is not supported, use D3hot as the target state. */
		if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
			target_state = state;
	} else if (!device->power.states[state].flags.valid) {
+19 −9
Original line number Diff line number Diff line
@@ -919,12 +919,9 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)

		if (buffer.length && package
		    && package->type == ACPI_TYPE_PACKAGE
		    && package->package.count) {
			int err = acpi_extract_power_resources(package, 0,
							       &ps->resources);
			if (!err)
				device->power.flags.power_resources = 1;
		}
		    && package->package.count)
			acpi_extract_power_resources(package, 0, &ps->resources);

		ACPI_FREE(buffer.pointer);
	}

@@ -971,14 +968,27 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
		acpi_bus_init_power_state(device, i);

	INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources);
	if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
		device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;

	/* Set defaults for D0 and D3hot states (always valid) */
	/* Set the defaults for D0 and D3hot (always supported). */
	device->power.states[ACPI_STATE_D0].flags.valid = 1;
	device->power.states[ACPI_STATE_D0].power = 100;
	device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1;

	/*
	 * Use power resources only if the D0 list of them is populated, because
	 * some platforms may provide _PR3 only to indicate D3cold support and
	 * in those cases the power resources list returned by it may be bogus.
	 */
	if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) {
		device->power.flags.power_resources = 1;
		/*
		 * D3cold is supported if the D3hot list of power resources is
		 * not empty.
		 */
		if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
			device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
	}

	if (acpi_bus_init_power(device))
		device->flags.power_manageable = 0;
}
+8 −6
Original line number Diff line number Diff line
@@ -126,12 +126,12 @@ static void boost_set_msr_each(void *p_en)
	boost_set_msr(enable);
}

static int set_boost(int val)
static int set_boost(struct cpufreq_policy *policy, int val)
{
	get_online_cpus();
	on_each_cpu(boost_set_msr_each, (void *)(long)val, 1);
	put_online_cpus();
	pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
	on_each_cpu_mask(policy->cpus, boost_set_msr_each,
			 (void *)(long)val, 1);
	pr_debug("CPU %*pbl: Core Boosting %sabled.\n",
		 cpumask_pr_args(policy->cpus), val ? "en" : "dis");

	return 0;
}
@@ -162,7 +162,9 @@ static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
	if (ret || val > 1)
		return -EINVAL;

	set_boost(val);
	get_online_cpus();
	set_boost(policy, val);
	put_online_cpus();

	return count;
}
+37 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
 * requested etc.
 */
static struct cppc_cpudata **all_cpu_data;
static bool boost_supported;

struct cppc_workaround_oem_info {
	char oem_id[ACPI_OEM_ID_SIZE + 1];
@@ -310,7 +311,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
	 * 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.highest_perf);
	policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);

	/*
	 * Set cpuinfo.min_freq to Lowest to make the full range of performance
@@ -318,7 +319,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
	 * 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.highest_perf);
	policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);

	policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
	policy->shared_type = cpu->shared_type;
@@ -343,6 +344,13 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)

	cpu->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)
		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);
@@ -410,6 +418,32 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
	return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
}

static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
{
	struct cppc_cpudata *cpudata;
	int ret;

	if (!boost_supported) {
		pr_err("BOOST not supported by CPU or firmware\n");
		return -EINVAL;
	}

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

	ret = freq_qos_update_request(policy->max_freq_req, policy->max);
	if (ret < 0)
		return ret;

	return 0;
}

static struct cpufreq_driver cppc_cpufreq_driver = {
	.flags = CPUFREQ_CONST_LOOPS,
	.verify = cppc_verify_policy,
@@ -417,6 +451,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
	.get = cppc_cpufreq_get_rate,
	.init = cppc_cpufreq_cpu_init,
	.stop_cpu = cppc_cpufreq_stop_cpu,
	.set_boost = cppc_cpufreq_set_boost,
	.name = "cppc_cpufreq",
};

+31 −26
Original line number Diff line number Diff line
@@ -2532,34 +2532,29 @@ EXPORT_SYMBOL_GPL(cpufreq_update_limits);
/*********************************************************************
 *               BOOST						     *
 *********************************************************************/
static int cpufreq_boost_set_sw(int state)
static int cpufreq_boost_set_sw(struct cpufreq_policy *policy, int state)
{
	struct cpufreq_policy *policy;

	for_each_active_policy(policy) {
	int ret;

	if (!policy->freq_table)
		return -ENXIO;

		ret = cpufreq_frequency_table_cpuinfo(policy,
						      policy->freq_table);
	ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);
	if (ret) {
			pr_err("%s: Policy frequency update failed\n",
			       __func__);
		pr_err("%s: Policy frequency update failed\n", __func__);
		return ret;
	}

	ret = freq_qos_update_request(policy->max_freq_req, policy->max);
	if (ret < 0)
		return ret;
	}

	return 0;
}

int cpufreq_boost_trigger_state(int state)
{
	struct cpufreq_policy *policy;
	unsigned long flags;
	int ret = 0;

@@ -2570,15 +2565,25 @@ int cpufreq_boost_trigger_state(int state)
	cpufreq_driver->boost_enabled = state;
	write_unlock_irqrestore(&cpufreq_driver_lock, flags);

	ret = cpufreq_driver->set_boost(state);
	if (ret) {
	get_online_cpus();
	for_each_active_policy(policy) {
		ret = cpufreq_driver->set_boost(policy, state);
		if (ret)
			goto err_reset_state;
	}
	put_online_cpus();

	return 0;

err_reset_state:
	put_online_cpus();

	write_lock_irqsave(&cpufreq_driver_lock, flags);
	cpufreq_driver->boost_enabled = !state;
	write_unlock_irqrestore(&cpufreq_driver_lock, flags);

	pr_err("%s: Cannot %s BOOST\n",
	       __func__, state ? "enable" : "disable");
	}

	return ret;
}
Loading