summaryrefslogtreecommitdiffstats
path: root/sys
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
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')
-rw-r--r--sys/dev/cardbus/cardbus.c19
-rw-r--r--sys/dev/pccard/pccard.c18
-rw-r--r--sys/dev/pccbb/pccbb.c57
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),
OpenPOWER on IntegriCloud