Skip to content

Commit 01ec716

Browse files
committed
Merge tag 'pm+acpi-4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI fixes from Rafael Wysocki: "Fixes for problems introduced or discovered recently (intel_pstate, sti-cpufreq, ARM64 cpuidle, Operating Performance Points framework, generic device properties framework) and one fix for a hotplug-related deadlock in ACPICA that's been there forever, but is nasty enough. Specifics: - Fix for a recent regression in the intel_pstate driver causing it to fail to restore the HWP (HW-managed P-states) configuration of the boot CPU after suspend-to-RAM (Rafael Wysocki). - Fix for two recent regressions in the intel_pstate driver, one that can trigger a divide by zero if the driver is accessed via sysfs before it manages to take the first sample and one causing it to fail to update a structure field used in a trace point, so the information coming from it is less useful (Rafael Wysocki). - Fix for a problem in the sti-cpufreq driver introduced during the 4.5 cycle that causes it to break CPU PM in multi-platform kernels by registering cpufreq-dt (which subsequently doesn't work) unconditionally and preventing the driver that would actually work from registering (Sudeep Holla). - Stable-candidate fix for an ARM64 cpuidle issue causing idle state usage counters to be incorrectly updated for idle states that were not entered due to errors (James Morse). - Fix for a recently introduced issue in the OPP (Operating Performance Points) framework causing it to print bogus error messages for missing optional regulators (Viresh Kumar). - Fix for a recently introduced issue in the generic device properties framework that may cause it to attempt to dereferece and invalid pointer in some cases (Heikki Krogerus). - Fix for a deadlock in the ACPICA core that may be triggered by device (eg Thunderbolt) hotplug (Prarit Bhargava)" * tag 'pm+acpi-4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PM / OPP: Remove useless check ACPICA: Dispatcher: Update thread ID for recursive method calls intel_pstate: Fix intel_pstate_get() cpufreq: intel_pstate: Fix HWP on boot CPU after system resume cpufreq: st: enable selective initialization based on the platform ARM: cpuidle: Pass on arm_cpuidle_suspend()'s return value device property: Avoid potential dereferences of invalid pointers
2 parents 17d25a3 + 5f2f88e commit 01ec716

File tree

9 files changed

+45
-27
lines changed

9 files changed

+45
-27
lines changed

drivers/acpi/acpica/dsmethod.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
428428
obj_desc->method.mutex->mutex.
429429
original_sync_level =
430430
obj_desc->method.mutex->mutex.sync_level;
431+
432+
obj_desc->method.mutex->mutex.thread_id =
433+
acpi_os_get_thread_id();
431434
}
432435
}
433436

drivers/base/power/opp/core.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,6 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
259259
reg = opp_table->regulator;
260260
if (IS_ERR(reg)) {
261261
/* Regulator may not be required for device */
262-
if (reg)
263-
dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__,
264-
PTR_ERR(reg));
265262
rcu_read_unlock();
266263
return 0;
267264
}

drivers/base/property.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
static inline bool is_pset_node(struct fwnode_handle *fwnode)
2323
{
24-
return fwnode && fwnode->type == FWNODE_PDATA;
24+
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA;
2525
}
2626

2727
static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)

drivers/cpufreq/cpufreq.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,21 +1557,25 @@ void cpufreq_suspend(void)
15571557
if (!cpufreq_driver)
15581558
return;
15591559

1560-
if (!has_target())
1560+
if (!has_target() && !cpufreq_driver->suspend)
15611561
goto suspend;
15621562

15631563
pr_debug("%s: Suspending Governors\n", __func__);
15641564

15651565
for_each_active_policy(policy) {
1566-
down_write(&policy->rwsem);
1567-
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1568-
up_write(&policy->rwsem);
1566+
if (has_target()) {
1567+
down_write(&policy->rwsem);
1568+
ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1569+
up_write(&policy->rwsem);
15691570

1570-
if (ret)
1571-
pr_err("%s: Failed to stop governor for policy: %p\n",
1572-
__func__, policy);
1573-
else if (cpufreq_driver->suspend
1574-
&& cpufreq_driver->suspend(policy))
1571+
if (ret) {
1572+
pr_err("%s: Failed to stop governor for policy: %p\n",
1573+
__func__, policy);
1574+
continue;
1575+
}
1576+
}
1577+
1578+
if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
15751579
pr_err("%s: Failed to suspend driver: %p\n", __func__,
15761580
policy);
15771581
}
@@ -1596,7 +1600,7 @@ void cpufreq_resume(void)
15961600

15971601
cpufreq_suspended = false;
15981602

1599-
if (!has_target())
1603+
if (!has_target() && !cpufreq_driver->resume)
16001604
return;
16011605

