diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 02d534da22dd..81e9d4412db8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/suspend.h> | ||
| 29 | #include <linux/syscore_ops.h> | 30 | #include <linux/syscore_ops.h> |
| 30 | #include <linux/tick.h> | 31 | #include <linux/tick.h> |
| 31 | #include <trace/events/power.h> | 32 | #include <trace/events/power.h> |
| @@ -47,6 +48,9 @@ static LIST_HEAD(cpufreq_policy_list); | |||
| 47 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); | 48 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
| 48 | #endif | 49 | #endif |
| 49 | 50 | ||
| 51 | /* Flag to suspend/resume CPUFreq governors */ | ||
| 52 | static bool cpufreq_suspended; | ||
| 53 | |||
| 50 | static inline bool has_target(void) | 54 | static inline bool has_target(void) |
| 51 | { | 55 | { |
| 52 | return cpufreq_driver->target_index || cpufreq_driver->target; | 56 | return cpufreq_driver->target_index || cpufreq_driver->target; |
| @@ -1462,6 +1466,41 @@ static struct subsys_interface cpufreq_interface = { | |||
| 1462 | .remove_dev = cpufreq_remove_dev, | 1466 | .remove_dev = cpufreq_remove_dev, |
| 1463 | }; | 1467 | }; |
| 1464 | 1468 | ||
| 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 | |||
| 1465 | /** | 1504 | /** |
| 1466 | * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. | 1505 | * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. |
| 1467 | * | 1506 | * |
| @@ -1764,6 +1803,10 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
| 1764 | struct cpufreq_governor *gov = NULL; | 1803 | struct cpufreq_governor *gov = NULL; |
| 1765 | #endif | 1804 | #endif |
| 1766 | 1805 | ||
| 1806 | /* Don't start any governor operations if we are entering suspend */ | ||
| 1807 | if (cpufreq_suspended) | ||
| 1808 | return 0; | ||
| 1809 | |||
| 1767 | if (policy->governor->max_transition_latency && | 1810 | if (policy->governor->max_transition_latency && |
| 1768 | policy->cpuinfo.transition_latency > | 1811 | policy->cpuinfo.transition_latency > |
| 1769 | policy->governor->max_transition_latency) { | 1812 | policy->governor->max_transition_latency) { |
| @@ -2076,9 +2119,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
| 2076 | dev = get_cpu_device(cpu); | 2119 | dev = get_cpu_device(cpu); |
| 2077 | if (dev) { | 2120 | if (dev) { |
| 2078 | 2121 | ||
| 2079 | if (action & CPU_TASKS_FROZEN) | ||
| 2080 | frozen = true; | ||
| 2081 | |||
| 2082 | switch (action & ~CPU_TASKS_FROZEN) { | 2122 | switch (action & ~CPU_TASKS_FROZEN) { |
| 2083 | case CPU_ONLINE: | 2123 | case CPU_ONLINE: |
| 2084 | __cpufreq_add_dev(dev, NULL, frozen); | 2124 | __cpufreq_add_dev(dev, NULL, frozen); |
