diff options
author | imp <imp@FreeBSD.org> | 2001-12-15 05:58:28 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2001-12-15 05:58:28 +0000 |
commit | 9292ea9a4dfc2ff90ee03892a97de158af725c44 (patch) | |
tree | 9d150006491e4846d4731d4cb78daa7d0ca0ebd5 /sys | |
parent | ad82adf6dd23cf18586eae17240b2a0f4b5891a4 (diff) | |
download | FreeBSD-src-9292ea9a4dfc2ff90ee03892a97de158af725c44.zip FreeBSD-src-9292ea9a4dfc2ff90ee03892a97de158af725c44.tar.gz |
Add support for suspending/resuming CardBus bridges.
We really should have and use power state information, but none exists
today.
Submitted by: YAMAMOTO Shigeru-san <shigeru@iij.ad.jp>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/cardbus/cardbus.c | 19 | ||||
-rw-r--r-- | sys/dev/pccard/pccard.c | 18 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 57 |
3 files changed, 87 insertions, 7 deletions
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index fc478b5..4fae016 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -146,7 +146,7 @@ static void cardbus_disable_io_method(device_t cbdev, device_t child, static int cardbus_probe(device_t cbdev) { - device_set_desc(cbdev, "Cardbus bus (newcard)"); + device_set_desc(cbdev, "CardBus bus"); return 0; } @@ -163,6 +163,19 @@ cardbus_detach(device_t cbdev) return 0; } +static int +cardbus_suspend(device_t self) +{ + cardbus_detach_card(self, DETACH_FORCE); + return (0); +} + +static int +cardbus_resume(device_t self) +{ + return (0); +} + /************************************************************************/ /* Attach/Detach card */ /************************************************************************/ @@ -1199,8 +1212,8 @@ static device_method_t cardbus_methods[] = { DEVMETHOD(device_attach, cardbus_attach), DEVMETHOD(device_detach, cardbus_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_suspend, cardbus_suspend), + DEVMETHOD(device_resume, cardbus_resume), /* Bus interface */ DEVMETHOD(bus_print_child, cardbus_print_child), diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c index 4612b40..f6ea864 100644 --- a/sys/dev/pccard/pccard.c +++ b/sys/dev/pccard/pccard.c @@ -807,6 +807,20 @@ pccard_detach(device_t dev) return 0; } +static int +pccard_suspend(device_t self) +{ + pccard_detach_card(self, 0); + return (0); +} + +static +int +pccard_resume(device_t self) +{ + return (0); +} + static void pccard_print_resources(struct resource_list *rl, const char *name, int type, int count, const char *format) @@ -1200,8 +1214,8 @@ static device_method_t pccard_methods[] = { DEVMETHOD(device_attach, pccard_attach), DEVMETHOD(device_detach, pccard_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_suspend, pccard_suspend), + DEVMETHOD(device_resume, pccard_resume), /* Bus interface */ DEVMETHOD(bus_print_child, pccard_print_child), diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index c8b21d2..1bf4fa3 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -2096,14 +2096,67 @@ pccbb_write_config(device_t brdev, int b, int s, int f, int reg, u_int32_t val, b, s, f, reg, val, width); } +static int +pccbb_suspend(device_t self) +{ + int error = 0; + struct pccbb_softc* sc = device_get_softc(self); + + bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intrhand); + error = bus_generic_suspend(self); + return (error); +} + +static int +pccbb_resume(device_t self) +{ + int error = 0; + struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(self); + u_int32_t tmp; + + pci_write_config(self, PCCBBR_SOCKBASE, + rman_get_start(sc->sc_base_res), 4); + DEVPRINTF((self, "PCI Memory allocated: %08lx\n", + rman_get_start(sc->sc_base_res))); + + pccbb_chipinit(sc); + + /* CSC Interrupt: Card detect interrupt on */ + sc->sc_socketreg->socket_mask |= PCCBB_SOCKET_MASK_CD; + + /* reset interrupt */ + tmp = sc->sc_socketreg->socket_event; + sc->sc_socketreg->socket_event = tmp; + + /* re-establish the interrupt. */ + if (bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc, + &(sc->sc_intrhand))) { + device_printf(self, "couldn't re-establish interrupt"); + bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); + bus_release_resource(self, SYS_RES_MEMORY, PCCBBR_SOCKBASE, + sc->sc_base_res); + mtx_destroy(&sc->sc_mtx); + error = ENOMEM; + } + bus_generic_resume(self); + + /* wakeup thread */ + if (!error) { + mtx_lock(&sc->sc_mtx); + wakeup(sc); + mtx_unlock(&sc->sc_mtx); + } + return (error); +} + static device_method_t pccbb_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pccbb_probe), DEVMETHOD(device_attach, pccbb_attach), DEVMETHOD(device_detach, pccbb_detach), DEVMETHOD(device_shutdown, pccbb_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_suspend, pccbb_suspend), + DEVMETHOD(device_resume, pccbb_resume), /* bus methods */ DEVMETHOD(bus_print_child, bus_generic_print_child), |