Power hook for ath pci front end.

Written and tested by George Michaelson [ggm at apnic.net]
This commit is contained in:
perry 2006-06-20 14:38:34 +00:00
parent aab3cbfbad
commit 97da3b129c

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ath_pci.c,v 1.13 2006/06/05 05:15:31 gdamore Exp $ */
/* $NetBSD: if_ath_pci.c,v 1.14 2006/06/20 14:38:34 perry Exp $ */
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -41,7 +41,7 @@
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.11 2005/01/18 18:08:16 sam Exp $");
#endif
#ifdef __NetBSD__
__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.13 2006/06/05 05:15:31 gdamore Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.14 2006/06/20 14:38:34 perry Exp $");
#endif
/*
@ -91,6 +91,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.13 2006/06/05 05:15:31 gdamore Exp
struct ath_pci_softc {
struct ath_softc sc_sc;
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
struct pci_conf_state sc_pciconf;
void *sc_ih; /* interrupt handler */
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
@ -103,6 +105,7 @@ struct ath_pci_softc {
static int ath_pci_match(struct device *, struct cfdata *, void *);
static void ath_pci_attach(struct device *, struct device *, void *);
static void ath_pci_shutdown(void *);
static void ath_pci_powerhook(int, void *);
static int ath_pci_detach(struct device *, int);
CFATTACH_DECL(ath_pci,
@ -165,11 +168,14 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux)
struct pci_attach_args *pa = aux;
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
void *hook;
void *shook;
void *phook;
const char *intrstr = NULL;
psc->sc_pc = pc;
psc->sc_pcitag = pa->pa_tag;
if (!ath_pci_setup(pa))
goto bad;
@ -207,16 +213,23 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = pa->pa_dmat;
hook = shutdownhook_establish(ath_pci_shutdown, psc);
if (hook == NULL) {
shook = shutdownhook_establish(ath_pci_shutdown, psc);
if (shook == NULL) {
aprint_error("couldn't make shutdown hook\n");
goto bad3;
}
phook = powerhook_establish(ath_pci_powerhook, psc);
if (phook == NULL) {
aprint_error("couldn't make power hook\n");
goto bad3;
}
if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0)
return;
shutdownhook_disestablish(hook);
shutdownhook_disestablish(shook);
powerhook_disestablish(phook);
bad3: pci_intr_disestablish(pc, psc->sc_ih);
bad2: /* XXX */
@ -243,3 +256,25 @@ ath_pci_shutdown(void *self)
ath_shutdown(&psc->sc_sc);
}
static void
ath_pci_powerhook(int why, void *arg)
{
struct ath_pci_softc *sc = arg;
pci_chipset_tag_t pc = sc->sc_pc;
pcitag_t tag = sc->sc_pcitag;
switch (why) {
case PWR_SOFTSUSPEND:
ath_pci_shutdown(sc);
break;
case PWR_SUSPEND:
pci_conf_capture(pc, tag, &sc->sc_pciconf);
break;
case PWR_RESUME:
pci_conf_restore(pc, tag, &sc->sc_pciconf);
break;
}
return;
}