diff options
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 53 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbb_isa.c | 16 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbb_pci.c | 101 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbbvar.h | 2 |
4 files changed, 74 insertions, 98 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index 092d3ef..edb00a2 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -996,8 +996,6 @@ cbb_cardbus_reset_power(device_t brdev, device_t child, int on) * a cardbus bus, so that's the only register we check here. */ if (on && CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) { - /* - */ PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, &~CBBM_BRIDGECTRL_RESET, 2); b = pcib_get_bus(child); @@ -1569,57 +1567,6 @@ cbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value) } int -cbb_suspend(device_t self) -{ - int error = 0; - struct cbb_softc *sc = device_get_softc(self); - - error = bus_generic_suspend(self); - if (error != 0) - return (error); - cbb_set(sc, CBB_SOCKET_MASK, 0); /* Quiet hardware */ - sc->cardok = 0; /* Card is bogus now */ - return (0); -} - -int -cbb_resume(device_t self) -{ - int error = 0; - struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(self); - uint32_t tmp; - - /* - * Some BIOSes will not save the BARs for the pci chips, so we - * must do it ourselves. If the BAR is reset to 0 for an I/O - * device, it will read back as 0x1, so no explicit test for - * memory devices are needed. - * - * Note: The PCI bus code should do this automatically for us on - * suspend/resume, but until it does, we have to cope. - */ - pci_write_config(self, CBBR_SOCKBASE, rman_get_start(sc->base_res), 4); - DEVPRINTF((self, "PCI Memory allocated: %08lx\n", - rman_get_start(sc->base_res))); - - sc->chipinit(sc); - - /* reset interrupt -- Do we really need to do this? */ - tmp = cbb_get(sc, CBB_SOCKET_EVENT); - cbb_set(sc, CBB_SOCKET_EVENT, tmp); - - /* CSC Interrupt: Card detect interrupt on */ - cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); - - /* Signal the thread to wakeup. */ - wakeup(&sc->intrhand); - - error = bus_generic_resume(self); - - return (error); -} - -int cbb_child_present(device_t parent, device_t child) { struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(parent); diff --git a/sys/dev/pccbb/pccbb_isa.c b/sys/dev/pccbb/pccbb_isa.c index 1d0a698..2a4961f 100644 --- a/sys/dev/pccbb/pccbb_isa.c +++ b/sys/dev/pccbb/pccbb_isa.c @@ -205,13 +205,25 @@ cbb_isa_attach(device_t dev) return (ENOMEM); } +static int +cbb_isa_suspend(device_t dev) +{ + return (0); +} + +static int +cbb_isa_resume(device_t dev) +{ + return (0); +} + static device_method_t cbb_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cbb_isa_probe), DEVMETHOD(device_attach, cbb_isa_attach), DEVMETHOD(device_detach, cbb_detach), - DEVMETHOD(device_suspend, cbb_suspend), - DEVMETHOD(device_resume, cbb_resume), + DEVMETHOD(device_suspend, cbb_isa_suspend), + DEVMETHOD(device_resume, cbb_isa_resume), /* bus methods */ DEVMETHOD(bus_read_ivar, cbb_read_ivar), diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c index 7b4727c..7dca418 100644 --- a/sys/dev/pccbb/pccbb_pci.c +++ b/sys/dev/pccbb/pccbb_pci.c @@ -259,32 +259,6 @@ cbb_pci_probe(device_t brdev) } /* - * Still need this because the pci code only does power for type 0 - * header devices. - */ -static void -cbb_powerstate_d0(device_t dev) -{ - u_int32_t membase, irq; - - if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { - /* Save important PCI config data. */ - membase = pci_read_config(dev, CBBR_SOCKBASE, 4); - irq = pci_read_config(dev, PCIR_INTLINE, 4); - - /* Reset the power state. */ - device_printf(dev, "chip is in D%d power mode " - "-- setting to D0\n", pci_get_powerstate(dev)); - - pci_set_powerstate(dev, PCI_POWERSTATE_D0); - - /* Restore PCI config data. */ - pci_write_config(dev, CBBR_SOCKBASE, membase, 4); - pci_write_config(dev, PCIR_INTLINE, irq, 4); - } -} - -/* * Print out the config space */ static void @@ -321,15 +295,15 @@ cbb_pci_attach(device_t brdev) sc->cbdev = NULL; sc->exca[0].pccarddev = NULL; sc->domain = pci_get_domain(brdev); - sc->bus.sec = pci_read_config(brdev, PCIR_SECBUS_2, 1); - sc->bus.sub = pci_read_config(brdev, PCIR_SUBBUS_2, 1); sc->pribus = pcib_get_bus(parent); #if defined(NEW_PCIB) && defined(PCI_RES_BUS) pci_write_config(brdev, PCIR_PRIBUS_2, sc->pribus, 1); pcib_setup_secbus(brdev, &sc->bus, 1); +#else + sc->bus.sec = pci_read_config(brdev, PCIR_SECBUS_2, 1); + sc->bus.sub = pci_read_config(brdev, PCIR_SUBBUS_2, 1); #endif SLIST_INIT(&sc->rl); - cbb_powerstate_d0(brdev); rid = CBBR_SOCKBASE; sc->base_res = bus_alloc_resource_any(brdev, SYS_RES_MEMORY, &rid, @@ -467,22 +441,17 @@ cbb_chipinit(struct cbb_softc *sc) uint32_t mux, sysctrl, reg; /* Set CardBus latency timer */ - if (pci_read_config(sc->dev, PCIR_SECLAT_1, 1) < 0x20) - pci_write_config(sc->dev, PCIR_SECLAT_1, 0x20, 1); + if (pci_read_config(sc->dev, PCIR_SECLAT_2, 1) < 0x20) + pci_write_config(sc->dev, PCIR_SECLAT_2, 0x20, 1); /* Set PCI latency timer */ if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20) pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1); - /* Restore bus configuration */ - pci_write_config(sc->dev, PCIR_PRIBUS_2, sc->pribus, 1); - pci_write_config(sc->dev, PCIR_SECBUS_2, sc->bus.sec, 1); - pci_write_config(sc->dev, PCIR_SUBBUS_2, sc->bus.sub, 1); - - /* Enable memory access */ + /* Enable DMA, memory access for this card and I/O acces for children */ pci_enable_busmaster(sc->dev); - /* XXX: This should not be necessary, but some chipsets require it */ - PCI_MASK_CONFIG(sc->dev, PCIR_COMMAND, | PCIM_CMD_PORTEN, 2); + pci_enable_io(sc->dev, SYS_RES_IOPORT); + pci_enable_io(sc->dev, SYS_RES_MEMORY); /* disable Legacy IO */ switch (sc->chipset) { @@ -877,14 +846,64 @@ cbb_write_config(device_t brdev, u_int b, u_int s, u_int f, u_int reg, uint32_t b, s, f, reg, val, width); } +static int +cbb_pci_suspend(device_t brdev) +{ + int error = 0; + struct cbb_softc *sc = device_get_softc(brdev); + + error = bus_generic_suspend(brdev); + if (error != 0) + return (error); + cbb_set(sc, CBB_SOCKET_MASK, 0); /* Quiet hardware */ + sc->cardok = 0; /* Card is bogus now */ + return (0); +} + +static int +cbb_pci_resume(device_t brdev) +{ + int error = 0; + struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev); + uint32_t tmp; + + /* + * In the APM and early ACPI era, BIOSes saved the PCI config + * registers. As chips became more complicated, that functionality moved + * into the ACPI code / tables. We must therefore, restore the settings + * we made here to make sure the device come back. Transitions to Dx + * from D0 and back to D0 cause the bridge to lose its config space, so + * all the bus mappings and such are preserved. + * + * The PCI layer handles standard PCI registers like the + * command register and BARs, but cbb-specific registers are + * handled here. + */ + sc->chipinit(sc); + + /* reset interrupt -- Do we really need to do this? */ + tmp = cbb_get(sc, CBB_SOCKET_EVENT); + cbb_set(sc, CBB_SOCKET_EVENT, tmp); + + /* CSC Interrupt: Card detect interrupt on */ + cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); + + /* Signal the thread to wakeup. */ + wakeup(&sc->intrhand); + + error = bus_generic_resume(brdev); + + return (error); +} + static device_method_t cbb_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cbb_pci_probe), DEVMETHOD(device_attach, cbb_pci_attach), DEVMETHOD(device_detach, cbb_detach), DEVMETHOD(device_shutdown, cbb_pci_shutdown), - DEVMETHOD(device_suspend, cbb_suspend), - DEVMETHOD(device_resume, cbb_resume), + DEVMETHOD(device_suspend, cbb_pci_suspend), + DEVMETHOD(device_resume, cbb_pci_resume), /* bus methods */ DEVMETHOD(bus_read_ivar, cbb_read_ivar), diff --git a/sys/dev/pccbb/pccbbvar.h b/sys/dev/pccbb/pccbbvar.h index c3e2d24..f19b933 100644 --- a/sys/dev/pccbb/pccbbvar.h +++ b/sys/dev/pccbb/pccbbvar.h @@ -134,11 +134,9 @@ int cbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result); int cbb_release_resource(device_t brdev, device_t child, int type, int rid, struct resource *r); -int cbb_resume(device_t self); int cbb_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep); -int cbb_suspend(device_t self); int cbb_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie); int cbb_write_ivar(device_t brdev, device_t child, int which, |