Module Name: src Committed By: jruoho Date: Tue Oct 18 05:08:24 UTC 2011
Modified Files: src/sys/arch/x86/acpi: acpi_cpu_md.c src/sys/dev/acpi: acpi_cpu.c acpi_cpu.h acpi_cpu_pstate.c Log Message: Convert to use cpufreq(9). To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/arch/x86/acpi/acpi_cpu_md.c cvs rdiff -u -r1.44 -r1.45 src/sys/dev/acpi/acpi_cpu.c cvs rdiff -u -r1.42 -r1.43 src/sys/dev/acpi/acpi_cpu.h cvs rdiff -u -r1.51 -r1.52 src/sys/dev/acpi/acpi_cpu_pstate.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/acpi/acpi_cpu_md.c diff -u src/sys/arch/x86/acpi/acpi_cpu_md.c:1.67 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.68 --- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.67 Sat Sep 24 19:41:40 2011 +++ src/sys/arch/x86/acpi/acpi_cpu_md.c Tue Oct 18 05:08:24 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_md.c,v 1.67 2011/09/24 19:41:40 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_md.c,v 1.68 2011/10/18 05:08:24 jruoho Exp $ */ /*- * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,10 +27,11 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.67 2011/09/24 19:41:40 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.68 2011/10/18 05:08:24 jruoho Exp $"); #include <sys/param.h> #include <sys/bus.h> +#include <sys/cpufreq.h> #include <sys/device.h> #include <sys/kcore.h> #include <sys/sysctl.h> @@ -749,7 +750,7 @@ acpicpu_md_pstate_get(struct acpicpu_sof /* * Pick any P-state for the status address. - */ + */ for (i = 0; i < sc->sc_pstate_count; i++) { ps = &sc->sc_pstate[i]; @@ -791,6 +792,9 @@ acpicpu_md_pstate_get(struct acpicpu_sof */ if ((sc->sc_flags & ACPICPU_FLAG_P_HWF) != 0) { + KASSERT(sc->sc_pstate_count > 0); + KASSERT(sc->sc_pstate[0].ps_freq != 0); + if (acpicpu_md_pstate_hwf(sc->sc_ci) == 100) { *freq = sc->sc_pstate[0].ps_freq; return 0; @@ -1136,15 +1140,14 @@ fail: static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_ARGS) { - struct cpu_info *ci = curcpu(); struct sysctlnode node; uint32_t freq; int err; - err = acpicpu_pstate_get(ci, &freq); + freq = cpufreq_get(curcpu()); - if (err != 0) - return err; + if (freq == 0) + return ENXIO; node = *rnode; node.sysctl_data = &freq; @@ -1160,15 +1163,14 @@ acpicpu_md_pstate_sysctl_get(SYSCTLFN_AR static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_ARGS) { - struct cpu_info *ci = curcpu(); struct sysctlnode node; uint32_t freq; int err; - err = acpicpu_pstate_get(ci, &freq); + freq = cpufreq_get(curcpu()); - if (err != 0) - return err; + if (freq == 0) + return ENXIO; node = *rnode; node.sysctl_data = &freq; @@ -1178,7 +1180,7 @@ acpicpu_md_pstate_sysctl_set(SYSCTLFN_AR if (err != 0 || newp == NULL) return err; - acpicpu_pstate_set(ci, freq); + cpufreq_set_all(freq); return 0; } Index: src/sys/dev/acpi/acpi_cpu.c diff -u src/sys/dev/acpi/acpi_cpu.c:1.44 src/sys/dev/acpi/acpi_cpu.c:1.45 --- src/sys/dev/acpi/acpi_cpu.c:1.44 Wed Jun 22 08:49:54 2011 +++ src/sys/dev/acpi/acpi_cpu.c Tue Oct 18 05:08:24 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu.c,v 1.44 2011/06/22 08:49:54 jruoho Exp $ */ +/* $NetBSD: acpi_cpu.c,v 1.45 2011/10/18 05:08:24 jruoho Exp $ */ /*- * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.44 2011/06/22 08:49:54 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.45 2011/10/18 05:08:24 jruoho Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v #include <sys/module.h> #include <sys/mutex.h> #include <sys/sysctl.h> +#include <sys/cpufreq.h> #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> @@ -66,7 +67,8 @@ static bool acpicpu_resume(device_t, static void acpicpu_evcnt_attach(device_t); static void acpicpu_evcnt_detach(device_t); static void acpicpu_debug_print(device_t); -static const char *acpicpu_debug_print_method(uint8_t); +static const char *acpicpu_debug_print_method_c(uint8_t); +static const char *acpicpu_debug_print_method_pt(uint8_t); static const char *acpicpu_debug_print_dep(uint32_t); static uint32_t acpicpu_count = 0; @@ -247,6 +249,7 @@ acpicpu_once_attach(void) static int acpicpu_once_detach(void) { + struct cpu_info *ci = curcpu(); struct acpicpu_softc *sc; if (acpicpu_count != 0) @@ -255,8 +258,15 @@ acpicpu_once_detach(void) if (acpicpu_log != NULL) sysctl_teardown(&acpicpu_log); - if (acpicpu_sc != NULL) + if (acpicpu_sc != NULL) { + + sc = acpicpu_sc[ci->ci_acpiid]; + + if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) + cpufreq_deregister(); + kmem_free(acpicpu_sc, maxcpus * sizeof(*sc)); + } return 0; } @@ -266,6 +276,8 @@ acpicpu_start(device_t self) { struct acpicpu_softc *sc = device_private(self); static uint32_t count = 0; + struct cpufreq cf; + uint32_t i; /* * Run the state-specific initialization routines. These @@ -294,6 +306,34 @@ acpicpu_start(device_t self) acpicpu_sysctl(self); aprint_debug_dev(self, "ACPI CPUs started\n"); + + /* + * Register with cpufreq(9). + */ + if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) { + + (void)memset(&cf, 0, sizeof(struct cpufreq)); + + cf.cf_mp = false; + cf.cf_cookie = NULL; + cf.cf_get_freq = acpicpu_pstate_get; + cf.cf_set_freq = acpicpu_pstate_set; + cf.cf_state_count = sc->sc_pstate_count; + + (void)strlcpy(cf.cf_name, "acpicpu", sizeof(cf.cf_name)); + + for (i = 0; i < sc->sc_pstate_count; i++) { + + if (sc->sc_pstate[i].ps_freq == 0) + continue; + + cf.cf_state[i].cfs_freq = sc->sc_pstate[i].ps_freq; + cf.cf_state[i].cfs_power = sc->sc_pstate[i].ps_power; + } + + if (cpufreq_register(&cf) != 0) + aprint_error_dev(self, "failed to register cpufreq\n"); + } } static void @@ -726,7 +766,7 @@ acpicpu_debug_print(device_t self) aprint_verbose_dev(sc->sc_dev, "C%d: %3s, " "lat %3u us, pow %5u mW%s\n", i, - acpicpu_debug_print_method(cs->cs_method), + acpicpu_debug_print_method_c(cs->cs_method), cs->cs_latency, cs->cs_power, (cs->cs_flags != 0) ? ", bus master check" : ""); } @@ -742,7 +782,7 @@ acpicpu_debug_print(device_t self) aprint_verbose_dev(sc->sc_dev, "P%d: %3s, " "lat %3u us, pow %5u mW, %4u MHz%s\n", i, - acpicpu_debug_print_method(method), + acpicpu_debug_print_method_pt(method), ps->ps_latency, ps->ps_power, ps->ps_freq, (ps->ps_flags & ACPICPU_FLAG_P_TURBO) != 0 ? ", turbo boost" : ""); @@ -759,7 +799,7 @@ acpicpu_debug_print(device_t self) aprint_verbose_dev(sc->sc_dev, "T%u: %3s, " "lat %3u us, pow %5u mW, %3u %%\n", i, - acpicpu_debug_print_method(method), + acpicpu_debug_print_method_pt(method), ts->ts_latency, ts->ts_power, ts->ts_percent); } @@ -799,7 +839,7 @@ acpicpu_debug_print(device_t self) } static const char * -acpicpu_debug_print_method(uint8_t val) +acpicpu_debug_print_method_c(uint8_t val) { if (val == ACPICPU_C_STATE_FFH) @@ -811,6 +851,13 @@ acpicpu_debug_print_method(uint8_t val) if (val == ACPICPU_C_STATE_SYSIO) return "I/O"; + return "???"; +} + +static const char * +acpicpu_debug_print_method_pt(uint8_t val) +{ + if (val == ACPI_ADR_SPACE_SYSTEM_IO) return "I/O"; Index: src/sys/dev/acpi/acpi_cpu.h diff -u src/sys/dev/acpi/acpi_cpu.h:1.42 src/sys/dev/acpi/acpi_cpu.h:1.43 --- src/sys/dev/acpi/acpi_cpu.h:1.42 Wed Jun 22 08:49:54 2011 +++ src/sys/dev/acpi/acpi_cpu.h Tue Oct 18 05:08:24 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu.h,v 1.42 2011/06/22 08:49:54 jruoho Exp $ */ +/* $NetBSD: acpi_cpu.h,v 1.43 2011/10/18 05:08:24 jruoho Exp $ */ /*- * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi> @@ -84,7 +84,6 @@ */ #define ACPICPU_P_STATE_MAX 255 /* Arbitrary upper limit */ #define ACPICPU_P_STATE_RETRY 100 -#define ACPICPU_P_STATE_UNKNOWN 0x0 /* * T-states. @@ -245,8 +244,8 @@ void acpicpu_pstate_start(device_t); void acpicpu_pstate_suspend(void *); void acpicpu_pstate_resume(void *); void acpicpu_pstate_callback(void *); -int acpicpu_pstate_get(struct cpu_info *, uint32_t *); -void acpicpu_pstate_set(struct cpu_info *, uint32_t); +void acpicpu_pstate_get(void *, void *); +void acpicpu_pstate_set(void *, void *); void acpicpu_tstate_attach(device_t); void acpicpu_tstate_detach(device_t); Index: src/sys/dev/acpi/acpi_cpu_pstate.c diff -u src/sys/dev/acpi/acpi_cpu_pstate.c:1.51 src/sys/dev/acpi/acpi_cpu_pstate.c:1.52 --- src/sys/dev/acpi/acpi_cpu_pstate.c:1.51 Wed Jun 22 08:49:54 2011 +++ src/sys/dev/acpi/acpi_cpu_pstate.c Tue Oct 18 05:08:24 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_pstate.c,v 1.51 2011/06/22 08:49:54 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_pstate.c,v 1.52 2011/10/18 05:08:24 jruoho Exp $ */ /*- * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,11 +27,11 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.51 2011/06/22 08:49:54 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.52 2011/10/18 05:08:24 jruoho Exp $"); #include <sys/param.h> +#include <sys/cpufreq.h> #include <sys/kmem.h> -#include <sys/xcall.h> #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> @@ -53,7 +53,6 @@ static int acpicpu_pstate_min(struct a static void acpicpu_pstate_change(struct acpicpu_softc *); static void acpicpu_pstate_reset(struct acpicpu_softc *); static void acpicpu_pstate_bios(void); -static void acpicpu_pstate_set_xcall(void *, void *); extern struct acpicpu_softc **acpicpu_sc; @@ -129,6 +128,7 @@ acpicpu_pstate_attach(device_t self) if (ACPI_SUCCESS(rv)) sc->sc_flags |= ACPICPU_FLAG_P_DEP; + sc->sc_pstate_current = 0; sc->sc_flags |= ACPICPU_FLAG_P; acpicpu_pstate_bios(); @@ -175,99 +175,33 @@ void acpicpu_pstate_start(device_t self) { struct acpicpu_softc *sc = device_private(self); - struct acpicpu_pstate *ps; - uint32_t i; - int rv; - - rv = acpicpu_md_pstate_start(sc); - - if (rv != 0) - goto fail; - - /* - * Initialize the states to P0. - */ - for (i = 0, rv = ENXIO; i < sc->sc_pstate_count; i++) { - - ps = &sc->sc_pstate[i]; - if (ps->ps_freq != 0) { - acpicpu_pstate_set(sc->sc_ci, ps->ps_freq); - return; - } - } + if (acpicpu_md_pstate_start(sc) == 0) + return; -fail: sc->sc_flags &= ~ACPICPU_FLAG_P; - aprint_error_dev(self, "failed to start P-states (err %d)\n", rv); + aprint_error_dev(self, "failed to start P-states\n"); } void acpicpu_pstate_suspend(void *aux) { - struct acpicpu_pstate *ps = NULL; struct acpicpu_softc *sc; - struct cpu_info *ci; device_t self = aux; - uint64_t xc; - int32_t i; - - sc = device_private(self); - ci = sc->sc_ci; /* * Reset any dynamic limits. */ + sc = device_private(self); mutex_enter(&sc->sc_mtx); acpicpu_pstate_reset(sc); - - /* - * Following design notes for Windows, we set the highest - * P-state when entering any of the system sleep states. - * When resuming, the saved P-state will be restored. - * - * Microsoft Corporation: Windows Native Processor - * Performance Control. Version 1.1a, November, 2002. - */ - sc->sc_pstate_saved = sc->sc_pstate_current; - - for (i = sc->sc_pstate_count - 1; i >= 0; i--) { - - if (sc->sc_pstate[i].ps_freq != 0) { - ps = &sc->sc_pstate[i]; - break; - } - } - - if (__predict_false(ps == NULL)) { - mutex_exit(&sc->sc_mtx); - return; - } - - if (sc->sc_pstate_saved == ps->ps_freq) { - mutex_exit(&sc->sc_mtx); - return; - } - mutex_exit(&sc->sc_mtx); - - xc = xc_unicast(0, acpicpu_pstate_set_xcall, &ps->ps_freq, NULL, ci); - xc_wait(xc); } void acpicpu_pstate_resume(void *aux) { - struct acpicpu_softc *sc; - device_t self = aux; - uint32_t freq; - uint64_t xc; - - sc = device_private(self); - freq = sc->sc_pstate_saved; - - xc = xc_unicast(0, acpicpu_pstate_set_xcall, &freq, NULL, sc->sc_ci); - xc_wait(xc); + /* Nothing. */ } void @@ -276,10 +210,8 @@ acpicpu_pstate_callback(void *aux) struct acpicpu_softc *sc; device_t self = aux; uint32_t freq; - uint64_t xc; sc = device_private(self); - mutex_enter(&sc->sc_mtx); acpicpu_pstate_change(sc); @@ -294,12 +226,10 @@ acpicpu_pstate_callback(void *aux) } mutex_exit(&sc->sc_mtx); - - xc = xc_unicast(0, acpicpu_pstate_set_xcall, &freq, NULL, sc->sc_ci); - xc_wait(xc); + cpufreq_set(sc->sc_ci, freq); } -ACPI_STATUS +static ACPI_STATUS acpicpu_pstate_pss(struct acpicpu_softc *sc) { struct acpicpu_pstate *ps; @@ -529,7 +459,7 @@ acpicpu_pstate_xpss_add(struct acpicpu_p return AE_OK; } -ACPI_STATUS +static ACPI_STATUS acpicpu_pstate_pct(struct acpicpu_softc *sc) { static const size_t size = sizeof(struct acpicpu_reg); @@ -635,31 +565,31 @@ acpicpu_pstate_pct(struct acpicpu_softc (void)memcpy(&sc->sc_pstate_control, reg[0], size); (void)memcpy(&sc->sc_pstate_status, reg[1], size); - if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) == 0) - goto out; + if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) != 0) { - /* - * At the very least, mandate that - * XPSS supplies the control address. - */ - if (sc->sc_pstate_control.reg_addr == 0) { - rv = AE_AML_BAD_RESOURCE_LENGTH; - goto out; - } + /* + * At the very least, mandate that + * XPSS supplies the control address. + */ + if (sc->sc_pstate_control.reg_addr == 0) { + rv = AE_AML_BAD_RESOURCE_LENGTH; + goto out; + } - /* - * If XPSS is present, copy the MSR addresses - * to the P-state structures for convenience. - */ - for (i = 0; i < sc->sc_pstate_count; i++) { + /* + * If XPSS is present, copy the supplied + * MSR addresses to the P-state structures. + */ + for (i = 0; i < sc->sc_pstate_count; i++) { - ps = &sc->sc_pstate[i]; + ps = &sc->sc_pstate[i]; - if (ps->ps_freq == 0) - continue; + if (ps->ps_freq == 0) + continue; - ps->ps_status_addr = sc->sc_pstate_status.reg_addr; - ps->ps_control_addr = sc->sc_pstate_control.reg_addr; + ps->ps_status_addr = sc->sc_pstate_status.reg_addr; + ps->ps_control_addr = sc->sc_pstate_control.reg_addr; + } } out: @@ -863,12 +793,13 @@ acpicpu_pstate_bios(void) (void)AcpiOsWritePort(addr, val, 8); } -int -acpicpu_pstate_get(struct cpu_info *ci, uint32_t *freq) +void +acpicpu_pstate_get(void *aux, void *cpu_freq) { struct acpicpu_pstate *ps = NULL; + struct cpu_info *ci = curcpu(); struct acpicpu_softc *sc; - uint32_t i, val = 0; + uint32_t freq, i, val = 0; uint64_t addr; uint8_t width; int rv; @@ -880,11 +811,6 @@ acpicpu_pstate_get(struct cpu_info *ci, goto fail; } - if (__predict_false(sc->sc_cold != false)) { - rv = EBUSY; - goto fail; - } - if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) { rv = ENODEV; goto fail; @@ -895,10 +821,10 @@ acpicpu_pstate_get(struct cpu_info *ci, /* * Use the cached value, if available. */ - if (sc->sc_pstate_current != ACPICPU_P_STATE_UNKNOWN) { - *freq = sc->sc_pstate_current; + if (sc->sc_pstate_current != 0) { + *(uint32_t *)cpu_freq = sc->sc_pstate_current; mutex_exit(&sc->sc_mtx); - return 0; + return; } mutex_exit(&sc->sc_mtx); @@ -907,7 +833,7 @@ acpicpu_pstate_get(struct cpu_info *ci, case ACPI_ADR_SPACE_FIXED_HARDWARE: - rv = acpicpu_md_pstate_get(sc, freq); + rv = acpicpu_md_pstate_get(sc, &freq); if (__predict_false(rv != 0)) goto fail; @@ -942,7 +868,7 @@ acpicpu_pstate_get(struct cpu_info *ci, goto fail; } - *freq = ps->ps_freq; + freq = ps->ps_freq; break; default: @@ -951,33 +877,24 @@ acpicpu_pstate_get(struct cpu_info *ci, } mutex_enter(&sc->sc_mtx); - sc->sc_pstate_current = *freq; + sc->sc_pstate_current = freq; + *(uint32_t *)cpu_freq = freq; mutex_exit(&sc->sc_mtx); - return 0; + return; fail: aprint_error_dev(sc->sc_dev, "failed " "to get frequency (err %d)\n", rv); mutex_enter(&sc->sc_mtx); - *freq = sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN; + sc->sc_pstate_current = 0; + *(uint32_t *)cpu_freq = 0; mutex_exit(&sc->sc_mtx); - - return rv; } void -acpicpu_pstate_set(struct cpu_info *ci, uint32_t freq) -{ - uint64_t xc; - - xc = xc_broadcast(0, acpicpu_pstate_set_xcall, &freq, NULL); - xc_wait(xc); -} - -static void -acpicpu_pstate_set_xcall(void *arg1, void *arg2) +acpicpu_pstate_set(void *aux, void *cpu_freq) { struct acpicpu_pstate *ps = NULL; struct cpu_info *ci = curcpu(); @@ -987,7 +904,7 @@ acpicpu_pstate_set_xcall(void *arg1, voi uint8_t width; int rv; - freq = *(uint32_t *)arg1; + freq = *(uint32_t *)cpu_freq; sc = acpicpu_sc[ci->ci_acpiid]; if (__predict_false(sc == NULL)) { @@ -995,11 +912,6 @@ acpicpu_pstate_set_xcall(void *arg1, voi goto fail; } - if (__predict_false(sc->sc_cold != false)) { - rv = EBUSY; - goto fail; - } - if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) { rv = ENODEV; goto fail; @@ -1096,6 +1008,6 @@ fail: "frequency to %u (err %d)\n", freq, rv); mutex_enter(&sc->sc_mtx); - sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN; + sc->sc_pstate_current = 0; mutex_exit(&sc->sc_mtx); }