History

Merge branches 'pm-cpuidle' and 'pm-cpufreq'

* pm-cpuidle: cpuidle: Check for dev before deregistering it. intel_idle: Fixed C6 state on Avoton/Rangeley processors * pm-cpufreq: cpufreq: fix garbage kobjects on errors during suspend/resume cpufreq: suspend governors on system suspend/hibernate

Rafael J. Wysocki committed 12 years ago

Commit 7cdcec93 parents dc1ccc4 813e8e3 2167e235 files · +57 −6Browse files

Unified · Split

5 files
  1. drivers/base/power/main.c +3 −0
  2. drivers/cpufreq/cpufreq.c +43 −3
  3. drivers/cpuidle/cpuidle.c +1 −1
  4. drivers/idle/intel_idle.c +2 −2
  5. include/linux/cpufreq.h +8 −0
drivers/base/power/main.c+3−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 #include <linux/async.h>
3030 #include <linux/suspend.h>
3131 #include <trace/events/power.h>
32+#include <linux/cpufreq.h>
3233 #include <linux/cpuidle.h>
3334 #include <linux/timer.h>
3435
@@ -540,6 +541,7 @@ static void dpm_resume_noirq(pm_message_t state) · 505 unmodified lines
540541 dpm_show_time(starttime, state, "noirq");
541542 resume_device_irqs();
542543 cpuidle_resume();
544+ cpufreq_resume();
543545 }
544546
545547 /**
@@ -955,6 +957,7 @@ static int dpm_suspend_noirq(pm_message_t state) · 409 unmodified lines
955957 ktime_t starttime = ktime_get();
956958 int error = 0;
957959
960+ cpufreq_suspend();
958961 cpuidle_pause();
959962 suspend_device_irqs();
960963 mutex_lock(&dpm_list_mtx);
drivers/cpufreq/cpufreq.c+43−3
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include <linux/module.h>
2727 #include <linux/mutex.h>
2828 #include <linux/slab.h>
29+#include <linux/suspend.h>
2930 #include <linux/syscore_ops.h>
3031 #include <linux/tick.h>
3132 #include <trace/events/power.h>
@@ -47,6 +48,9 @@ static LIST_HEAD(cpufreq_policy_list); · 15 unmodified lines
4748 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
4849 #endif
4950
51+/* Flag to suspend/resume CPUFreq governors */
52+static bool cpufreq_suspended;
53+
5054 static inline bool has_target(void)
5155 {
5256 return cpufreq_driver->target_index || cpufreq_driver->target;
@@ -1462,6 +1466,41 @@ static struct subsys_interface cpufreq_interface = { · 1409 unmodified lines
14621466 .remove_dev = cpufreq_remove_dev,
14631467 };
14641468
1469+void cpufreq_suspend(void)
1470+{
1471+ struct cpufreq_policy *policy;
1472+
1473+ if (!has_target())
1474+ return;
1475+
1476+ pr_debug("%s: Suspending Governors\n", __func__);
1477+
1478+ list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
1479+ if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
1480+ pr_err("%s: Failed to stop governor for policy: %p\n",
1481+ __func__, policy);
1482+
1483+ cpufreq_suspended = true;
1484+}
1485+
1486+void cpufreq_resume(void)
1487+{
1488+ struct cpufreq_policy *policy;
1489+
1490+ if (!has_target())
1491+ return;
1492+
1493+ pr_debug("%s: Resuming Governors\n", __func__);
1494+
1495+ cpufreq_suspended = false;
1496+
1497+ list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
1498+ if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
1499+ || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
1500+ pr_err("%s: Failed to start governor for policy: %p\n",
1501+ __func__, policy);
1502+}
1503+
14651504 /**
14661505 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
14671506 *
@@ -1764,6 +1803,10 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, · 296 unmodified lines
17641803 struct cpufreq_governor *gov = NULL;
17651804 #endif
17661805
1806+ /* Don't start any governor operations if we are entering suspend */
1807+ if (cpufreq_suspended)
1808+ return 0;
1809+
17671810 if (policy->governor->max_transition_latency &&
17681811 policy->cpuinfo.transition_latency >
17691812 policy->governor->max_transition_latency) {
@@ -2076,9 +2119,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, · 306 unmodified lines
20762119 dev = get_cpu_device(cpu);
20772120 if (dev) {
20782121
2079− if (action & CPU_TASKS_FROZEN)
2080− frozen = true;
2081−
20822122 switch (action & ~CPU_TASKS_FROZEN) {
20832123 case CPU_ONLINE:
20842124 __cpufreq_add_dev(dev, NULL, frozen);
drivers/cpuidle/cpuidle.c+1−1
@@ -400,7 +400,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); · 399 unmodified lines
400400 */
401401 void cpuidle_unregister_device(struct cpuidle_device *dev)
402402 {
403− if (dev->registered == 0)
403+ if (!dev || dev->registered == 0)
404404 return;
405405
406406 cpuidle_pause_and_lock();
drivers/idle/intel_idle.c+2−2
@@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[] __initdata = { · 328 unmodified lines
329329 {
330330 .enter = NULL }
331331 };
332−static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = {
332+static struct cpuidle_state avn_cstates[] __initdata = {
333333 {
334334 .name = "C1-AVN",
335335 .desc = "MWAIT 0x00",
@@ -340,7 +340,7 @@ static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = { · 4 unmodified lines
340340 {
341341 .name = "C6-AVN",
342342 .desc = "MWAIT 0x51",
343− .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
343+ .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
344344 .exit_latency = 15,
345345 .target_residency = 45,
346346 .enter = &intel_idle },
include/linux/cpufreq.h+8−0
@@ -280,6 +280,14 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) · 279 unmodified lines
280280 policy->cpuinfo.max_freq);
281281 }
282282
283+#ifdef CONFIG_CPU_FREQ
284+void cpufreq_suspend(void);
285+void cpufreq_resume(void);
286+#else
287+static inline void cpufreq_suspend(void) {}
288+static inline void cpufreq_resume(void) {}
289+#endif
290+
283291 /*********************************************************************
284292 * CPUFREQ NOTIFIER INTERFACE *
285293 *********************************************************************/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t