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>
This commit is contained in:
parent
91b70c33dd
commit
a432b68b87
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user