History

Merge tag 'pm-5.5-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull additional power management updates from Rafael Wysocki: "These fix an ACPI EC driver bug exposed by the recent rework of the suspend-to-idle code flow, reintroduce frequency constraints into device PM QoS (in preparation for adding QoS support to devfreq), drop a redundant field from struct cpuidle_state and clean up Kconfig in some places. Specifics: - Avoid a race condition in the ACPI EC driver that may cause systems to be unable to leave suspend-to-idle (Rafael Wysocki) - Drop the "disabled" field, which is redundant, from struct cpuidle_state (Rafael Wysocki) - Reintroduce device PM QoS frequency constraints (temporarily introduced and than dropped during the 5.4 cycle) in preparation for adding QoS support to devfreq (Leonard Crestez) - Clean up indentation (in multiple places) and the cpuidle drivers help text in Kconfig (Krzysztof Kozlowski, Randy Dunlap)" * tag 'pm-5.5-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: PM: s2idle: Rework ACPI events synchronization ACPI: EC: Rework flushing of pending work PM / devfreq: Add missing locking while setting suspend_freq PM / QoS: Restore DEV_PM_QOS_MIN/MAX_FREQUENCY PM / QoS: Reorder pm_qos/freq_qos/dev_pm_qos structs PM / QoS: Initial kunit test PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX power: avs: Fix Kconfig indentation cpufreq: Fix Kconfig indentation cpuidle: minor Kconfig help text fixes cpuidle: Drop disabled field from struct cpuidle_state cpuidle: Fix Kconfig indentation

Linus Torvalds committed 6 years ago

Commit ef867c12 parents 63de374 1e4230f19 files · +324 −120Browse files

Unified · Split

19 files
  1. arch/sh/kernel/cpu/shmobile/cpuidle.c +4 −4
  2. drivers/acpi/ec.c +13 −23
  3. drivers/acpi/sleep.c +19 −7
  4. drivers/base/Kconfig +4 −0
  5. drivers/base/power/Makefile +1 −0
  6. drivers/base/power/qos-test.c +117 −0
  7. drivers/base/power/qos.c +67 −6
  8. drivers/cpufreq/Kconfig.powerpc +4 −4
  9. drivers/cpufreq/Kconfig.x86 +8 −8
  10. drivers/cpuidle/Kconfig +8 −8
  11. drivers/cpuidle/Kconfig.arm +11 −11
  12. drivers/cpuidle/cpuidle.c +1 −1
  13. drivers/cpuidle/poll_state.c +0 −1
  14. drivers/devfreq/devfreq.c +4 −0
  15. drivers/idle/intel_idle.c +3 −3
  16. drivers/power/avs/Kconfig +6 −6
  17. include/linux/cpuidle.h +1 −1
  18. include/linux/pm_qos.h +50 −36
  19. kernel/power/qos.c +3 −1
