summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccbb
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-12-15 05:58:28 +0000
committerimp <imp@FreeBSD.org>2001-12-15 05:58:28 +0000
commit9292ea9a4dfc2ff90ee03892a97de158af725c44 (patch)
tree9d150006491e4846d4731d4cb78daa7d0ca0ebd5 /sys/dev/pccbb
parentad82adf6dd23cf18586eae17240b2a0f4b5891a4 (diff)
downloadFreeBSD-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/dev/pccbb')
-rw-r--r--sys/dev/pccbb/pccbb.c57
1 files changed, 55 insertions, 2 deletions
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),
OpenPOWER on IntegriCloud