summaryrefslogtreecommitdiff
path: root/sys/arch/loongson
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-09-07 16:52:05 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-09-07 16:52:05 +0000
commitbe8a92e83b3d6ef73fea916ded236a1fe71ddbc7 (patch)
tree5cccdc5fb6baa643fcc228491bf40b860506ae30 /sys/arch/loongson
parent52852ea3823529a18252b1e2e3bcaea2a0ba8fa0 (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.c38
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)
{