From 3a0f6cde4673d2aeca6c32fcfdf31bf4641ca4fb Mon Sep 17 00:00:00 2001 From: reinoud Date: Tue, 4 Nov 2008 16:05:29 +0000 Subject: 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. --- sys/dev/pci/ixpide.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'sys/dev') 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 -__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 #include @@ -38,6 +38,8 @@ __KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.13 2008/09/06 22:18:56 rmind Exp $"); #include #include +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) { -- cgit