16021606
pr_debug("%s: Resuming Governors\n", __func__);
@@ -1605,7 +1609,7 @@ void cpufreq_resume(void)
16051609
if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) {
16061610
pr_err("%s: Failed to resume driver: %p\n", __func__,
16071611
policy);
1608-
} else {
1612+
} else if (has_target()) {
16091613
down_write(&policy->rwsem);
16101614
ret = cpufreq_start_governor(policy);
16111615
up_write(&policy->rwsem);

drivers/cpufreq/intel_pstate.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
453453
}
454454
}
455455

456+
static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy)
457+
{
458+
if (hwp_active)
459+
intel_pstate_hwp_set(policy->cpus);
460+
461+
return 0;
462+
}
463+
456464
static void intel_pstate_hwp_set_online_cpus(void)
457465
{
458466
get_online_cpus();
@@ -1062,8 +1070,9 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
10621070

10631071
static inline int32_t get_avg_frequency(struct cpudata *cpu)
10641072
{
1065-
return div64_u64(cpu->pstate.max_pstate_physical * cpu->sample.aperf *
1066-
cpu->pstate.scaling, cpu->sample.mperf);
1073+
return fp_toint(mul_fp(cpu->sample.core_pct_busy,
1074+
int_tofp(cpu->pstate.max_pstate_physical *
1075+
cpu->pstate.scaling / 100)));
10671076
}
10681077

10691078
static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
@@ -1106,8 +1115,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
11061115
int32_t core_busy, max_pstate, current_pstate, sample_ratio;
11071116
u64 duration_ns;
11081117

1109-
intel_pstate_calc_busy(cpu);
1110-
11111118
/*
11121119
* core_busy is the ratio of actual performance to max
11131120
* max_pstate is the max non turbo pstate available
@@ -1191,8 +1198,11 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time,
11911198
if ((s64)delta_ns >= pid_params.sample_rate_ns) {
11921199
bool sample_taken = intel_pstate_sample(cpu, time);
11931200

1194-
if (sample_taken && !hwp_active)
1195-
intel_pstate_adjust_busy_pstate(cpu);
1201+
if (sample_taken) {
1202+
intel_pstate_calc_busy(cpu);
1203+
if (!hwp_active)
1204+
intel_pstate_adjust_busy_pstate(cpu);
1205+
}
11961206
}
11971207
}
11981208

@@ -1346,8 +1356,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
13461356
out:
13471357
intel_pstate_set_update_util_hook(policy->cpu);
13481358

1349-
if (hwp_active)
1350-
intel_pstate_hwp_set(policy->cpus);
1359+
intel_pstate_hwp_set_policy(policy);
13511360

13521361
return 0;
13531362
}
@@ -1411,6 +1420,7 @@ static struct cpufreq_driver intel_pstate_driver = {
14111420
.flags = CPUFREQ_CONST_LOOPS,
14121421
.verify = intel_pstate_verify_policy,
14131422
.setpolicy = intel_pstate_set_policy,
1423+
.resume = intel_pstate_hwp_set_policy,
14141424
.get = intel_pstate_get,
14151425
.init = intel_pstate_cpu_init,
14161426
.stop_cpu = intel_pstate_stop_cpu,

drivers/cpufreq/sti-cpufreq.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ static int sti_cpufreq_init(void)
259259
{
260260
int ret;
261261

262+
if ((!of_machine_is_compatible("st,stih407")) &&
263+
(!of_machine_is_compatible("st,stih410")))
264+
return -ENODEV;
265+
262266
ddata.cpu = get_cpu_device(0);
263267
if (!ddata.cpu) {
264268
dev_err(ddata.cpu, "Failed to get device for CPU0\n");

drivers/cpuidle/cpuidle-arm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
5050
* call the CPU ops suspend protocol with idle index as a
5151
* parameter.
5252
*/
53-
arm_cpuidle_suspend(idx);
53+
ret = arm_cpuidle_suspend(idx);
5454

5555
cpu_pm_exit();
5656
}

include/acpi/acpi_bus.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,13 @@ struct acpi_data_node {
394394

395395
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
396396
{
397-
return fwnode && (fwnode->type == FWNODE_ACPI
397+
return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI
398398
|| fwnode->type == FWNODE_ACPI_DATA);
399399
}
400400

401401
static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
402402
{
403-
return fwnode && fwnode->type == FWNODE_ACPI;
403+
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI;
404404
}
405405

406406
static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)

include/linux/of.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void of_core_init(void);
133133

134134
static inline bool is_of_node(struct fwnode_handle *fwnode)
135135
{
136-
return fwnode && fwnode->type == FWNODE_OF;
136+
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF;
137137
}
138138

139139
static inline struct device_node *to_of_node(struct fwnode_handle *fwnode)

0 commit comments

Comments
 (0)