summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccbb
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r--sys/dev/pccbb/pccbb.c53
-rw-r--r--sys/dev/pccbb/pccbb_isa.c16
-rw-r--r--sys/dev/pccbb/pccbb_pci.c101
-rw-r--r--sys/dev/pccbb/pccbbvar.h2
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,
OpenPOWER on IntegriCloud