arch/sh/kernel/cpu/shmobile/cpuidle.c+4−4
@@ -67,7 +67,7 @@ static struct cpuidle_driver cpuidle_driver = { · 66 unmodified lines
67 .enter = cpuidle_sleep_enter,67 .enter = cpuidle_sleep_enter,
68 .name = "C2",68 .name = "C2",
69 .desc = "SuperH Sleep Mode [SF]",69 .desc = "SuperH Sleep Mode [SF]",
70 .disabled = true,70 .flags = CPUIDLE_FLAG_UNUSABLE,
71 },71 },
72 {72 {
73 .exit_latency = 2300,73 .exit_latency = 2300,
@@ -76,7 +76,7 @@ static struct cpuidle_driver cpuidle_driver = { · 2 unmodified lines
76 .enter = cpuidle_sleep_enter,76 .enter = cpuidle_sleep_enter,
77 .name = "C3",77 .name = "C3",
78 .desc = "SuperH Mobile Standby Mode [SF]",78 .desc = "SuperH Mobile Standby Mode [SF]",
79 .disabled = true,79 .flags = CPUIDLE_FLAG_UNUSABLE,
80 },80 },
81 },81 },
82 .safe_state_index = 0,82 .safe_state_index = 0,
@@ -86,10 +86,10 @@ static struct cpuidle_driver cpuidle_driver = { · 3 unmodified lines
86int __init sh_mobile_setup_cpuidle(void)86int __init sh_mobile_setup_cpuidle(void)
87{87{
88 if (sh_mobile_sleep_supported & SUSP_SH_SF)88 if (sh_mobile_sleep_supported & SUSP_SH_SF)
89 cpuidle_driver.states[1].disabled = false;89 cpuidle_driver.states[1].flags = CPUIDLE_FLAG_NONE;
90 90
91 if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)91 if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
92 cpuidle_driver.states[2].disabled = false;92 cpuidle_driver.states[2].flags = CPUIDLE_FLAG_NONE;
93 93
94 return cpuidle_register(&cpuidle_driver, NULL);94 return cpuidle_register(&cpuidle_driver, NULL);
95}95}
drivers/acpi/ec.c+13−23
@@ -533,26 +533,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) · 532 unmodified lines
533}533}
534 534
535#ifdef CONFIG_PM_SLEEP535#ifdef CONFIG_PM_SLEEP
536static bool acpi_ec_query_flushed(struct acpi_ec *ec)536static void __acpi_ec_flush_work(void)
537{537{
538 bool flushed;538 flush_scheduled_work(); /* flush ec->work */
539 unsigned long flags;539 flush_workqueue(ec_query_wq); /* flush queries */
540
541 spin_lock_irqsave(&ec->lock, flags);
542 flushed = !ec->nr_pending_queries;
543 spin_unlock_irqrestore(&ec->lock, flags);
544 return flushed;
545}
546
547static void __acpi_ec_flush_event(struct acpi_ec *ec)
548{
549 /*
550 * When ec_freeze_events is true, we need to flush events in
551 * the proper position before entering the noirq stage.
552 */
553 wait_event(ec->wait, acpi_ec_query_flushed(ec));
554 if (ec_query_wq)
555 flush_workqueue(ec_query_wq);
556}540}
557 541
558static void acpi_ec_disable_event(struct acpi_ec *ec)542static void acpi_ec_disable_event(struct acpi_ec *ec)
@@ -562,15 +546,21 @@ static void acpi_ec_disable_event(struct acpi_ec *ec) · 3 unmodified lines
562 spin_lock_irqsave(&ec->lock, flags);546 spin_lock_irqsave(&ec->lock, flags);
563 __acpi_ec_disable_event(ec);547 __acpi_ec_disable_event(ec);
564 spin_unlock_irqrestore(&ec->lock, flags);548 spin_unlock_irqrestore(&ec->lock, flags);
565 __acpi_ec_flush_event(ec);549
550 /*
551 * When ec_freeze_events is true, we need to flush events in
552 * the proper position before entering the noirq stage.
553 */
554 __acpi_ec_flush_work();
566}555}
567 556
568void acpi_ec_flush_work(void)557void acpi_ec_flush_work(void)
569{558{
570 if (first_ec)559 /* Without ec_query_wq there is nothing to flush. */
571 __acpi_ec_flush_event(first_ec);560 if (!ec_query_wq)
561 return;
572 562
573 flush_scheduled_work();563 __acpi_ec_flush_work();
574}564}
575#endif /* CONFIG_PM_SLEEP */565#endif /* CONFIG_PM_SLEEP */
576 566
drivers/acpi/sleep.c+19−7
@@ -977,6 +977,16 @@ static int acpi_s2idle_prepare_late(void) · 976 unmodified lines
977 return 0;977 return 0;
978}978}
979 979
980static void acpi_s2idle_sync(void)
981{
982 /*
983 * The EC driver uses the system workqueue and an additional special
984 * one, so those need to be flushed too.
985 */
986 acpi_ec_flush_work();
987 acpi_os_wait_events_complete(); /* synchronize Notify handling */
988}
989
980static void acpi_s2idle_wake(void)990static void acpi_s2idle_wake(void)
981{991{
982 /*992 /*
@@ -1001,13 +1011,8 @@ static void acpi_s2idle_wake(void) · 18 unmodified lines
1001 * should be missed by canceling the wakeup here.1011 * should be missed by canceling the wakeup here.
1002 */1012 */
1003 pm_system_cancel_wakeup();1013 pm_system_cancel_wakeup();
1004 /*1014
1005 * The EC driver uses the system workqueue and an additional1015 acpi_s2idle_sync();
1006 * special one, so those need to be flushed too.
1007 */
1008 acpi_os_wait_events_complete(); /* synchronize EC GPE processing */
1009 acpi_ec_flush_work();
1010 acpi_os_wait_events_complete(); /* synchronize Notify handling */
1011 1016
1012 rearm_wake_irq(acpi_sci_irq);1017 rearm_wake_irq(acpi_sci_irq);
1013 }1018 }
@@ -1024,6 +1029,13 @@ static void acpi_s2idle_restore_early(void) · 10 unmodified lines
1024 1029
1025static void acpi_s2idle_restore(void)1030static void acpi_s2idle_restore(void)
1026{1031{
1032 /*
1033 * Drain pending events before restoring the working-state configuration
1034 * of GPEs.
1035 */
1036 acpi_os_wait_events_complete(); /* synchronize GPE processing */
1037 acpi_s2idle_sync();
1038
1027 s2idle_wakeup = false;1039 s2idle_wakeup = false;
1028 1040
1029 acpi_enable_all_runtime_gpes();1041 acpi_enable_all_runtime_gpes();
drivers/base/Kconfig+4−0
@@ -148,6 +148,10 @@ config DEBUG_TEST_DRIVER_REMOVE · 147 unmodified lines
148 unusable. You should say N here unless you are explicitly looking to148 unusable. You should say N here unless you are explicitly looking to
149 test this functionality.149 test this functionality.
150 150
151config PM_QOS_KUNIT_TEST
152 bool "KUnit Test for PM QoS features"
153 depends on KUNIT
154
151config HMEM_REPORTING155config HMEM_REPORTING
152 bool156 bool
153 default n157 default n
drivers/base/power/Makefile+1−0
@@ -4,5 +4,6 @@ obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o wakeup_stats.o · 3 unmodified lines
4obj-$(CONFIG_PM_TRACE_RTC) += trace.o4obj-$(CONFIG_PM_TRACE_RTC) += trace.o
5obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o5obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o
6obj-$(CONFIG_HAVE_CLK) += clock_ops.o6obj-$(CONFIG_HAVE_CLK) += clock_ops.o
7obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
7 8
8ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG9ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
drivers/base/power/qos-test.c+117−0
@@ -0,0 +1,117 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2019 NXP
4 */
5#include <kunit/test.h>
6#include <linux/pm_qos.h>
7
8/* Basic test for aggregating two "min" requests */
9static void freq_qos_test_min(struct kunit *test)
10{
11 struct freq_constraints qos;
12 struct freq_qos_request req1, req2;
13 int ret;
14
15 freq_constraints_init(&qos);
16 memset(&req1, 0, sizeof(req1));
17 memset(&req2, 0, sizeof(req2));
18
19 ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MIN, 1000);
20 KUNIT_EXPECT_EQ(test, ret, 1);
21 ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MIN, 2000);
22 KUNIT_EXPECT_EQ(test, ret, 1);
23
24 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
25
26 ret = freq_qos_remove_request(&req2);
27 KUNIT_EXPECT_EQ(test, ret, 1);
28 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
29
30 ret = freq_qos_remove_request(&req1);
31 KUNIT_EXPECT_EQ(test, ret, 1);
32 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
33 FREQ_QOS_MIN_DEFAULT_VALUE);
34}
35
36/* Test that requests for MAX_DEFAULT_VALUE have no effect */
37static void freq_qos_test_maxdef(struct kunit *test)
38{
39 struct freq_constraints qos;
40 struct freq_qos_request req1, req2;
41 int ret;
42
43 freq_constraints_init(&qos);
44 memset(&req1, 0, sizeof(req1));
45 memset(&req2, 0, sizeof(req2));
46 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX),
47 FREQ_QOS_MAX_DEFAULT_VALUE);
48
49 ret = freq_qos_add_request(&qos, &req1, FREQ_QOS_MAX,
50 FREQ_QOS_MAX_DEFAULT_VALUE);
51 KUNIT_EXPECT_EQ(test, ret, 0);
52 ret = freq_qos_add_request(&qos, &req2, FREQ_QOS_MAX,
53 FREQ_QOS_MAX_DEFAULT_VALUE);
54 KUNIT_EXPECT_EQ(test, ret, 0);
55
56 /* Add max 1000 */
57 ret = freq_qos_update_request(&req1, 1000);
58 KUNIT_EXPECT_EQ(test, ret, 1);
59 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
60
61 /* Add max 2000, no impact */
62 ret = freq_qos_update_request(&req2, 2000);
63 KUNIT_EXPECT_EQ(test, ret, 0);
64 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 1000);
65
66 /* Remove max 1000, new max 2000 */
67 ret = freq_qos_remove_request(&req1);
68 KUNIT_EXPECT_EQ(test, ret, 1);
69 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MAX), 2000);
70}
71
72/*
73 * Test that a freq_qos_request can be added again after removal
74 *
75 * This issue was solved by commit 05ff1ba412fd ("PM: QoS: Invalidate frequency
76 * QoS requests after removal")
77 */
78static void freq_qos_test_readd(struct kunit *test)
79{
80 struct freq_constraints qos;
81 struct freq_qos_request req;
82 int ret;
83
84 freq_constraints_init(&qos);
85 memset(&req, 0, sizeof(req));
86 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
87 FREQ_QOS_MIN_DEFAULT_VALUE);
88
89 /* Add */
90 ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 1000);
91 KUNIT_EXPECT_EQ(test, ret, 1);
92 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 1000);
93
94 /* Remove */
95 ret = freq_qos_remove_request(&req);
96 KUNIT_EXPECT_EQ(test, ret, 1);
97 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN),
98 FREQ_QOS_MIN_DEFAULT_VALUE);
99
100 /* Add again */
101 ret = freq_qos_add_request(&qos, &req, FREQ_QOS_MIN, 2000);
102 KUNIT_EXPECT_EQ(test, ret, 1);
103 KUNIT_EXPECT_EQ(test, freq_qos_read_value(&qos, FREQ_QOS_MIN), 2000);
104}
105
106static struct kunit_case pm_qos_test_cases[] = {
107 KUNIT_CASE(freq_qos_test_min),
108 KUNIT_CASE(freq_qos_test_maxdef),
109 KUNIT_CASE(freq_qos_test_readd),
110 {},
111};
112
113static struct kunit_suite pm_qos_test_module = {
114 .name = "qos-kunit-test",
115 .test_cases = pm_qos_test_cases,
116};
117kunit_test_suite(pm_qos_test_module);
drivers/base/power/qos.c+67−6
@@ -115,10 +115,20 @@ s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type) · 114 unmodified lines
115 115
116 spin_lock_irqsave(&dev->power.lock, flags);116 spin_lock_irqsave(&dev->power.lock, flags);
117 117
118 if (type == DEV_PM_QOS_RESUME_LATENCY) {118 switch (type) {
119 case DEV_PM_QOS_RESUME_LATENCY:
119 ret = IS_ERR_OR_NULL(qos) ? PM_QOS_RESUME_LATENCY_NO_CONSTRAINT120 ret = IS_ERR_OR_NULL(qos) ? PM_QOS_RESUME_LATENCY_NO_CONSTRAINT
120 : pm_qos_read_value(&qos->resume_latency);121 : pm_qos_read_value(&qos->resume_latency);
121 } else {122 break;
123 case DEV_PM_QOS_MIN_FREQUENCY:
124 ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE
125 : freq_qos_read_value(&qos->freq, FREQ_QOS_MIN);
126 break;
127 case DEV_PM_QOS_MAX_FREQUENCY:
128 ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE
129 : freq_qos_read_value(&qos->freq, FREQ_QOS_MAX);
130 break;
131 default:
122 WARN_ON(1);132 WARN_ON(1);
123 ret = 0;133 ret = 0;
124 }134 }
@@ -159,6 +169,10 @@ static int apply_constraint(struct dev_pm_qos_request *req, · 34 unmodified lines
159 req->dev->power.set_latency_tolerance(req->dev, value);169 req->dev->power.set_latency_tolerance(req->dev, value);
160 }170 }
161 break;171 break;
172 case DEV_PM_QOS_MIN_FREQUENCY:
173 case DEV_PM_QOS_MAX_FREQUENCY:
174 ret = freq_qos_apply(&req->data.freq, action, value);
175 break;
162 case DEV_PM_QOS_FLAGS:176 case DEV_PM_QOS_FLAGS:
163 ret = pm_qos_update_flags(&qos->flags, &req->data.flr,177 ret = pm_qos_update_flags(&qos->flags, &req->data.flr,
164 action, value);178 action, value);
@@ -209,6 +223,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) · 44 unmodified lines
209 c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;223 c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;
210 c->type = PM_QOS_MIN;224 c->type = PM_QOS_MIN;
211 225
226 freq_constraints_init(&qos->freq);
227
212 INIT_LIST_HEAD(&qos->flags.list);228 INIT_LIST_HEAD(&qos->flags.list);
213 229
214 spin_lock_irq(&dev->power.lock);230 spin_lock_irq(&dev->power.lock);
@@ -269,6 +285,20 @@ void dev_pm_qos_constraints_destroy(struct device *dev) · 54 unmodified lines
269 memset(req, 0, sizeof(*req));285 memset(req, 0, sizeof(*req));
270 }286 }
271 287
288 c = &qos->freq.min_freq;
289 plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
290 apply_constraint(req, PM_QOS_REMOVE_REQ,
291 PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
292 memset(req, 0, sizeof(*req));
293 }
294
295 c = &qos->freq.max_freq;
296 plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
297 apply_constraint(req, PM_QOS_REMOVE_REQ,
298 PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
299 memset(req, 0, sizeof(*req));
300 }
301
272 f = &qos->flags;302 f = &qos->flags;
273 list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {303 list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
274 apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);304 apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
@@ -314,11 +344,22 @@ static int __dev_pm_qos_add_request(struct device *dev, · 39 unmodified lines
314 ret = dev_pm_qos_constraints_allocate(dev);344 ret = dev_pm_qos_constraints_allocate(dev);
315 345
316 trace_dev_pm_qos_add_request(dev_name(dev), type, value);346 trace_dev_pm_qos_add_request(dev_name(dev), type, value);
317 if (!ret) {347 if (ret)
318 req->dev = dev;348 return ret;
319 req->type = type;349
350 req->dev = dev;
351 req->type = type;
352 if (req->type == DEV_PM_QOS_MIN_FREQUENCY)
353 ret = freq_qos_add_request(&dev->power.qos->freq,
354 &req->data.freq,
355 FREQ_QOS_MIN, value);
356 else if (req->type == DEV_PM_QOS_MAX_FREQUENCY)
357 ret = freq_qos_add_request(&dev->power.qos->freq,
358 &req->data.freq,
359 FREQ_QOS_MAX, value);
360 else
320 ret = apply_constraint(req, PM_QOS_ADD_REQ, value);361 ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
321 }362
322 return ret;363 return ret;
323}364}
324 365
@@ -382,6 +423,10 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, · 57 unmodified lines
382 case DEV_PM_QOS_LATENCY_TOLERANCE:423 case DEV_PM_QOS_LATENCY_TOLERANCE:
383 curr_value = req->data.pnode.prio;424 curr_value = req->data.pnode.prio;
384 break;425 break;
426 case DEV_PM_QOS_MIN_FREQUENCY:
427 case DEV_PM_QOS_MAX_FREQUENCY:
428 curr_value = req->data.freq.pnode.prio;
429 break;
385 case DEV_PM_QOS_FLAGS:430 case DEV_PM_QOS_FLAGS:
386 curr_value = req->data.flr.flags;431 curr_value = req->data.flr.flags;
387 break;432 break;
@@ -507,6 +552,14 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier, · 119 unmodified lines
507 ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers,552 ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers,
508 notifier);553 notifier);
509 break;554 break;
555 case DEV_PM_QOS_MIN_FREQUENCY:
556 ret = freq_qos_add_notifier(&dev->power.qos->freq,
557 FREQ_QOS_MIN, notifier);
558 break;
559 case DEV_PM_QOS_MAX_FREQUENCY:
560 ret = freq_qos_add_notifier(&dev->power.qos->freq,
561 FREQ_QOS_MAX, notifier);
562 break;
510 default:563 default:
511 WARN_ON(1);564 WARN_ON(1);
512 ret = -EINVAL;565 ret = -EINVAL;
@@ -546,6 +599,14 @@ int dev_pm_qos_remove_notifier(struct device *dev, · 33 unmodified lines
546 ret = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers,599 ret = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers,
547 notifier);600 notifier);
548 break;601 break;
602 case DEV_PM_QOS_MIN_FREQUENCY:
603 ret = freq_qos_remove_notifier(&dev->power.qos->freq,
604 FREQ_QOS_MIN, notifier);
605 break;
606 case DEV_PM_QOS_MAX_FREQUENCY:
607 ret = freq_qos_remove_notifier(&dev->power.qos->freq,
608 FREQ_QOS_MAX, notifier);
609 break;
549 default:610 default:
550 WARN_ON(1);611 WARN_ON(1);
551 ret = -EINVAL;612 ret = -EINVAL;
drivers/cpufreq/Kconfig.powerpc+4−4
@@ -48,9 +48,9 @@ config PPC_PASEMI_CPUFREQ · 47 unmodified lines
48 PWRficient processors.48 PWRficient processors.
49 49
50config POWERNV_CPUFREQ50config POWERNV_CPUFREQ
51 tristate "CPU frequency scaling for IBM POWERNV platform"51 tristate "CPU frequency scaling for IBM POWERNV platform"
52 depends on PPC_POWERNV52 depends on PPC_POWERNV
53 default y53 default y
54 help54 help
55 This adds support for CPU frequency switching on IBM POWERNV55 This adds support for CPU frequency switching on IBM POWERNV
56 platform56 platform
drivers/cpufreq/Kconfig.x86+8−8
@@ -4,17 +4,17 @@ · 3 unmodified lines
4#4#
5 5
6config X86_INTEL_PSTATE6config X86_INTEL_PSTATE
7 bool "Intel P state control"7 bool "Intel P state control"
8 depends on X868 depends on X86
9 select ACPI_PROCESSOR if ACPI9 select ACPI_PROCESSOR if ACPI
10 select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_MC_PRIO10 select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_MC_PRIO
11 help11 help
12 This driver provides a P state for Intel core processors.12 This driver provides a P state for Intel core processors.
13 The driver implements an internal governor and will become13 The driver implements an internal governor and will become
14 the scaling driver and governor for Sandy bridge processors.14 the scaling driver and governor for Sandy bridge processors.
15 15
16 When this driver is enabled it will become the preferred16 When this driver is enabled it will become the preferred
17 scaling driver for Sandy bridge processors.17 scaling driver for Sandy bridge processors.
18 18
19 If in doubt, say N.19 If in doubt, say N.
20 20
drivers/cpuidle/Kconfig+8−8
@@ -16,7 +16,7 @@ config CPU_IDLE · 15 unmodified lines
16if CPU_IDLE16if CPU_IDLE
17 17
18config CPU_IDLE_MULTIPLE_DRIVERS18config CPU_IDLE_MULTIPLE_DRIVERS
19 bool19 bool
20 20
21config CPU_IDLE_GOV_LADDER21config CPU_IDLE_GOV_LADDER
22 bool "Ladder governor (for periodic timer tick)"22 bool "Ladder governor (for periodic timer tick)"
@@ -63,13 +63,13 @@ source "drivers/cpuidle/Kconfig.powerpc" · 40 unmodified lines
63endmenu63endmenu
64 64
65config HALTPOLL_CPUIDLE65config HALTPOLL_CPUIDLE
66 tristate "Halt poll cpuidle driver"66 tristate "Halt poll cpuidle driver"
67 depends on X86 && KVM_GUEST67 depends on X86 && KVM_GUEST
68 default y68 default y
69 help69 help
70 This option enables halt poll cpuidle driver, which allows to poll70 This option enables halt poll cpuidle driver, which allows to poll
71 before halting in the guest (more efficient than polling in the71 before halting in the guest (more efficient than polling in the
72 host via halt_poll_ns for some scenarios).72 host via halt_poll_ns for some scenarios).
73 73
74endif74endif
75 75
drivers/cpuidle/Kconfig.arm+11−11
@@ -3,15 +3,15 @@ · 2 unmodified lines
3# ARM CPU Idle drivers3# ARM CPU Idle drivers
4#4#
5config ARM_CPUIDLE5config ARM_CPUIDLE
6 bool "Generic ARM/ARM64 CPU idle Driver"6 bool "Generic ARM/ARM64 CPU idle Driver"
7 select DT_IDLE_STATES7 select DT_IDLE_STATES
8 select CPU_IDLE_MULTIPLE_DRIVERS8 select CPU_IDLE_MULTIPLE_DRIVERS
9 help9 help
10 Select this to enable generic cpuidle driver for ARM.10 Select this to enable generic cpuidle driver for ARM.
11 It provides a generic idle driver whose idle states are configured11 It provides a generic idle driver whose idle states are configured
12 at run-time through DT nodes. The CPUidle suspend backend is12 at run-time through DT nodes. The CPUidle suspend backend is
13 initialized by calling the CPU operations init idle hook13 initialized by calling the CPU operations init idle hook
14 provided by architecture code.14 provided by architecture code.
15 15
16config ARM_PSCI_CPUIDLE16config ARM_PSCI_CPUIDLE
17 bool "PSCI CPU idle Driver"17 bool "PSCI CPU idle Driver"
@@ -65,21 +65,21 @@ config ARM_U8500_CPUIDLE · 47 unmodified lines
65 bool "Cpu Idle Driver for the ST-E u8500 processors"65 bool "Cpu Idle Driver for the ST-E u8500 processors"
66 depends on ARCH_U8500 && !ARM6466 depends on ARCH_U8500 && !ARM64
67 help67 help
68 Select this to enable cpuidle for ST-E u8500 processors68 Select this to enable cpuidle for ST-E u8500 processors.
69 69
70config ARM_AT91_CPUIDLE70config ARM_AT91_CPUIDLE
71 bool "Cpu Idle Driver for the AT91 processors"71 bool "Cpu Idle Driver for the AT91 processors"
72 default y72 default y
73 depends on ARCH_AT91 && !ARM6473 depends on ARCH_AT91 && !ARM64
74 help74 help
75 Select this to enable cpuidle for AT91 processors75 Select this to enable cpuidle for AT91 processors.
76 76
77config ARM_EXYNOS_CPUIDLE77config ARM_EXYNOS_CPUIDLE
78 bool "Cpu Idle Driver for the Exynos processors"78 bool "Cpu Idle Driver for the Exynos processors"
79 depends on ARCH_EXYNOS && !ARM6479 depends on ARCH_EXYNOS && !ARM64
80 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP80 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
81 help81 help
82 Select this to enable cpuidle for Exynos processors82 Select this to enable cpuidle for Exynos processors.
83 83
84config ARM_MVEBU_V7_CPUIDLE84config ARM_MVEBU_V7_CPUIDLE
85 bool "CPU Idle Driver for mvebu v7 family processors"85 bool "CPU Idle Driver for mvebu v7 family processors"
drivers/cpuidle/cpuidle.c+1−1
@@ -572,7 +572,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) · 571 unmodified lines
572 return -EINVAL;572 return -EINVAL;
573 573
574 for (i = 0; i < drv->state_count; i++)574 for (i = 0; i < drv->state_count; i++)
575 if (drv->states[i].disabled)575 if (drv->states[i].flags & CPUIDLE_FLAG_UNUSABLE)
576 dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;576 dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
577 577
578 per_cpu(cpuidle_devices, dev->cpu) = dev;578 per_cpu(cpuidle_devices, dev->cpu) = dev;
drivers/cpuidle/poll_state.c+0−1
@@ -53,7 +53,6 @@ void cpuidle_poll_state_init(struct cpuidle_driver *drv) · 52 unmodified lines
53 state->target_residency_ns = 0;53 state->target_residency_ns = 0;
54 state->power_usage = -1;54 state->power_usage = -1;
55 state->enter = poll_idle;55 state->enter = poll_idle;
56 state->disabled = false;
57 state->flags = CPUIDLE_FLAG_POLLING;56 state->flags = CPUIDLE_FLAG_POLLING;
58}57}
59EXPORT_SYMBOL_GPL(cpuidle_poll_state_init);58EXPORT_SYMBOL_GPL(cpuidle_poll_state_init);
drivers/devfreq/devfreq.c+4−0
@@ -921,7 +921,9 @@ int devfreq_suspend_device(struct devfreq *devfreq) · 920 unmodified lines
921 }921 }
922 922
923 if (devfreq->suspend_freq) {923 if (devfreq->suspend_freq) {
924 mutex_lock(&devfreq->lock);
924 ret = devfreq_set_target(devfreq, devfreq->suspend_freq, 0);925 ret = devfreq_set_target(devfreq, devfreq->suspend_freq, 0);
926 mutex_unlock(&devfreq->lock);
925 if (ret)927 if (ret)
926 return ret;928 return ret;
927 }929 }
@@ -949,7 +951,9 @@ int devfreq_resume_device(struct devfreq *devfreq) · 21 unmodified lines
949 return 0;951 return 0;
950 952
951 if (devfreq->resume_freq) {953 if (devfreq->resume_freq) {
954 mutex_lock(&devfreq->lock);
952 ret = devfreq_set_target(devfreq, devfreq->resume_freq, 0);955 ret = devfreq_set_target(devfreq, devfreq->resume_freq, 0);
956 mutex_unlock(&devfreq->lock);
953 if (ret)957 if (ret)
954 return ret;958 return ret;
955 }959 }
drivers/idle/intel_idle.c+3−3
@@ -1291,8 +1291,8 @@ static void sklh_idle_state_table_update(void) · 1290 unmodified lines
1291 return;1291 return;
1292 }1292 }
1293 1293
1294 skl_cstates[5].disabled = 1; /* C8-SKL */1294 skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE; /* C8-SKL */
1295 skl_cstates[6].disabled = 1; /* C9-SKL */1295 skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE; /* C9-SKL */
1296}1296}
1297/*1297/*
1298 * intel_idle_state_table_update()1298 * intel_idle_state_table_update()
@@ -1355,7 +1355,7 @@ static void __init intel_idle_cpuidle_driver_init(void) · 56 unmodified lines
1355 continue;1355 continue;
1356 1356
1357 /* if state marked as disabled, skip it */1357 /* if state marked as disabled, skip it */
1358 if (cpuidle_state_table[cstate].disabled != 0) {1358 if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) {
1359 pr_debug("state %s is disabled\n",1359 pr_debug("state %s is disabled\n",
1360 cpuidle_state_table[cstate].name);1360 cpuidle_state_table[cstate].name);
1361 continue;1361 continue;
drivers/power/avs/Kconfig+6−6
@@ -13,9 +13,9 @@ menuconfig POWER_AVS · 12 unmodified lines
13 Say Y here to enable Adaptive Voltage Scaling class support.13 Say Y here to enable Adaptive Voltage Scaling class support.
14 14
15config ROCKCHIP_IODOMAIN15config ROCKCHIP_IODOMAIN
16 tristate "Rockchip IO domain support"16 tristate "Rockchip IO domain support"
17 depends on POWER_AVS && ARCH_ROCKCHIP && OF17 depends on POWER_AVS && ARCH_ROCKCHIP && OF
18 help18 help
19 Say y here to enable support io domains on Rockchip SoCs. It is19 Say y here to enable support io domains on Rockchip SoCs. It is
20 necessary for the io domain setting of the SoC to match the20 necessary for the io domain setting of the SoC to match the
21 voltage supplied by the regulators.21 voltage supplied by the regulators.
include/linux/cpuidle.h+1−1
@@ -54,7 +54,6 @@ struct cpuidle_state { · 53 unmodified lines
54 unsigned int exit_latency; /* in US */54 unsigned int exit_latency; /* in US */
55 int power_usage; /* in mW */55 int power_usage; /* in mW */
56 unsigned int target_residency; /* in US */56 unsigned int target_residency; /* in US */
57 bool disabled; /* disabled on all CPUs */
58 57
59 int (*enter) (struct cpuidle_device *dev,58 int (*enter) (struct cpuidle_device *dev,
60 struct cpuidle_driver *drv,59 struct cpuidle_driver *drv,
@@ -77,6 +76,7 @@ struct cpuidle_state { · 16 unmodified lines
77#define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */76#define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */
78#define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */77#define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */
79#define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */78#define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */
79#define CPUIDLE_FLAG_UNUSABLE BIT(3) /* avoid using this state */
80 80
81struct cpuidle_device_kobj;81struct cpuidle_device_kobj;
82struct cpuidle_state_kobj;82struct cpuidle_state_kobj;
include/linux/pm_qos.h+50−36
@@ -34,6 +34,8 @@ enum pm_qos_flags_status { · 33 unmodified lines
34#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY34#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY
35#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS35#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS
36#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 036#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
37#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0
38#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE
37#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)39#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
38 40
39#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)41#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
@@ -49,21 +51,6 @@ struct pm_qos_flags_request { · 9 unmodified lines
49 s32 flags; /* Do not change to 64 bit */51 s32 flags; /* Do not change to 64 bit */
50};52};
51 53
52enum dev_pm_qos_req_type {
53 DEV_PM_QOS_RESUME_LATENCY = 1,
54 DEV_PM_QOS_LATENCY_TOLERANCE,
55 DEV_PM_QOS_FLAGS,
56};
57
58struct dev_pm_qos_request {
59 enum dev_pm_qos_req_type type;
60 union {
61 struct plist_node pnode;
62 struct pm_qos_flags_request flr;
63 } data;
64 struct device *dev;
65};
66
67enum pm_qos_type {54enum pm_qos_type {
68 PM_QOS_UNITIALIZED,55 PM_QOS_UNITIALIZED,
69 PM_QOS_MAX, /* return the largest value */56 PM_QOS_MAX, /* return the largest value */
@@ -90,9 +77,51 @@ struct pm_qos_flags { · 20 unmodified lines
90 s32 effective_flags; /* Do not change to 64 bit */77 s32 effective_flags; /* Do not change to 64 bit */
91};78};
92 79
80
81#define FREQ_QOS_MIN_DEFAULT_VALUE 0
82#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX
83
84enum freq_qos_req_type {
85 FREQ_QOS_MIN = 1,
86 FREQ_QOS_MAX,
87};
88
89struct freq_constraints {
90 struct pm_qos_constraints min_freq;
91 struct blocking_notifier_head min_freq_notifiers;
92 struct pm_qos_constraints max_freq;
93 struct blocking_notifier_head max_freq_notifiers;
94};
95
96struct freq_qos_request {
97 enum freq_qos_req_type type;
98 struct plist_node pnode;
99 struct freq_constraints *qos;
100};
101
102
103enum dev_pm_qos_req_type {
104 DEV_PM_QOS_RESUME_LATENCY = 1,
105 DEV_PM_QOS_LATENCY_TOLERANCE,
106 DEV_PM_QOS_MIN_FREQUENCY,
107 DEV_PM_QOS_MAX_FREQUENCY,
108 DEV_PM_QOS_FLAGS,
109};
110
111struct dev_pm_qos_request {
112 enum dev_pm_qos_req_type type;
113 union {
114 struct plist_node pnode;
115 struct pm_qos_flags_request flr;
116 struct freq_qos_request freq;
117 } data;
118 struct device *dev;
119};
120
93struct dev_pm_qos {121struct dev_pm_qos {
94 struct pm_qos_constraints resume_latency;122 struct pm_qos_constraints resume_latency;
95 struct pm_qos_constraints latency_tolerance;123 struct pm_qos_constraints latency_tolerance;
124 struct freq_constraints freq;
96 struct pm_qos_flags flags;125 struct pm_qos_flags flags;
97 struct dev_pm_qos_request *resume_latency_req;126 struct dev_pm_qos_request *resume_latency_req;
98 struct dev_pm_qos_request *latency_tolerance_req;127 struct dev_pm_qos_request *latency_tolerance_req;
@@ -191,6 +220,10 @@ static inline s32 dev_pm_qos_read_value(struct device *dev, · 92 unmodified lines
191 switch (type) {220 switch (type) {
192 case DEV_PM_QOS_RESUME_LATENCY:221 case DEV_PM_QOS_RESUME_LATENCY:
193 return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;222 return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
223 case DEV_PM_QOS_MIN_FREQUENCY:
224 return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE;
225 case DEV_PM_QOS_MAX_FREQUENCY:
226 return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
194 default:227 default:
195 WARN_ON(1);228 WARN_ON(1);
196 return 0;229 return 0;
@@ -255,27 +288,6 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) · 58 unmodified lines
255}288}
256#endif289#endif
257 290
258#define FREQ_QOS_MIN_DEFAULT_VALUE 0
259#define FREQ_QOS_MAX_DEFAULT_VALUE (-1)
260
261enum freq_qos_req_type {
262 FREQ_QOS_MIN = 1,
263 FREQ_QOS_MAX,
264};
265
266struct freq_constraints {
267 struct pm_qos_constraints min_freq;
268 struct blocking_notifier_head min_freq_notifiers;
269 struct pm_qos_constraints max_freq;
270 struct blocking_notifier_head max_freq_notifiers;
271};
272
273struct freq_qos_request {
274 enum freq_qos_req_type type;
275 struct plist_node pnode;
276 struct freq_constraints *qos;
277};
278
279static inline int freq_qos_request_active(struct freq_qos_request *req)291static inline int freq_qos_request_active(struct freq_qos_request *req)
280{292{
281 return !IS_ERR_OR_NULL(req->qos);293 return !IS_ERR_OR_NULL(req->qos);
@@ -291,6 +303,8 @@ int freq_qos_add_request(struct freq_constraints *qos, · 9 unmodified lines
291 enum freq_qos_req_type type, s32 value);303 enum freq_qos_req_type type, s32 value);
292int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);304int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);
293int freq_qos_remove_request(struct freq_qos_request *req);305int freq_qos_remove_request(struct freq_qos_request *req);
306int freq_qos_apply(struct freq_qos_request *req,
307 enum pm_qos_req_action action, s32 value);
294 308
295int freq_qos_add_notifier(struct freq_constraints *qos,309int freq_qos_add_notifier(struct freq_constraints *qos,
296 enum freq_qos_req_type type,310 enum freq_qos_req_type type,
kernel/power/qos.c+3−1
@@ -714,8 +714,10 @@ s32 freq_qos_read_value(struct freq_constraints *qos, · 713 unmodified lines
714 * @req: Constraint request to apply.714 * @req: Constraint request to apply.
715 * @action: Action to perform (add/update/remove).715 * @action: Action to perform (add/update/remove).
716 * @value: Value to assign to the QoS request.716 * @value: Value to assign to the QoS request.
717 *
718 * This is only meant to be called from inside pm_qos, not drivers.
717 */719 */
718static int freq_qos_apply(struct freq_qos_request *req,720int freq_qos_apply(struct freq_qos_request *req,
719 enum pm_qos_req_action action, s32 value)721 enum pm_qos_req_action action, s32 value)
720{722{
721 int ret;723 int ret;

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