summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2008-01-18 01:33:40 +0000
committerjoerg <joerg@NetBSD.org>2008-01-18 01:33:40 +0000
commit4ef3261d7ca2e39db13e7087c09e7f6089771ace (patch)
tree5135110601e4358dfccaf63ae35d203bd01dff52 /sys/dev
parent04eaea3b169d63209260d0b89809e66e3edd955c (diff)
Add power management support. Untested due to lack of feedback.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/viaide.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/sys/dev/pci/viaide.c b/sys/dev/pci/viaide.c
index e1d1471416c..b323751ba96 100644
--- a/sys/dev/pci/viaide.c
+++ b/sys/dev/pci/viaide.c
@@ -1,4 +1,4 @@
-/* $NetBSD: viaide.c,v 1.50 2007/12/20 22:24:40 phx Exp $ */
+/* $NetBSD: viaide.c,v 1.51 2008/01/18 01:33:40 joerg Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.50 2007/12/20 22:24:40 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.51 2008/01/18 01:33:40 joerg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,6 +67,8 @@ static int viaide_match(struct device *, struct cfdata *, void *);
static void viaide_attach(struct device *, struct device *, void *);
static const struct pciide_product_desc *
viaide_lookup(pcireg_t);
+static bool viaide_suspend(device_t);
+static bool viaide_resume(device_t);
CFATTACH_DECL(viaide, sizeof(struct pciide_softc),
viaide_match, viaide_attach, NULL, NULL);
@@ -374,6 +376,9 @@ viaide_attach(struct device *parent, struct device *self, void *aux)
if (pp == NULL)
panic("viaide_attach");
pciide_common_attach(sc, pa, pp);
+
+ if (!pmf_device_register(self, viaide_suspend, viaide_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
@@ -386,6 +391,39 @@ via_pcib_match(struct pci_attach_args *pa)
return 0;
}
+static bool
+viaide_suspend(device_t dv)
+{
+ struct pciide_softc *sc = device_private(dv);
+
+ sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc));
+ /* APO_DATATIM(sc) includes APO_UDMA(sc) */
+ sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc));
+ /* This two are VIA-only, but should be ignored by other devices. */
+ sc->sc_pm_reg[2] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc));
+ sc->sc_pm_reg[3] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc));
+
+ return true;
+}
+
+static bool
+viaide_resume(device_t dv)
+{
+ struct pciide_softc *sc = device_private(dv);
+
+ pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc),
+ sc->sc_pm_reg[0]);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc),
+ sc->sc_pm_reg[1]);
+ /* This two are VIA-only, but should be ignored by other devices. */
+ pci_conf_write(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc),
+ sc->sc_pm_reg[2]);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc),
+ sc->sc_pm_reg[3]);
+
+ return true;
+}
+
static void
via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{