2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/queue.h>
43 #include <sys/sysctl.h>
44 #include <sys/msgport2.h>
45 #include <sys/cpu_topology.h>
47 #include <net/netisr2.h>
48 #include <net/netmsg2.h>
49 #include <net/if_var.h>
54 #include "acpi_cpu_pstate.h"
56 #define ACPI_NPSTATE_MAX 32
58 #define ACPI_PSS_PX_NENTRY 6
60 #define ACPI_PSD_COORD_SWALL 0xfc
61 #define ACPI_PSD_COORD_SWANY 0xfd
62 #define ACPI_PSD_COORD_HWALL 0xfe
63 #define ACPI_PSD_COORD_VALID(coord) \
64 ((coord) == ACPI_PSD_COORD_SWALL || \
65 (coord) == ACPI_PSD_COORD_SWANY || \
66 (coord) == ACPI_PSD_COORD_HWALL)
68 struct acpi_pst_softc;
69 LIST_HEAD(acpi_pst_list, acpi_pst_softc);
71 struct netmsg_acpi_pst {
72 struct netmsg_base base;
73 const struct acpi_pst_res *ctrl;
74 const struct acpi_pst_res *status;
77 struct acpi_pst_domain {
81 LIST_ENTRY(acpi_pst_domain) pd_link;
85 struct lwkt_serialize pd_serialize;
88 struct acpi_pst_list pd_pstlist;
90 struct sysctl_ctx_list pd_sysctl_ctx;
91 struct sysctl_oid *pd_sysctl_tree;
93 LIST_HEAD(acpi_pst_domlist, acpi_pst_domain);
95 #define ACPI_PSTDOM_FLAG_STUB 0x1 /* stub domain, no _PSD */
96 #define ACPI_PSTDOM_FLAG_DEAD 0x2 /* domain can't be started */
97 #define ACPI_PSTDOM_FLAG_INT 0x4 /* domain created from Integer _PSD */
99 struct acpi_pst_softc {
101 struct acpi_cpu_softc *pst_parent;
102 struct acpi_pst_domain *pst_domain;
103 struct acpi_pst_res pst_creg;
104 struct acpi_pst_res pst_sreg;
111 ACPI_HANDLE pst_handle;
113 LIST_ENTRY(acpi_pst_softc) pst_link;
116 #define ACPI_PST_FLAG_PPC 0x1
117 #define ACPI_PST_FLAG_PDL 0x2
119 static int acpi_pst_probe(device_t dev);
120 static int acpi_pst_attach(device_t dev);
121 static void acpi_pst_notify(device_t dev);
123 static void acpi_pst_postattach(void *);
124 static struct acpi_pst_domain *
125 acpi_pst_domain_create_int(device_t, uint32_t);
126 static struct acpi_pst_domain *
127 acpi_pst_domain_create_pkg(device_t, ACPI_OBJECT *);
128 static struct acpi_pst_domain *
129 acpi_pst_domain_find(uint32_t);
130 static struct acpi_pst_domain *
131 acpi_pst_domain_alloc(uint32_t, uint32_t, uint32_t);
132 static void acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *,
134 static void acpi_pst_domain_set_pstate(struct acpi_pst_domain *, int,
136 static void acpi_pst_domain_check_nproc(device_t, struct acpi_pst_domain *);
137 static void acpi_pst_global_set_pstate(int);
138 static void acpi_pst_global_fixup_pstate(void);
140 static int acpi_pst_check_csr(struct acpi_pst_softc *);
141 static int acpi_pst_check_pstates(struct acpi_pst_softc *);
142 static int acpi_pst_init(struct acpi_pst_softc *);
143 static int acpi_pst_set_pstate(struct acpi_pst_softc *,
144 const struct acpi_pstate *);
145 static const struct acpi_pstate *
146 acpi_pst_get_pstate(struct acpi_pst_softc *);
147 static int acpi_pst_alloc_resource(device_t, ACPI_OBJECT *, int,
148 struct acpi_pst_res *);
149 static int acpi_pst_eval_ppc(struct acpi_pst_softc *, int *);
150 static int acpi_pst_eval_pdl(struct acpi_pst_softc *, int *);
152 static void acpi_pst_check_csr_handler(netmsg_t);
153 static void acpi_pst_check_pstates_handler(netmsg_t);
154 static void acpi_pst_init_handler(netmsg_t);
155 static void acpi_pst_set_pstate_handler(netmsg_t);
156 static void acpi_pst_get_pstate_handler(netmsg_t);
158 static int acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS);
159 static int acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS);
160 static int acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS);
161 static int acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS);
162 static int acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS);
163 static int acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS);
165 static struct acpi_pst_domlist acpi_pst_domains =
166 LIST_HEAD_INITIALIZER(acpi_pst_domains);
167 static int acpi_pst_domain_id;
169 static int acpi_pst_global_state;
171 static int acpi_pstate_start = -1;
172 static int acpi_pstate_count;
173 static int acpi_npstates;
174 static struct acpi_pstate *acpi_pstates;
176 static const struct acpi_pst_md *acpi_pst_md;
178 static int acpi_pst_pdl = -1;
179 TUNABLE_INT("hw.acpi.cpu.pst.pdl", &acpi_pst_pdl);
181 static int acpi_pst_ht_reuse_domain = 1;
182 TUNABLE_INT("hw.acpi.cpu.pst.ht_reuse_domain", &acpi_pst_ht_reuse_domain);
184 static int acpi_pst_force_pkg_domain = 0;
185 TUNABLE_INT("hw.acpi.cpu.pst.force_pkg_domain", &acpi_pst_force_pkg_domain);
187 static int acpi_pst_handle_notify = 1;
188 TUNABLE_INT("hw.acpi.cpu.pst.handle_notify", &acpi_pst_handle_notify);
191 * Force CPU package power domain for Intel CPUs.
193 * As of this write (14 July 2015), all Intel CPUs only have CPU package
196 static int acpi_pst_intel_pkg_domain = 1;
197 TUNABLE_INT("hw.acpi.cpu.pst.intel_pkg_domain", &acpi_pst_intel_pkg_domain);
199 static device_method_t acpi_pst_methods[] = {
200 /* Device interface */
201 DEVMETHOD(device_probe, acpi_pst_probe),
202 DEVMETHOD(device_attach, acpi_pst_attach),
203 DEVMETHOD(device_detach, bus_generic_detach),
204 DEVMETHOD(device_shutdown, bus_generic_shutdown),
205 DEVMETHOD(device_suspend, bus_generic_suspend),
206 DEVMETHOD(device_resume, bus_generic_resume),
209 DEVMETHOD(bus_add_child, bus_generic_add_child),
210 DEVMETHOD(bus_print_child, bus_generic_print_child),
211 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
212 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
213 DEVMETHOD(bus_get_resource_list, bus_generic_get_resource_list),
214 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
215 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
216 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
217 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
218 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
219 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
220 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
221 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
222 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
227 static driver_t acpi_pst_driver = {
230 sizeof(struct acpi_pst_softc)
233 static devclass_t acpi_pst_devclass;
234 DRIVER_MODULE(cpu_pst, cpu, acpi_pst_driver, acpi_pst_devclass, NULL, NULL);
235 MODULE_DEPEND(cpu_pst, acpi, 1, 1, 1);
238 acpi_pst_freq2index(int freq)
242 for (i = 0; i < acpi_npstates; ++i) {
243 if (acpi_pstates[i].st_freq == freq)
250 acpi_pst_probe(device_t dev)
257 if (acpi_disabled("cpu_pst") ||
258 acpi_get_type(dev) != ACPI_TYPE_PROCESSOR)
261 if (acpi_pst_md == NULL)
262 acpi_pst_md = acpi_pst_md_probe();
264 handle = acpi_get_handle(dev);
270 * Some BIOSes do not expose _PCT for the second thread of
271 * CPU cores. In this case, _PSD should be enough to get the
272 * P-state of the second thread working, since it must have
273 * the same _PCT and _PSS as the first thread in the same
277 buf.Length = ACPI_ALLOCATE_BUFFER;
278 status = AcpiEvaluateObject(handle, "_PSD", NULL, &buf);
279 if (!ACPI_FAILURE(status)) {
280 AcpiOsFree((ACPI_OBJECT *)buf.Pointer);
288 buf.Length = ACPI_ALLOCATE_BUFFER;
289 status = AcpiEvaluateObject(handle, "_PCT", NULL, &buf);
290 if (ACPI_FAILURE(status)) {
292 device_printf(dev, "Can't get _PCT package - %s\n",
293 AcpiFormatException(status));
298 obj = (ACPI_OBJECT *)buf.Pointer;
299 if (!ACPI_PKG_VALID_EQ(obj, 2)) {
300 device_printf(dev, "Invalid _PCT package\n");
310 buf.Length = ACPI_ALLOCATE_BUFFER;
311 status = AcpiEvaluateObject(handle, "_PSS", NULL, &buf);
312 if (ACPI_FAILURE(status)) {
313 device_printf(dev, "Can't get _PSS package - %s\n",
314 AcpiFormatException(status));
318 obj = (ACPI_OBJECT *)buf.Pointer;
319 if (!ACPI_PKG_VALID(obj, 1)) {
320 device_printf(dev, "Invalid _PSS package\n");
327 device_set_desc(dev, "ACPI CPU P-State");
332 acpi_pst_attach(device_t dev)
334 struct acpi_pst_softc *sc = device_get_softc(dev);
335 struct acpi_pst_domain *dom = NULL;
339 struct acpi_pstate *pstate, *p;
340 int i, npstate, error, sstart, scount;
343 sc->pst_parent = device_get_softc(device_get_parent(dev));
344 sc->pst_handle = acpi_get_handle(dev);
345 sc->pst_cpuid = acpi_get_magic(dev);
348 * If there is a _PSD, then we create procossor domain
349 * accordingly. If there is no _PSD, we just fake a
350 * default processor domain0.
353 buf.Length = ACPI_ALLOCATE_BUFFER;
354 status = AcpiEvaluateObject(sc->pst_handle, "_PSD", NULL, &buf);
355 if (!ACPI_FAILURE(status)) {
356 obj = (ACPI_OBJECT *)buf.Pointer;
358 if (acpi_pst_domain_id > 0) {
359 device_printf(dev, "Missing _PSD for certain CPUs\n");
363 acpi_pst_domain_id = -1;
365 if (ACPI_PKG_VALID_EQ(obj, 1)) {
366 dom = acpi_pst_domain_create_pkg(dev,
367 &obj->Package.Elements[0]);
373 if (obj->Type != ACPI_TYPE_INTEGER) {
375 "Invalid _PSD package, Type 0x%x\n",
380 device_printf(dev, "Integer _PSD %ju\n",
381 (uintmax_t)obj->Integer.Value);
382 dom = acpi_pst_domain_create_int(dev,
392 AcpiOsFree(buf.Pointer);
394 if (acpi_pst_domain_id < 0) {
395 device_printf(dev, "Missing _PSD for cpu%d\n",
401 * Create a stub one processor domain for each processor
403 dom = acpi_pst_domain_alloc(acpi_pst_domain_id,
404 ACPI_PSD_COORD_SWANY, 1);
405 dom->pd_flags |= ACPI_PSTDOM_FLAG_STUB;
407 ++acpi_pst_domain_id;
410 /* Make sure that adding us will not overflow our domain */
411 acpi_pst_domain_check_nproc(dev, dom);
414 * Get control/status registers from _PCT
417 buf.Length = ACPI_ALLOCATE_BUFFER;
418 status = AcpiEvaluateObject(sc->pst_handle, "_PCT", NULL, &buf);
419 if (ACPI_FAILURE(status)) {
420 struct acpi_pst_softc *pst;
423 * No _PCT. See the comment in acpi_pst_probe() near
426 * Use control/status registers of another CPU in the
427 * same domain, or in the same core, if the type of
428 * these registers are "Fixed Hardware", e.g. on most
429 * of the model Intel CPUs.
431 pst = LIST_FIRST(&dom->pd_pstlist);
435 mask = get_cpumask_from_level(sc->pst_cpuid,
437 if (CPUMASK_TESTNZERO(mask)) {
438 struct acpi_pst_domain *dom1;
440 LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) {
441 LIST_FOREACH(pst, &dom1->pd_pstlist,
443 if (CPUMASK_TESTBIT(mask,
450 if (pst != NULL && acpi_pst_ht_reuse_domain) {
452 * Use the same domain for CPUs in the
455 device_printf(dev, "Destroy domain%u, "
457 dom->pd_dom, dom1->pd_dom);
458 LIST_REMOVE(dom, pd_link);
459 kfree(dom, M_DEVBUF);
462 * Make sure that adding us will not
463 * overflow the domain containing
464 * siblings in the same core.
466 acpi_pst_domain_check_nproc(dev, dom);
471 pst->pst_creg.pr_res == NULL &&
472 pst->pst_creg.pr_rid == 0 &&
473 pst->pst_creg.pr_gas.SpaceId ==
474 ACPI_ADR_SPACE_FIXED_HARDWARE &&
475 pst->pst_sreg.pr_res == NULL &&
476 pst->pst_sreg.pr_rid == 0 &&
477 pst->pst_sreg.pr_gas.SpaceId ==
478 ACPI_ADR_SPACE_FIXED_HARDWARE) {
479 sc->pst_creg = pst->pst_creg;
480 sc->pst_sreg = pst->pst_sreg;
482 "No _PCT; reuse %s control/status regs\n",
483 device_get_nameunit(pst->pst_dev));
486 device_printf(dev, "Can't get _PCT package - %s\n",
487 AcpiFormatException(status));
491 obj = (ACPI_OBJECT *)buf.Pointer;
492 if (!ACPI_PKG_VALID_EQ(obj, 2)) {
493 device_printf(dev, "Invalid _PCT package\n");
498 /* Save and try allocating control register */
499 error = acpi_pst_alloc_resource(dev, obj, 0, &sc->pst_creg);
505 device_printf(dev, "control reg %d %jx\n",
506 sc->pst_creg.pr_gas.SpaceId,
507 (uintmax_t)sc->pst_creg.pr_gas.Address);
510 /* Save and try allocating status register */
511 error = acpi_pst_alloc_resource(dev, obj, 1, &sc->pst_sreg);
517 device_printf(dev, "status reg %d %jx\n",
518 sc->pst_sreg.pr_gas.SpaceId,
519 (uintmax_t)sc->pst_sreg.pr_gas.Address);
527 * Create P-State table according to _PSS
530 buf.Length = ACPI_ALLOCATE_BUFFER;
531 status = AcpiEvaluateObject(sc->pst_handle, "_PSS", NULL, &buf);
532 if (ACPI_FAILURE(status)) {
534 * No _PSS. See the comment in acpi_pst_probe() near
537 * Assume _PSS are same across all CPUs; well, they
538 * should/have to be so.
540 if (acpi_npstates > 0 && acpi_pstates != NULL) {
541 device_printf(dev, "No _PSS\n");
544 device_printf(dev, "Can't get _PSS package - %s\n",
545 AcpiFormatException(status));
549 obj = (ACPI_OBJECT *)buf.Pointer;
550 if (!ACPI_PKG_VALID(obj, 1)) {
551 device_printf(dev, "Invalid _PSS package\n");
556 /* Don't create too many P-States */
557 npstate = obj->Package.Count;
558 if (npstate > ACPI_NPSTATE_MAX) {
559 device_printf(dev, "Too many P-States, %d->%d\n",
560 npstate, ACPI_NPSTATE_MAX);
561 npstate = ACPI_NPSTATE_MAX;
565 * If we have already created P-State table,
566 * we must make sure that number of entries
569 if (acpi_pstates != NULL && acpi_npstates != npstate) {
570 device_printf(dev, "Inconsistent # of P-States "
571 "cross Processor objects\n");
577 * Create a temporary P-State table
579 pstate = kmalloc(sizeof(*pstate) * npstate, M_TEMP, M_WAITOK);
580 for (i = 0, p = pstate; i < npstate; ++i, ++p) {
582 uint32_t *ptr[ACPI_PSS_PX_NENTRY] = {
583 &p->st_freq, &p->st_power, &p->st_xsit_lat,
584 &p->st_bm_lat, &p->st_cval, &p->st_sval
588 pkg = &obj->Package.Elements[i];
589 if (!ACPI_PKG_VALID(pkg, ACPI_PSS_PX_NENTRY)) {
590 device_printf(dev, "Invalud _PSS P%d\n", i);
592 kfree(pstate, M_TEMP);
595 for (j = 0; j < ACPI_PSS_PX_NENTRY; ++j) {
596 if (acpi_PkgInt32(pkg, j, ptr[j]) != 0) {
597 device_printf(dev, "Can't extract "
598 "_PSS P%d %dth entry\n", i, j);
600 kfree(pstate, M_TEMP);
609 if (acpi_pstates == NULL) {
611 * If no P-State table is created yet,
612 * save the temporary one we just created.
614 acpi_pstates = pstate;
615 acpi_npstates = npstate;
619 for (i = 0; i < acpi_npstates; ++i) {
621 "freq %u, pwr %u, xlat %u, blat %u, "
622 "cv %08x, sv %08x\n",
623 acpi_pstates[i].st_freq,
624 acpi_pstates[i].st_power,
625 acpi_pstates[i].st_xsit_lat,
626 acpi_pstates[i].st_bm_lat,
627 acpi_pstates[i].st_cval,
628 acpi_pstates[i].st_sval);
633 * Make sure that P-State tables are same
634 * for all processors.
636 if (memcmp(pstate, acpi_pstates,
637 sizeof(*pstate) * npstate) != 0) {
638 device_printf(dev, "Inconsistent _PSS "
639 "cross Processor objects\n");
642 * Some BIOSes create different P-State tables;
643 * just trust the one from the BSP and move on.
645 kfree(pstate, M_TEMP);
649 kfree(pstate, M_TEMP);
653 /* By default, we start from P-State table's first entry */
657 * Adjust the usable first entry of P-State table,
658 * if there is _PPC object.
660 error = acpi_pst_eval_ppc(sc, &sstart);
661 if (error && error != ENOENT)
664 sc->pst_flags |= ACPI_PST_FLAG_PPC;
665 if (acpi_pstate_start < 0) {
666 acpi_pstate_start = sstart;
667 } else if (acpi_pstate_start != sstart) {
668 device_printf(dev, "_PPC mismatch, was %d, now %d\n",
669 acpi_pstate_start, sstart);
670 if (acpi_pstate_start < sstart) {
671 device_printf(dev, "_PPC %d -> %d\n",
672 acpi_pstate_start, sstart);
673 acpi_pstate_start = sstart;
678 * By default, we assume number of usable P-States is same as
679 * number of P-States.
681 scount = acpi_npstates;
684 * Allow users to override or set _PDL
686 if (acpi_pst_pdl >= 0) {
687 if (acpi_pst_pdl < acpi_npstates) {
689 device_printf(dev, "_PDL override %d\n",
692 scount = acpi_pst_pdl + 1;
695 device_printf(dev, "Invalid _PDL override %d, "
696 "must be less than %d\n", acpi_pst_pdl,
702 * Adjust the number of usable entries in P-State table,
703 * if there is _PDL object.
705 error = acpi_pst_eval_pdl(sc, &scount);
706 if (error && error != ENOENT)
709 sc->pst_flags |= ACPI_PST_FLAG_PDL;
711 if (acpi_pstate_count == 0) {
712 acpi_pstate_count = scount;
713 } else if (acpi_pstate_count != scount) {
714 device_printf(dev, "_PDL mismatch, was %d, now %d\n",
715 acpi_pstate_count, scount);
716 if (acpi_pstate_count > scount) {
717 device_printf(dev, "_PDL %d -> %d\n",
718 acpi_pstate_count, scount);
719 acpi_pstate_count = scount;
724 * Some CPUs only have package P-states, but some BIOSes put each
725 * hyperthread to its own P-state domain; allow user to override.
727 if (LIST_EMPTY(&dom->pd_pstlist) &&
728 (acpi_pst_force_pkg_domain ||
729 (cpu_vendor_id == CPU_VENDOR_INTEL &&
730 acpi_pst_intel_pkg_domain))) {
733 mask = get_cpumask_from_level(sc->pst_cpuid, CHIP_LEVEL);
734 if (CPUMASK_TESTNZERO(mask)) {
735 struct acpi_pst_softc *pst = NULL;
736 struct acpi_pst_domain *dom1;
738 LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) {
739 LIST_FOREACH(pst, &dom1->pd_pstlist,
741 if (CPUMASK_TESTBIT(mask,
749 memcmp(&pst->pst_creg, &sc->pst_creg,
750 sizeof(sc->pst_creg)) == 0 &&
751 memcmp(&pst->pst_sreg, &sc->pst_sreg,
752 sizeof(sc->pst_sreg)) == 0) {
754 * Use the same domain for CPUs in the
757 device_printf(dev, "Destroy domain%u, "
758 "force pkg domain%u\n",
759 dom->pd_dom, dom1->pd_dom);
760 LIST_REMOVE(dom, pd_link);
761 kfree(dom, M_DEVBUF);
764 * Make sure that adding us will not
765 * overflow the domain containing
766 * siblings in the same package.
768 acpi_pst_domain_check_nproc(dev, dom);
773 /* Link us with the domain */
774 sc->pst_domain = dom;
775 LIST_INSERT_HEAD(&dom->pd_pstlist, sc, pst_link);
777 if (device_get_unit(dev) == 0)
778 AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_pst_postattach, NULL);
780 if (sc->pst_flags & (ACPI_PST_FLAG_PPC | ACPI_PST_FLAG_PDL))
781 sc->pst_parent->cpu_pst_notify = acpi_pst_notify;
786 static struct acpi_pst_domain *
787 acpi_pst_domain_create_pkg(device_t dev, ACPI_OBJECT *obj)
789 struct acpi_pst_domain *dom;
790 uint32_t val, domain, coord, nproc;
792 if (!ACPI_PKG_VALID_EQ(obj, 5)) {
793 device_printf(dev, "Invalid _PSD package\n");
797 /* NumberOfEntries */
798 if (acpi_PkgInt32(obj, 0, &val) != 0 || val != 5) {
799 device_printf(dev, "Invalid _PSD NumberOfEntries\n");
804 if (acpi_PkgInt32(obj, 1, &val) != 0 || val != 0) {
805 device_printf(dev, "Invalid _PSD Revision\n");
809 if (acpi_PkgInt32(obj, 2, &domain) != 0 ||
810 acpi_PkgInt32(obj, 3, &coord) != 0 ||
811 acpi_PkgInt32(obj, 4, &nproc) != 0) {
812 device_printf(dev, "Can't extract _PSD package\n");
816 if (!ACPI_PSD_COORD_VALID(coord)) {
817 device_printf(dev, "Invalid _PSD CoordType (%#x)\n", coord);
821 if (nproc > MAXCPU) {
823 * If NumProcessors is greater than MAXCPU
824 * and domain's coordination is SWALL, then
825 * we will never be able to start all CPUs
826 * within this domain, and power state
827 * transition will never be completed, so we
828 * just bail out here.
830 if (coord == ACPI_PSD_COORD_SWALL) {
831 device_printf(dev, "Unsupported _PSD NumProcessors "
835 } else if (nproc == 0) {
836 device_printf(dev, "_PSD NumProcessors are zero\n");
840 dom = acpi_pst_domain_find(domain);
842 if (dom->pd_flags & ACPI_PSTDOM_FLAG_INT) {
843 device_printf(dev, "Mixed Integer _PSD and "
847 if (dom->pd_coord != coord) {
848 device_printf(dev, "Inconsistent _PSD coord "
849 "information cross Processor objects\n");
852 if (dom->pd_nproc != nproc) {
853 device_printf(dev, "Inconsistent _PSD nproc "
854 "information cross Processor objects\n");
856 * Some stupid BIOSes will set wrong "# of processors",
857 * e.g. 1 for CPU w/ hyperthreading; Be lenient here.
863 dom = acpi_pst_domain_alloc(domain, coord, nproc);
865 device_printf(dev, "create pkg domain%u, coord %#x\n",
866 dom->pd_dom, dom->pd_coord);
872 static struct acpi_pst_domain *
873 acpi_pst_domain_create_int(device_t dev, uint32_t domain)
875 struct acpi_pst_domain *dom;
877 dom = acpi_pst_domain_find(domain);
879 if ((dom->pd_flags & ACPI_PSTDOM_FLAG_INT) == 0) {
880 device_printf(dev, "Mixed Package _PSD and "
884 KKASSERT(dom->pd_coord == ACPI_PSD_COORD_SWALL);
890 dom = acpi_pst_domain_alloc(domain, ACPI_PSD_COORD_SWALL, 1);
891 dom->pd_flags |= ACPI_PSTDOM_FLAG_INT;
894 device_printf(dev, "create int domain%u\n", dom->pd_dom);
899 static struct acpi_pst_domain *
900 acpi_pst_domain_find(uint32_t domain)
902 struct acpi_pst_domain *dom;
904 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
905 if (dom->pd_flags & ACPI_PSTDOM_FLAG_STUB)
907 if (dom->pd_dom == domain)
913 static struct acpi_pst_domain *
914 acpi_pst_domain_alloc(uint32_t domain, uint32_t coord, uint32_t nproc)
916 struct acpi_pst_domain *dom;
918 dom = kmalloc(sizeof(*dom), M_DEVBUF, M_WAITOK | M_ZERO);
919 dom->pd_dom = domain;
920 dom->pd_coord = coord;
921 dom->pd_nproc = nproc;
922 LIST_INIT(&dom->pd_pstlist);
923 lwkt_serialize_init(&dom->pd_serialize);
925 LIST_INSERT_HEAD(&acpi_pst_domains, dom, pd_link);
931 acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *dom, int i, int *global)
933 const struct acpi_pstate *pstate;
934 struct acpi_pst_softc *sc;
937 ASSERT_SERIALIZED(&dom->pd_serialize);
939 KKASSERT(i >= 0 && i < acpi_npstates);
940 pstate = &acpi_pstates[i];
943 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
945 error = acpi_pst_set_pstate(sc, pstate);
947 device_printf(sc->pst_dev, "can't set "
948 "freq %d\n", pstate->st_freq);
949 /* XXX error cleanup? */
951 if (dom->pd_coord == ACPI_PSD_COORD_SWANY)
963 acpi_pst_domain_set_pstate(struct acpi_pst_domain *dom, int i, int *global)
965 lwkt_serialize_enter(&dom->pd_serialize);
966 acpi_pst_domain_set_pstate_locked(dom, i, global);
967 lwkt_serialize_exit(&dom->pd_serialize);
971 acpi_pst_global_set_pstate(int i)
973 struct acpi_pst_domain *dom;
974 int *global = &acpi_pst_global_state;
976 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
977 /* Skip dead domain */
978 if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD)
980 acpi_pst_domain_set_pstate(dom, i, global);
986 acpi_pst_global_fixup_pstate(void)
988 struct acpi_pst_domain *dom;
989 int *global = &acpi_pst_global_state;
992 sstart = acpi_pstate_start;
993 scount = acpi_pstate_count;
995 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
998 /* Skip dead domain */
999 if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD)
1002 lwkt_serialize_enter(&dom->pd_serialize);
1004 if (global != NULL) {
1005 if (*global < sstart)
1007 else if (*global >= scount)
1008 *global = scount - 1;
1011 if (dom->pd_state < sstart)
1013 else if (dom->pd_state >= scount)
1016 acpi_pst_domain_set_pstate_locked(dom, i, NULL);
1018 lwkt_serialize_exit(&dom->pd_serialize);
1023 acpi_pst_postattach(void *arg __unused)
1025 struct acpi_pst_domain *dom;
1026 struct acpi_cpu_softc *cpu;
1028 int i, ndevices, error, has_domain;
1032 error = devclass_get_devices(acpi_pst_devclass, &devices, &ndevices);
1040 for (i = 0; i < ndevices; ++i) {
1041 cpu = device_get_softc(device_get_parent(devices[i]));
1042 if (cpu->glob_sysctl_tree != NULL)
1045 kfree(devices, M_TEMP);
1046 KKASSERT(cpu != NULL);
1048 if (acpi_pst_md == NULL)
1049 kprintf("ACPI: no P-State CPU driver\n");
1052 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
1053 struct acpi_pst_softc *sc;
1056 dom->pd_state = acpi_pstate_start;
1059 * Make sure that all processors belonging to this
1060 * domain are located.
1063 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1064 sc->pst_state = acpi_pstate_start;
1067 if (i != dom->pd_nproc) {
1068 KKASSERT(i < dom->pd_nproc);
1070 kprintf("ACPI: domain%u misses processors, "
1071 "should be %d, got %d\n", dom->pd_dom,
1073 if (dom->pd_coord == ACPI_PSD_COORD_SWALL) {
1075 * If this domain's coordination is
1076 * SWALL and we don't see all of the
1077 * member CPUs of this domain, then
1078 * the P-State transition will never
1079 * be completed, so just leave this
1082 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1089 * Validate P-State configurations for this domain
1091 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1092 error = acpi_pst_check_csr(sc);
1096 error = acpi_pst_check_pstates(sc);
1101 kprintf("ACPI: domain%u P-State configuration "
1102 "check failed\n", dom->pd_dom);
1103 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1108 * Do necssary P-State initialization
1110 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1111 error = acpi_pst_init(sc);
1116 kprintf("ACPI: domain%u P-State initialization "
1117 "check failed\n", dom->pd_dom);
1118 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1124 ksnprintf(buf, sizeof(buf), "px_dom%u", dom->pd_dom);
1126 sysctl_ctx_init(&dom->pd_sysctl_ctx);
1127 dom->pd_sysctl_tree =
1128 SYSCTL_ADD_NODE(&dom->pd_sysctl_ctx,
1129 SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1130 OID_AUTO, buf, CTLFLAG_RD, 0,
1132 if (dom->pd_sysctl_tree == NULL) {
1133 kprintf("ACPI: Can't create sysctl tree for domain%u",
1138 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1139 SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1140 OID_AUTO, "available",
1141 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP,
1142 dom, 0, acpi_pst_sysctl_freqs, "A",
1143 "available frequencies");
1145 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1146 SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1148 CTLTYPE_OPAQUE | CTLFLAG_RD,
1149 dom, 0, acpi_pst_sysctl_freqs_bin, "IU",
1150 "available frequencies");
1152 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1153 SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1155 CTLTYPE_OPAQUE | CTLFLAG_RD,
1156 dom, 0, acpi_pst_sysctl_power, "IU",
1157 "power of available frequencies");
1159 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1160 SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1161 OID_AUTO, "members",
1162 CTLTYPE_STRING | CTLFLAG_RD,
1163 dom, 0, acpi_pst_sysctl_members, "A",
1166 if (acpi_pst_md != NULL &&
1167 acpi_pst_md->pmd_set_pstate != NULL) {
1168 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1169 SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1171 CTLTYPE_UINT | CTLFLAG_RW,
1172 dom, 0, acpi_pst_sysctl_select,
1173 "IU", "select freq");
1177 if (has_domain && acpi_pst_md != NULL &&
1178 acpi_pst_md->pmd_set_pstate != NULL) {
1179 SYSCTL_ADD_PROC(&cpu->glob_sysctl_ctx,
1180 SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1181 OID_AUTO, "px_global",
1182 CTLTYPE_UINT | CTLFLAG_RW,
1183 NULL, 0, acpi_pst_sysctl_global,
1184 "IU", "select freq for all domains");
1185 SYSCTL_ADD_INT(&cpu->glob_sysctl_ctx,
1186 SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1187 OID_AUTO, "px_handle_notify", CTLFLAG_RW,
1188 &acpi_pst_handle_notify, 0,
1189 "handle type 0x80 notify");
1191 acpi_pst_global_set_pstate(acpi_pstate_start);
1196 acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS)
1198 int i, error, sstart, scount;
1201 sstart = acpi_pstate_start;
1202 scount = acpi_pstate_count;
1203 for (i = 0; i < acpi_npstates; ++i) {
1204 if (error == 0 && i)
1205 error = SYSCTL_OUT(req, " ", 1);
1210 if (i < sstart || i >= scount)
1215 ksnprintf(buf, sizeof(buf), pat,
1216 acpi_pstates[i].st_freq);
1217 error = SYSCTL_OUT(req, buf, strlen(buf));
1224 acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS)
1226 uint32_t freqs[ACPI_NPSTATE_MAX];
1227 int cnt, i, sstart, scount;
1229 sstart = acpi_pstate_start;
1230 scount = acpi_pstate_count;
1232 cnt = scount - sstart;
1233 for (i = 0; i < cnt; ++i)
1234 freqs[i] = acpi_pstates[sstart + i].st_freq;
1236 return sysctl_handle_opaque(oidp, freqs, cnt * sizeof(freqs[0]), req);
1240 acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS)
1242 uint32_t power[ACPI_NPSTATE_MAX];
1243 int cnt, i, sstart, scount;
1245 sstart = acpi_pstate_start;
1246 scount = acpi_pstate_count;
1248 cnt = scount - sstart;
1249 for (i = 0; i < cnt; ++i)
1250 power[i] = acpi_pstates[sstart + i].st_power;
1252 return sysctl_handle_opaque(oidp, power, cnt * sizeof(power[0]), req);
1256 acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS)
1258 struct acpi_pst_domain *dom = arg1;
1259 struct acpi_pst_softc *sc;
1263 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1266 if (error == 0 && loop)
1267 error = SYSCTL_OUT(req, " ", 1);
1269 ksnprintf(buf, sizeof(buf), "cpu%d", sc->pst_cpuid);
1270 error = SYSCTL_OUT(req, buf, strlen(buf));
1273 if (error == 0 && acpi_pst_md && acpi_pst_md->pmd_get_pstate) {
1274 const struct acpi_pstate *pstate;
1277 pstate = acpi_pst_get_pstate(sc);
1278 if (pstate == NULL) {
1281 ksnprintf(buf, sizeof(buf), "(%d)",
1285 error = SYSCTL_OUT(req, str, strlen(str));
1293 acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS)
1295 struct acpi_pst_domain *dom = arg1;
1298 KKASSERT(dom->pd_state >= 0 && dom->pd_state < acpi_npstates);
1300 freq = acpi_pstates[dom->pd_state].st_freq;
1302 error = sysctl_handle_int(oidp, &freq, 0, req);
1303 if (error || req->newptr == NULL)
1306 i = acpi_pst_freq2index(freq);
1310 acpi_pst_domain_set_pstate(dom, i, NULL);
1315 acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS)
1319 KKASSERT(acpi_pst_global_state >= 0 &&
1320 acpi_pst_global_state < acpi_npstates);
1322 freq = acpi_pstates[acpi_pst_global_state].st_freq;
1324 error = sysctl_handle_int(oidp, &freq, 0, req);
1325 if (error || req->newptr == NULL)
1328 i = acpi_pst_freq2index(freq);
1332 acpi_pst_global_set_pstate(i);
1338 acpi_pst_check_csr_handler(netmsg_t msg)
1340 struct netmsg_acpi_pst *rmsg = (struct netmsg_acpi_pst *)msg;
1343 error = acpi_pst_md->pmd_check_csr(rmsg->ctrl, rmsg->status);
1344 lwkt_replymsg(&rmsg->base.lmsg, error);
1348 acpi_pst_check_csr(struct acpi_pst_softc *sc)
1350 struct netmsg_acpi_pst msg;
1352 if (acpi_pst_md == NULL)
1355 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
1356 MSGF_PRIORITY, acpi_pst_check_csr_handler);
1357 msg.ctrl = &sc->pst_creg;
1358 msg.status = &sc->pst_sreg;
1360 return lwkt_domsg(netisr_cpuport(sc->pst_cpuid), &msg.base.lmsg, 0);
1364 acpi_pst_check_pstates_handler(netmsg_t msg)
1368 error = acpi_pst_md->pmd_check_pstates(acpi_pstates, acpi_npstates);
1369 lwkt_replymsg(&msg->lmsg, error);
1373 acpi_pst_check_pstates(struct acpi_pst_softc *sc)
1375 struct netmsg_base msg;
1377 if (acpi_pst_md == NULL)
1380 netmsg_init(&msg, NULL, &curthread->td_msgport,
1381 MSGF_PRIORITY, acpi_pst_check_pstates_handler);
1383 return lwkt_domsg(netisr_cpuport(sc->pst_cpuid), &msg.lmsg, 0);
1387 acpi_pst_init_handler(netmsg_t msg)
1389 struct netmsg_acpi_pst *rmsg = (struct netmsg_acpi_pst *)msg;
1392 error = acpi_pst_md->pmd_init(rmsg->ctrl, rmsg->status);
1393 lwkt_replymsg(&rmsg->base.lmsg, error);
1397 acpi_pst_init(struct acpi_pst_softc *sc)
1399 struct netmsg_acpi_pst msg;
1401 if (acpi_pst_md == NULL)
1404 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
1405 MSGF_PRIORITY, acpi_pst_init_handler);
1406 msg.ctrl = &sc->pst_creg;
1407 msg.status = &sc->pst_sreg;
1409 return lwkt_domsg(netisr_cpuport(sc->pst_cpuid), &msg.base.lmsg, 0);
1413 acpi_pst_set_pstate_handler(netmsg_t msg)
1415 struct netmsg_acpi_pst *rmsg = (struct netmsg_acpi_pst *)msg;
1418 error = acpi_pst_md->pmd_set_pstate(rmsg->ctrl, rmsg->status,
1419 rmsg->base.lmsg.u.ms_resultp);
1420 lwkt_replymsg(&rmsg->base.lmsg, error);
1424 acpi_pst_set_pstate(struct acpi_pst_softc *sc, const struct acpi_pstate *pstate)
1426 struct netmsg_acpi_pst msg;
1428 KKASSERT(acpi_pst_md != NULL);
1430 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
1431 MSGF_PRIORITY, acpi_pst_set_pstate_handler);
1432 msg.base.lmsg.u.ms_resultp = __DECONST(void *, pstate);
1433 msg.ctrl = &sc->pst_creg;
1434 msg.status = &sc->pst_sreg;
1436 return lwkt_domsg(netisr_cpuport(sc->pst_cpuid), &msg.base.lmsg, 0);
1440 acpi_pst_get_pstate_handler(netmsg_t msg)
1442 struct netmsg_acpi_pst *rmsg = (struct netmsg_acpi_pst *)msg;
1443 const struct acpi_pstate *pstate;
1445 pstate = acpi_pst_md->pmd_get_pstate(rmsg->status, acpi_pstates,
1447 rmsg->base.lmsg.u.ms_resultp = __DECONST(void *, pstate);
1448 lwkt_replymsg(&rmsg->base.lmsg, 0);
1451 static const struct acpi_pstate *
1452 acpi_pst_get_pstate(struct acpi_pst_softc *sc)
1454 struct netmsg_acpi_pst msg;
1456 if (acpi_pst_md == NULL)
1459 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
1460 MSGF_PRIORITY, acpi_pst_get_pstate_handler);
1461 msg.status = &sc->pst_sreg;
1463 lwkt_domsg(netisr_cpuport(sc->pst_cpuid), &msg.base.lmsg, 0);
1464 return msg.base.lmsg.u.ms_resultp;
1468 acpi_pst_alloc_resource(device_t dev, ACPI_OBJECT *obj, int idx,
1469 struct acpi_pst_res *res)
1471 struct acpi_pst_softc *sc = device_get_softc(dev);
1475 error = acpi_PkgRawGas(obj, idx, &res->pr_gas);
1479 /* Allocate resource, if possible */
1480 res->pr_rid = sc->pst_parent->cpu_next_rid;
1481 acpi_bus_alloc_gas(dev, &type, &res->pr_rid, &res->pr_gas, &res->pr_res, 0);
1482 if (res->pr_res != NULL) {
1483 sc->pst_parent->cpu_next_rid++;
1484 res->pr_bt = rman_get_bustag(res->pr_res);
1485 res->pr_bh = rman_get_bushandle(res->pr_res);
1493 acpi_pst_domain_check_nproc(device_t dev, struct acpi_pst_domain *dom)
1495 struct acpi_pst_softc *pst;
1499 LIST_FOREACH(pst, &dom->pd_pstlist, pst_link)
1501 if (i == dom->pd_nproc) {
1503 * Some stupid BIOSes will set wrong "# of processors",
1504 * e.g. 1 for CPU w/ hyperthreading; Be lenient here.
1507 device_printf(dev, "domain%u already contains %d "
1508 "P-States\n", dom->pd_dom, dom->pd_nproc);
1512 KKASSERT(i < dom->pd_nproc);
1516 acpi_pst_eval_ppc(struct acpi_pst_softc *sc, int *sstart)
1523 buf.Length = ACPI_ALLOCATE_BUFFER;
1524 status = AcpiEvaluateObject(sc->pst_handle, "_PPC", NULL, &buf);
1525 if (!ACPI_FAILURE(status)) {
1526 ACPI_OBJECT_LIST arglist;
1529 obj = (ACPI_OBJECT *)buf.Pointer;
1530 if (obj->Type == ACPI_TYPE_INTEGER) {
1531 if (obj->Integer.Value >= acpi_npstates) {
1532 device_printf(sc->pst_dev,
1533 "Invalid _PPC value\n");
1537 *sstart = obj->Integer.Value;
1539 device_printf(sc->pst_dev, "_PPC %d\n",
1543 device_printf(sc->pst_dev, "Invalid _PPC object\n");
1551 /* _PPC has been successfully processed */
1552 arglist.Pointer = arg;
1554 arg[0].Type = ACPI_TYPE_INTEGER;
1555 arg[0].Integer.Value = 0x80;
1556 arg[1].Type = ACPI_TYPE_INTEGER;
1557 arg[1].Integer.Value = 0;
1558 AcpiEvaluateObject(sc->pst_handle, "_OST", &arglist, NULL);
1566 acpi_pst_eval_pdl(struct acpi_pst_softc *sc, int *scount)
1573 buf.Length = ACPI_ALLOCATE_BUFFER;
1574 status = AcpiEvaluateObject(sc->pst_handle, "_PDL", NULL, &buf);
1575 if (!ACPI_FAILURE(status)) {
1576 obj = (ACPI_OBJECT *)buf.Pointer;
1577 if (obj->Type == ACPI_TYPE_INTEGER) {
1578 if (obj->Integer.Value >= acpi_npstates) {
1579 device_printf(sc->pst_dev,
1580 "Invalid _PDL value\n");
1584 if (obj->Integer.Value >= acpi_pstate_start) {
1585 *scount = obj->Integer.Value + 1;
1587 device_printf(sc->pst_dev, "_PDL %d\n",
1591 /* Prefer _PPC as stated in ACPI 5.1 8.4.4.6 */
1592 device_printf(sc->pst_dev, "conflict _PDL %ju "
1593 "and _PPC %d, ignore\n",
1594 (uintmax_t)obj->Integer.Value,
1598 device_printf(sc->pst_dev, "Invalid _PDL object\n");
1612 * Notify is serialized by acpi task thread.
1615 acpi_pst_notify(device_t dev)
1617 struct acpi_pst_softc *sc = device_get_softc(dev);
1618 boolean_t fixup = FALSE;
1620 if (!acpi_pst_handle_notify)
1625 * _PPC and _PDL evaluation order is critical. _PDL
1626 * evaluation depends on _PPC evaluation.
1628 if (sc->pst_flags & ACPI_PST_FLAG_PPC) {
1629 int sstart = acpi_pstate_start;
1631 acpi_pst_eval_ppc(sc, &sstart);
1632 if (acpi_pstate_start != sstart && sc->pst_cpuid == 0) {
1633 acpi_pstate_start = sstart;
1637 if (sc->pst_flags & ACPI_PST_FLAG_PDL) {
1638 int scount = acpi_pstate_count;
1640 acpi_pst_eval_pdl(sc, &scount);
1641 if (acpi_pstate_count != scount && sc->pst_cpuid == 0) {
1642 acpi_pstate_count = scount;
1647 if (fixup && acpi_pst_md != NULL &&
1648 acpi_pst_md->pmd_set_pstate != NULL)
1649 acpi_pst_global_fixup_pstate();