Skip to content

Commit 50dd154

Browse files
committed
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
3 parents 4c277e2 + 54e74df + 956ad9d commit 50dd154

File tree

7 files changed

+99
-46
lines changed

7 files changed

+99
-46
lines changed

drivers/acpi/device_pm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
186186
* possibly drop references to the power resources in use.
187187
*/
188188
state = ACPI_STATE_D3_HOT;
189-
/* If _PR3 is not available, use D3hot as the target state. */
189+
/* If D3cold is not supported, use D3hot as the target state. */
190190
if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
191191
target_state = state;
192192
} else if (!device->power.states[state].flags.valid) {

drivers/acpi/scan.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -919,12 +919,9 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
919919

920920
if (buffer.length && package
921921
&& package->type == ACPI_TYPE_PACKAGE
922-
&& package->package.count) {
923-
int err = acpi_extract_power_resources(package, 0,
924-
&ps->resources);
925-
if (!err)
926-
device->power.flags.power_resources = 1;
927-
}
922+
&& package->package.count)
923+
acpi_extract_power_resources(package, 0, &ps->resources);
924+
928925
ACPI_FREE(buffer.pointer);
929926
}
930927

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

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

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

977+
/*
978+
* Use power resources only if the D0 list of them is populated, because
979+
* some platforms may provide _PR3 only to indicate D3cold support and
980+
* in those cases the power resources list returned by it may be bogus.
981+
*/
982+
if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) {
983+
device->power.flags.power_resources = 1;
984+
/*
985+
* D3cold is supported if the D3hot list of power resources is
986+
* not empty.
987+
*/
988+
if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
989+
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
990+
}
991+
982992
if (acpi_bus_init_power(device))
983993
device->flags.power_manageable = 0;
984994
}

drivers/cpufreq/acpi-cpufreq.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ static void boost_set_msr_each(void *p_en)
126126
boost_set_msr(enable);
127127
}
128128

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

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

165-
set_boost(val);
165+
get_online_cpus();
166+
set_boost(policy, val);
167+
put_online_cpus();
166168

167169
return count;
168170
}

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* requested etc.
3838
*/
3939
static struct cppc_cpudata **all_cpu_data;
40+
static bool boost_supported;
4041

4142
struct cppc_workaround_oem_info {
4243
char oem_id[ACPI_OEM_ID_SIZE + 1];
@@ -310,15 +311,15 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
310311
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
311312
*/
312313
policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf);
313-
policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
314+
policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
314315

315316
/*
316317
* Set cpuinfo.min_freq to Lowest to make the full range of performance
317318
* available if userspace wants to use any perf between lowest & lowest
318319
* nonlinear perf
319320
*/
320321
policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf);
321-
policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
322+
policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
322323

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

344345
cpu->cur_policy = policy;
345346

347+
/*
348+
* If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
349+
* is supported.
350+
*/
351+
if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf)
352+
boost_supported = true;
353+
346354
/* Set policy->cur to max now. The governors will adjust later. */
347355
policy->cur = cppc_cpufreq_perf_to_khz(cpu,
348356
cpu->perf_caps.highest_perf);
@@ -410,13 +418,40 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
410418
return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
411419
}
412420

421+
static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
422+
{
423+
struct cppc_cpudata *cpudata;
424+
int ret;
425+
426+
if (!boost_supported) {
427+
pr_err("BOOST not supported by CPU or firmware\n");
428+
return -EINVAL;
429+
}
430+
431+
cpudata = all_cpu_data[policy->cpu];
432+
if (state)
433+
policy->max = cppc_cpufreq_perf_to_khz(cpudata,
434+
cpudata->perf_caps.highest_perf);
435+
else
436+
policy->max = cppc_cpufreq_perf_to_khz(cpudata,
437+
cpudata->perf_caps.nominal_perf);
438+
policy->cpuinfo.max_freq = policy->max;
439+
440+
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
441+
if (ret < 0)
442+
return ret;
443+
444+
return 0;
445+
}
446+
413447
static struct cpufreq_driver cppc_cpufreq_driver = {
414448
.flags = CPUFREQ_CONST_LOOPS,
415449
.verify = cppc_verify_policy,
416450
.target = cppc_cpufreq_set_target,
417451
.get = cppc_cpufreq_get_rate,
418452
.init = cppc_cpufreq_cpu_init,
419453
.stop_cpu = cppc_cpufreq_stop_cpu,
454+
.set_boost = cppc_cpufreq_set_boost,
420455
.name = "cppc_cpufreq",
421456
};
422457

