summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorreinoud <reinoud@NetBSD.org>2008-11-04 16:05:29 +0000
committerreinoud <reinoud@NetBSD.org>2008-11-04 16:05:29 +0000
commit3a0f6cde4673d2aeca6c32fcfdf31bf4641ca4fb (patch)
treeca348a9bde3b098a151ab1622fb2f545d2c88250 /sys/dev/pci
parent3829e1193057692ddd8798420f7d5fc7b621fe8f (diff)
Implement powersave for ixpide(4). Tested it on an Asus IXP250 with IGP.
It seems to sleep and awake fine now without errors or warnings.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/ixpide.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/sys/dev/pci/ixpide.c b/sys/dev/pci/ixpide.c
index 9a132f7111e..0a469426288 100644
--- a/sys/dev/pci/ixpide.c
+++ b/sys/dev/pci/ixpide.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ixpide.c,v 1.13 2008/09/06 22:18:56 rmind Exp $ */
+/* $NetBSD: ixpide.c,v 1.14 2008/11/04 16:05:29 reinoud Exp $ */
/*
* Copyright (c) 2004 The NetBSD Foundation.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.13 2008/09/06 22:18:56 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.14 2008/11/04 16:05:29 reinoud Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +38,8 @@ __KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.13 2008/09/06 22:18:56 rmind Exp $");
#include <dev/pci/pciidevar.h>
#include <dev/pci/pciide_ixp_reg.h>
+static bool ixpide_resume(device_t PMF_FN_PROTO);
+static bool ixpide_suspend(device_t PMF_FN_PROTO);
static int ixpide_match(device_t, cfdata_t, void *);
static void ixpide_attach(device_t, device_t, void *);
@@ -86,6 +88,9 @@ ixpide_attach(device_t parent, device_t self, void *aux)
pciide_common_attach(sc, pa,
pciide_lookup_product(pa->pa_id, pciide_ixpide_products));
+
+ if (!pmf_device_register(self, ixpide_suspend, ixpide_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
@@ -140,6 +145,32 @@ static const uint8_t ixp_mdma_timings[] = {
0x77, 0x21, 0x20
};
+static bool
+ixpide_resume(device_t dv PMF_FN_ARGS)
+{
+ struct pciide_softc *sc = device_private(dv);
+
+ pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_MDMA_TIMING,
+ sc->sc_pm_reg[0]);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_PIO_TIMING,
+ sc->sc_pm_reg[1]);
+
+ return true;
+}
+
+static bool
+ixpide_suspend(device_t dv PMF_FN_ARGS)
+{
+ struct pciide_softc *sc = device_private(dv);
+
+ sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ IXP_MDMA_TIMING);
+ sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ IXP_PIO_TIMING);
+
+ return true;
+}
+
static void
ixp_setup_channel(struct ata_channel *chp)
{