diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-09-07 16:52:05 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-09-07 16:52:05 +0000 |
commit | be8a92e83b3d6ef73fea916ded236a1fe71ddbc7 (patch) | |
tree | 5cccdc5fb6baa643fcc228491bf40b860506ae30 /sys/arch/loongson | |
parent | 52852ea3823529a18252b1e2e3bcaea2a0ba8fa0 (diff) |
Join the cf_activate() crowd and preserve a few msr around suspend.
Diffstat (limited to 'sys/arch/loongson')
-rw-r--r-- | sys/arch/loongson/dev/glxpcib.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/sys/arch/loongson/dev/glxpcib.c b/sys/arch/loongson/dev/glxpcib.c index 9b7d3bdeaf3..4f175005828 100644 --- a/sys/arch/loongson/dev/glxpcib.c +++ b/sys/arch/loongson/dev/glxpcib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glxpcib.c,v 1.6 2010/05/08 21:59:56 miod Exp $ */ +/* $OpenBSD: glxpcib.c,v 1.7 2010/09/07 16:52:04 miod Exp $ */ /* * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> @@ -146,9 +146,11 @@ struct cfdriver glxpcib_cd = { int glxpcib_match(struct device *, void *, void *); void glxpcib_attach(struct device *, struct device *, void *); +int glxpcib_activate(struct device *, int); struct cfattach glxpcib_ca = { - sizeof(struct glxpcib_softc), glxpcib_match, glxpcib_attach + sizeof(struct glxpcib_softc), glxpcib_match, glxpcib_attach, + NULL, glxpcib_activate }; /* from arch/<*>/pci/pcib.c */ @@ -265,6 +267,38 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux) #endif } +int +glxpcib_activate(struct device *dv, int act) +{ + int rv = 0; + const uint32_t msrlist[] = { + GLIU_PAE, + GLCP_GLD_MSR_PM, + DIVIL_BALL_OPTS + }; + static uint64_t msrsave[nitems(msrlist)]; + uint64_t msr; + uint i; + + switch (act) { + case DVACT_SUSPEND: + rv = config_activate_children(dv, act); + for (i = 0; i < nitems(msrlist); i++) + msrsave[i] = rdmsr(msrlist[i]); + break; + case DVACT_RESUME: + for (i = 0; i < nitems(msrlist); i++) { + msr = rdmsr(msrlist[i]); + if (msr != msrsave[i]) + wrmsr(msrlist[i], msr); + } + rv = config_activate_children(dv, act); + break; + } + + return rv; +} + u_int glxpcib_get_timecount(struct timecounter *tc) { |