drivers/cpufreq/cpufreq.c

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,34 +2532,29 @@ EXPORT_SYMBOL_GPL(cpufreq_update_limits);
25322532
/*********************************************************************
25332533
* BOOST *
25342534
*********************************************************************/
2535-
static int cpufreq_boost_set_sw(int state)
2535+
static int cpufreq_boost_set_sw(struct cpufreq_policy *policy, int state)
25362536
{
2537-
struct cpufreq_policy *policy;
2538-
2539-
for_each_active_policy(policy) {
2540-
int ret;
2537+
int ret;
25412538

2542-
if (!policy->freq_table)
2543-
return -ENXIO;
2539+
if (!policy->freq_table)
2540+
return -ENXIO;
25442541

2545-
ret = cpufreq_frequency_table_cpuinfo(policy,
2546-
policy->freq_table);
2547-
if (ret) {
2548-
pr_err("%s: Policy frequency update failed\n",
2549-
__func__);
2550-
return ret;
2551-
}
2552-
2553-
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
2554-
if (ret < 0)
2555-
return ret;
2542+
ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);
2543+
if (ret) {
2544+
pr_err("%s: Policy frequency update failed\n", __func__);
2545+
return ret;
25562546
}
25572547

2548+
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
2549+
if (ret < 0)
2550+
return ret;
2551+
25582552
return 0;
25592553
}
25602554

25612555
int cpufreq_boost_trigger_state(int state)
25622556
{
2557+
struct cpufreq_policy *policy;
25632558
unsigned long flags;
25642559
int ret = 0;
25652560

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

2573-
ret = cpufreq_driver->set_boost(state);
2574-
if (ret) {
2575-
write_lock_irqsave(&cpufreq_driver_lock, flags);
2576-
cpufreq_driver->boost_enabled = !state;
2577-
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2578-
2579-
pr_err("%s: Cannot %s BOOST\n",
2580-
__func__, state ? "enable" : "disable");
2568+
get_online_cpus();
2569+
for_each_active_policy(policy) {
2570+
ret = cpufreq_driver->set_boost(policy, state);
2571+
if (ret)
2572+
goto err_reset_state;
25812573
}
2574+
put_online_cpus();
2575+
2576+
return 0;
2577+
2578+
err_reset_state:
2579+
put_online_cpus();
2580+
2581+
write_lock_irqsave(&cpufreq_driver_lock, flags);
2582+
cpufreq_driver->boost_enabled = !state;
2583+
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2584+
2585+
pr_err("%s: Cannot %s BOOST\n",
2586+
__func__, state ? "enable" : "disable");
25822587

25832588
return ret;
25842589
}

drivers/cpufreq/tegra186-cpufreq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
9393

9494
static struct cpufreq_driver tegra186_cpufreq_driver = {
9595
.name = "tegra186",
96-
.flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
96+
.flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
97+
CPUFREQ_NEED_INITIAL_FREQ_CHECK,
9798
.verify = cpufreq_generic_frequency_table_verify,
9899
.target_index = tegra186_cpufreq_set_target,
99100
.init = tegra186_cpufreq_init,

include/linux/cpufreq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ struct cpufreq_driver {
367367

368368
/* platform specific boost support code */
369369
bool boost_enabled;
370-
int (*set_boost)(int state);
370+
int (*set_boost)(struct cpufreq_policy *policy, int state);
371371
};
372372

373373
/* flags */

0 commit comments

Comments
 (0)