Page MenuHomeFreeBSD

D7585.diff
No OneTemporary

D7585.diff

Index: sys/dev/pci/isa_pci.c
===================================================================
--- sys/dev/pci/isa_pci.c
+++ sys/dev/pci/isa_pci.c
@@ -93,7 +93,7 @@
sizeof(struct isab_pci_softc),
};
-DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0);
+EARLY_DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0, BUS_PASS_BUS);
/*
* XXX we need to add a quirk list here for bridges that don't correctly
Index: sys/dev/pci/pci.c
===================================================================
--- sys/dev/pci/pci.c
+++ sys/dev/pci/pci.c
@@ -206,7 +206,8 @@
DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc));
static devclass_t pci_devclass;
-DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, NULL);
+EARLY_DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, NULL,
+ BUS_PASS_BUS);
MODULE_VERSION(pci, 1);
static char *pci_vendordata;
Index: sys/dev/pci/pci_pci.c
===================================================================
--- sys/dev/pci/pci_pci.c
+++ sys/dev/pci/pci_pci.c
@@ -72,6 +72,7 @@
static void pcib_ari_decode_rid(device_t pcib, uint16_t rid,
int *bus, int *slot, int *func);
#ifdef PCI_HP
+static void pcib_pcie_new_pass(device_t dev);
static void pcib_pcie_ab_timeout(void *arg);
static void pcib_pcie_cc_timeout(void *arg);
static void pcib_pcie_dll_timeout(void *arg);
@@ -87,6 +88,9 @@
DEVMETHOD(device_resume, pcib_resume),
/* Bus interface */
+#ifdef PCI_HP
+ DEVMETHOD(bus_new_pass, pcib_pcie_new_pass),
+#endif
DEVMETHOD(bus_child_present, pcib_child_present),
DEVMETHOD(bus_read_ivar, pcib_read_ivar),
DEVMETHOD(bus_write_ivar, pcib_write_ivar),
@@ -126,7 +130,8 @@
static devclass_t pcib_devclass;
DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
-DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL);
+EARLY_DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL,
+ BUS_PASS_BUS);
#if defined(NEW_PCIB) || defined(PCI_HP)
SYSCTL_DECL(_hw_pci);
@@ -913,6 +918,7 @@
SYSCTL_INT(_hw_pci, OID_AUTO, enable_pcie_hp, CTLFLAG_RDTUN,
&pci_enable_pcie_hp, 0,
"Enable support for native PCI-express HotPlug.");
+static int pcib_detach_hotplug(struct pcib_softc *sc);
static void
pcib_probe_hotplug(struct pcib_softc *sc)
@@ -1291,9 +1297,9 @@
pcib_alloc_pcie_irq(struct pcib_softc *sc)
{
device_t dev;
- int count, error, rid;
+ int count, error;
- rid = -1;
+ sc->pcie_irq_id = -1;
dev = sc->dev;
/*
@@ -1305,39 +1311,69 @@
if (count == 1) {
error = pci_alloc_msix(dev, &count);
if (error == 0)
- rid = 1;
+ sc->pcie_irq_id = 1;
}
- if (rid < 0 && pci_msi_count(dev) > 0) {
+ if (sc->pcie_irq_id < 0 && pci_msi_count(dev) > 0) {
count = 1;
error = pci_alloc_msi(dev, &count);
if (error == 0)
- rid = 1;
+ sc->pcie_irq_id = 1;
}
- if (rid < 0)
- rid = 0;
+ if (sc->pcie_irq_id < 0)
+ sc->pcie_irq_id = 0;
- sc->pcie_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
+ sc->pcie_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->pcie_irq_id, 0 /* Inactive until after BUS_PASS_INTERRUPT */);
if (sc->pcie_irq == NULL) {
device_printf(dev,
"Failed to allocate interrupt for PCI-e events\n");
- if (rid > 0)
+ if (sc->pcie_irq_id > 0)
pci_release_msi(dev);
return (ENXIO);
}
+ /* Check if this attached late */
+ if (bus_current_pass > BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST)
+ pcib_pcie_new_pass(dev);
+
+ return (0);
+}
+
+/*
+ * Late attach for interrupt setup for hotplug bridges, since the interrupt
+ * controller may be a child of the bridge.
+ */
+
+static void
+pcib_pcie_new_pass(device_t dev)
+{
+ struct pcib_softc *sc;
+ int error;
+
+ if (bus_current_pass <= BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST)
+ goto out;
+
+ sc = device_get_softc(dev);
+ if (sc->pcie_irq == NULL || (rman_get_flags(sc->pcie_irq) & RF_ACTIVE))
+ goto out;
+
+ bus_activate_resource(dev, SYS_RES_IRQ, sc->pcie_irq_id, sc->pcie_irq);
+
error = bus_setup_intr(dev, sc->pcie_irq, INTR_TYPE_MISC,
NULL, pcib_pcie_intr, sc, &sc->pcie_ihand);
if (error) {
device_printf(dev, "Failed to setup PCI-e interrupt handler\n");
- bus_release_resource(dev, SYS_RES_IRQ, rid, sc->pcie_irq);
- if (rid > 0)
- pci_release_msi(dev);
- return (error);
+ bus_release_resource(dev, SYS_RES_IRQ, sc->pcie_irq_id,
+ sc->pcie_irq);
+ pcib_detach_hotplug(sc);
+ sc->flags &= ~PCIB_DETACHING;
+ sc->pcie_irq = NULL;
}
- return (0);
+
+out:
+ bus_generic_new_pass(dev);
}
static int
@@ -1347,9 +1383,11 @@
int error;
dev = sc->dev;
- error = bus_teardown_intr(dev, sc->pcie_irq, sc->pcie_ihand);
- if (error)
- return (error);
+ if (rman_get_flags(sc->pcie_irq) & RF_ACTIVE) {
+ error = bus_teardown_intr(dev, sc->pcie_irq, sc->pcie_ihand);
+ if (error)
+ return (error);
+ }
error = bus_free_resource(dev, SYS_RES_IRQ, sc->pcie_irq);
if (error)
return (error);
Index: sys/dev/pci/pcib_private.h
===================================================================
--- sys/dev/pci/pcib_private.h
+++ sys/dev/pci/pcib_private.h
@@ -135,6 +135,7 @@
uint32_t pcie_link_cap;
uint32_t pcie_slot_cap;
struct resource *pcie_irq;
+ int pcie_irq_id;
void *pcie_ihand;
struct task pcie_hp_task;
struct callout pcie_ab_timer;
Index: sys/isa/isa_common.c
===================================================================
--- sys/isa/isa_common.c
+++ sys/isa/isa_common.c
@@ -1103,8 +1103,8 @@
* ISA can be attached to a PCI-ISA bridge, or other locations on some
* platforms.
*/
-DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0);
-DRIVER_MODULE(isa, eisab, isa_driver, isa_devclass, 0, 0);
+EARLY_DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0, BUS_PASS_BUS);
+EARLY_DRIVER_MODULE(isa, eisab, isa_driver, isa_devclass, 0, 0, BUS_PASS_BUS);
MODULE_VERSION(isa, 1);
/*
Index: sys/powerpc/include/openpicvar.h
===================================================================
--- sys/powerpc/include/openpicvar.h
+++ sys/powerpc/include/openpicvar.h
@@ -69,6 +69,7 @@
* Bus-independent attach i/f
*/
int openpic_common_attach(device_t, uint32_t);
+void openpic_new_pass(device_t);
/*
* PIC interface.
Index: sys/powerpc/mpc85xx/atpic.c
===================================================================
--- sys/powerpc/mpc85xx/atpic.c
+++ sys/powerpc/mpc85xx/atpic.c
@@ -67,6 +67,7 @@
};
static int atpic_isa_attach(device_t);
+static void atpic_isa_new_pass(device_t);
static void atpic_isa_identify(driver_t *, device_t);
static int atpic_isa_probe(device_t);
@@ -87,6 +88,7 @@
DEVMETHOD(device_identify, atpic_isa_identify),
DEVMETHOD(device_probe, atpic_isa_probe),
DEVMETHOD(device_attach, atpic_isa_attach),
+ DEVMETHOD(bus_new_pass, atpic_isa_new_pass),
/* PIC interface */
DEVMETHOD(pic_config, atpic_config),
@@ -110,7 +112,8 @@
static devclass_t atpic_devclass;
-DRIVER_MODULE(atpic, isa, atpic_isa_driver, atpic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(atpic, isa, atpic_isa_driver, atpic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
static struct isa_pnp_id atpic_ids[] = {
{ 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
@@ -211,15 +214,10 @@
sc->sc_irid = 0;
sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid,
- RF_ACTIVE);
+ 0 /* later */);
if (sc->sc_ires == NULL)
goto fail;
- error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_MISC | INTR_MPSAFE,
- NULL, atpic_intr, dev, &sc->sc_icookie);
- if (error)
- goto fail;
-
atpic_init(sc, ATPIC_SLAVE);
atpic_init(sc, ATPIC_MASTER);
@@ -239,7 +237,30 @@
return (error);
}
+void
+atpic_new_pass(device_t dev)
+{
+ struct atpic_softc *sc;
+ int error;
+ if (bus_current_pass <= BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST)
+ return;
+
+ sc = device_get_softc(dev);
+
+ if (rman_get_flags(sc->sc_ires) & RF_ACTIVE)
+ return;
+
+ bus_activate_resource(dev, SYS_RES_IRQ, sc->sc_irid, sc->sc_ires);
+
+ error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_MISC | INTR_MPSAFE,
+ NULL, atpic_intr, dev, &sc->sc_icookie);
+
+ if (error != 0)
+ panic("atpic_new_pass: could not set up parent interrupt (%d)",
+ error);
+}
+
/*
* PIC interface.
*/
Index: sys/powerpc/mpc85xx/pci_mpc85xx.c
===================================================================
--- sys/powerpc/mpc85xx/pci_mpc85xx.c
+++ sys/powerpc/mpc85xx/pci_mpc85xx.c
@@ -135,6 +135,7 @@
bus_space_tag_t sc_bst;
int sc_rid;
+ int sc_irq_id;
struct resource *sc_irq_res;
void *sc_ih;
@@ -190,6 +191,7 @@
/* Forward declerations. */
static int fsl_pcib_attach(device_t);
+static void fsl_new_pass(device_t);
static int fsl_pcib_detach(device_t);
static int fsl_pcib_probe(device_t);
@@ -210,6 +212,7 @@
DEVMETHOD(device_probe, fsl_pcib_probe),
DEVMETHOD(device_attach, fsl_pcib_attach),
DEVMETHOD(device_detach, fsl_pcib_detach),
+ DEVMETHOD(bus_new_pass, fsl_new_pass),
/* pcib interface */
DEVMETHOD(pcib_maxslots, fsl_pcib_maxslots),
@@ -223,7 +226,8 @@
DEFINE_CLASS_1(pcib, fsl_pcib_driver, fsl_pcib_methods,
sizeof(struct fsl_pcib_softc), ofw_pci_driver);
-DRIVER_MODULE(pcib, ofwbus, fsl_pcib_driver, fsl_pcib_devclass, 0, 0);
+EARLY_DRIVER_MODULE(pcib, ofwbus, fsl_pcib_driver, fsl_pcib_devclass, 0, 0,
+ BUS_PASS_BUS);
static int
fsl_pcib_err_intr(void *v)
@@ -280,7 +284,7 @@
struct fsl_pcib_softc *sc;
phandle_t node;
uint32_t cfgreg;
- int error, maxslot, rid;
+ int error, maxslot;
uint8_t ltssm, capptr;
sc = device_get_softc(dev);
@@ -362,9 +366,9 @@
}
/* Allocate irq */
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE | RF_SHAREABLE);
+ sc->sc_irq_id = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->sc_irq_id, RF_SHAREABLE /* Set up as inactive */);
if (sc->sc_irq_res == NULL) {
error = fsl_pcib_detach(dev);
if (error != 0) {
@@ -375,20 +379,7 @@
return (ENXIO);
}
- /* Setup interrupt handler */
- error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
- NULL, (driver_intr_t *)fsl_pcib_err_intr, dev, &sc->sc_ih);
- if (error != 0) {
- device_printf(dev, "Could not setup irq, %d\n", error);
- sc->sc_ih = NULL;
- error = fsl_pcib_detach(dev);
- if (error != 0) {
- device_printf(dev,
- "Detach of the driver failed with error %d\n",
- error);
- }
- return (ENXIO);
- }
+ /* Setup interrupt handler in fsl_new_pass() */
fsl_pcib_err_init(dev);
@@ -398,6 +389,32 @@
return (ENXIO);
}
+static void
+fsl_new_pass(device_t dev)
+{
+ struct fsl_pcib_softc *sc;
+ int error;
+
+ if (bus_current_pass <= BUS_PASS_INTERRUPT)
+ goto out;
+
+ sc = device_get_softc(dev);
+
+ if (rman_get_flags(sc->sc_irq_res) & RF_ACTIVE)
+ goto out;
+
+ /* Setup interrupt handler */
+ bus_activate_resource(dev, SYS_RES_IRQ, sc->sc_irq_id, sc->sc_irq_res);
+ error = bus_setup_intr(dev, sc->sc_irq_res,
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL,
+ (driver_intr_t *)fsl_pcib_err_intr, dev, &sc->sc_ih);
+ if (error != 0)
+ panic("fsl_new_pass: could not setup irq, %d\n", error);
+
+out:
+ bus_generic_new_pass(dev);
+}
+
static uint32_t
fsl_pcib_cfgread(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func,
u_int reg, int bytes)
Index: sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c
===================================================================
--- sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c
+++ sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c
@@ -80,5 +80,6 @@
static devclass_t fsl_pcib_rc_devclass;
DEFINE_CLASS_1(pcib, fsl_pcib_rc_driver, fsl_pcib_rc_methods,
sizeof(struct pcib_softc), pcib_driver);
-DRIVER_MODULE(rcpcib, pci, fsl_pcib_rc_driver, fsl_pcib_rc_devclass, 0, 0);
+EARLY_DRIVER_MODULE(rcpcib, pci, fsl_pcib_rc_driver, fsl_pcib_rc_devclass, 0, 0,
+ BUS_PASS_BUS);
Index: sys/powerpc/ofw/ofw_pcib_pci.c
===================================================================
--- sys/powerpc/ofw/ofw_pcib_pci.c
+++ sys/powerpc/ofw/ofw_pcib_pci.c
@@ -83,7 +83,8 @@
DEFINE_CLASS_1(pcib, ofw_pcib_pci_driver, ofw_pcib_pci_methods,
sizeof(struct ofw_pcib_softc), pcib_driver);
-DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_pci_driver, pcib_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_pci_driver, pcib_devclass, 0, 0,
+ BUS_PASS_BUS);
static int
ofw_pcib_pci_probe(device_t dev)
Index: sys/powerpc/ofw/ofw_pcibus.c
===================================================================
--- sys/powerpc/ofw/ofw_pcibus.c
+++ sys/powerpc/ofw/ofw_pcibus.c
@@ -98,7 +98,8 @@
DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods,
sizeof(struct pci_softc), pci_driver);
-DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0,
+ BUS_PASS_BUS);
MODULE_VERSION(ofw_pcibus, 1);
MODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
Index: sys/powerpc/ofw/openpic_ofw.c
===================================================================
--- sys/powerpc/ofw/openpic_ofw.c
+++ sys/powerpc/ofw/openpic_ofw.c
@@ -69,6 +69,7 @@
/* Device interface */
DEVMETHOD(device_probe, openpic_ofw_probe),
DEVMETHOD(device_attach, openpic_ofw_attach),
+ DEVMETHOD(bus_new_pass, openpic_new_pass),
DEVMETHOD(device_suspend, openpic_suspend),
DEVMETHOD(device_resume, openpic_resume),
@@ -93,9 +94,12 @@
sizeof(struct openpic_softc),
};
-DRIVER_MODULE(openpic, ofwbus, openpic_ofw_driver, openpic_devclass, 0, 0);
-DRIVER_MODULE(openpic, simplebus, openpic_ofw_driver, openpic_devclass, 0, 0);
-DRIVER_MODULE(openpic, macio, openpic_ofw_driver, openpic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(openpic, ofwbus, openpic_ofw_driver, openpic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
+EARLY_DRIVER_MODULE(openpic, simplebus, openpic_ofw_driver, openpic_devclass, 0,
+ 0, BUS_PASS_INTERRUPT);
+EARLY_DRIVER_MODULE(openpic, macio, openpic_ofw_driver, openpic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
static int
openpic_ofw_probe(device_t dev)
Index: sys/powerpc/powermac/cpcht.c
===================================================================
--- sys/powerpc/powermac/cpcht.c
+++ sys/powerpc/powermac/cpcht.c
@@ -135,7 +135,8 @@
static devclass_t cpcht_devclass;
DEFINE_CLASS_1(pcib, cpcht_driver, cpcht_methods, sizeof(struct cpcht_softc),
ofw_pci_driver);
-DRIVER_MODULE(cpcht, ofwbus, cpcht_driver, cpcht_devclass, 0, 0);
+EARLY_DRIVER_MODULE(cpcht, ofwbus, cpcht_driver, cpcht_devclass, 0, 0,
+ BUS_PASS_BUS);
#define CPCHT_IOPORT_BASE 0xf4000000UL /* Hardwired */
#define CPCHT_IOPORT_SIZE 0x00400000UL
@@ -515,6 +516,7 @@
/* Device interface */
DEVMETHOD(device_probe, openpic_cpcht_probe),
DEVMETHOD(device_attach, openpic_cpcht_attach),
+ DEVMETHOD(bus_new_pass, openpic_new_pass),
/* PIC interface */
DEVMETHOD(pic_bind, openpic_bind),
@@ -541,7 +543,8 @@
sizeof(struct openpic_cpcht_softc),
};
-DRIVER_MODULE(openpic, unin, openpic_cpcht_driver, openpic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(openpic, unin, openpic_cpcht_driver, openpic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
static int
openpic_cpcht_probe(device_t dev)
Index: sys/powerpc/powermac/grackle.c
===================================================================
--- sys/powerpc/powermac/grackle.c
+++ sys/powerpc/powermac/grackle.c
@@ -99,7 +99,8 @@
static devclass_t grackle_devclass;
DEFINE_CLASS_1(pcib, grackle_driver, grackle_methods,
sizeof(struct grackle_softc), ofw_pci_driver);
-DRIVER_MODULE(grackle, ofwbus, grackle_driver, grackle_devclass, 0, 0);
+EARLY_DRIVER_MODULE(grackle, ofwbus, grackle_driver, grackle_devclass, 0, 0,
+ BUS_PASS_BUS);
static int
grackle_probe(device_t dev)
Index: sys/powerpc/powermac/hrowpic.c
===================================================================
--- sys/powerpc/powermac/hrowpic.c
+++ sys/powerpc/powermac/hrowpic.c
@@ -94,7 +94,8 @@
static devclass_t hrowpic_devclass;
-DRIVER_MODULE(hrowpic, macio, hrowpic_driver, hrowpic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(hrowpic, macio, hrowpic_driver, hrowpic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
static uint32_t
hrowpic_read_reg(struct hrowpic_softc *sc, u_int reg, u_int bank)
Index: sys/powerpc/powermac/macio.c
===================================================================
--- sys/powerpc/powermac/macio.c
+++ sys/powerpc/powermac/macio.c
@@ -133,7 +133,8 @@
devclass_t macio_devclass;
-DRIVER_MODULE(macio, pci, macio_pci_driver, macio_devclass, 0, 0);
+EARLY_DRIVER_MODULE(macio, pci, macio_pci_driver, macio_devclass, 0, 0,
+ BUS_PASS_BUS);
/*
* PCI ID search table
Index: sys/powerpc/powermac/uninorth.c
===================================================================
--- sys/powerpc/powermac/uninorth.c
+++ sys/powerpc/powermac/uninorth.c
@@ -144,7 +144,8 @@
*/
static device_t unin_chip;
-DRIVER_MODULE(unin, ofwbus, unin_chip_driver, unin_chip_devclass, 0, 0);
+EARLY_DRIVER_MODULE(unin, ofwbus, unin_chip_driver, unin_chip_devclass, 0, 0,
+ BUS_PASS_BUS);
/*
* Add an interrupt to the dev's resource list if present
Index: sys/powerpc/powermac/uninorthpci.c
===================================================================
--- sys/powerpc/powermac/uninorthpci.c
+++ sys/powerpc/powermac/uninorthpci.c
@@ -97,7 +97,8 @@
DEFINE_CLASS_1(pcib, uninorth_driver, uninorth_methods,
sizeof(struct uninorth_softc), ofw_pci_driver);
-DRIVER_MODULE(uninorth, ofwbus, uninorth_driver, uninorth_devclass, 0, 0);
+EARLY_DRIVER_MODULE(uninorth, ofwbus, uninorth_driver, uninorth_devclass, 0, 0,
+ BUS_PASS_BUS);
static int
uninorth_probe(device_t dev)
Index: sys/powerpc/powerpc/openpic.c
===================================================================
--- sys/powerpc/powerpc/openpic.c
+++ sys/powerpc/powerpc/openpic.c
@@ -127,11 +127,14 @@
break;
sc->sc_intr = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &sc->sc_irq, RF_ACTIVE);
+ &sc->sc_irq, 0 /* Activate later */);
- /* XXX Cascaded PICs pass NULL trapframes! */
- bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_MISC | INTR_MPSAFE,
- openpic_intr, NULL, dev, &sc->sc_icookie);
+ /*
+ * If this is attaching late (which will probably fail),
+ * immediately set up the parent interrupt.
+ */
+ if (bus_current_pass > BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST)
+ openpic_new_pass(dev);
} while (0);
/* Reset the PIC */
@@ -226,6 +229,26 @@
return (0);
}
+void
+openpic_new_pass(device_t dev)
+{
+ struct openpic_softc *sc;
+
+ if (bus_current_pass <= BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST)
+ return;
+
+ sc = device_get_softc(dev);
+
+ if (sc->sc_intr == NULL || (rman_get_flags(sc->sc_intr) & RF_ACTIVE))
+ return;
+
+ bus_activate_resource(dev, SYS_RES_IRQ, sc->sc_irq, sc->sc_intr);
+
+ /* XXX Cascaded PICs pass NULL trapframes! */
+ bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_MISC | INTR_MPSAFE,
+ openpic_intr, NULL, dev, &sc->sc_icookie);
+}
+
/*
* PIC I/F methods
*/
Index: sys/powerpc/ps3/ps3pic.c
===================================================================
--- sys/powerpc/ps3/ps3pic.c
+++ sys/powerpc/ps3/ps3pic.c
@@ -91,7 +91,8 @@
static devclass_t ps3pic_devclass;
-DRIVER_MODULE(ps3pic, nexus, ps3pic_driver, ps3pic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(ps3pic, nexus, ps3pic_driver, ps3pic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
static MALLOC_DEFINE(M_PS3PIC, "ps3pic", "PS3 PIC");
Index: sys/powerpc/psim/iobus.c
===================================================================
--- sys/powerpc/psim/iobus.c
+++ sys/powerpc/psim/iobus.c
@@ -116,7 +116,8 @@
devclass_t iobus_devclass;
-DRIVER_MODULE(iobus, ofwbus, iobus_driver, iobus_devclass, 0, 0);
+EARLY_DRIVER_MODULE(iobus, ofwbus, iobus_driver, iobus_devclass, 0, 0,
+ BUS_PASS_BUS);
static int
iobus_probe(device_t dev)
Index: sys/powerpc/psim/openpic_iobus.c
===================================================================
--- sys/powerpc/psim/openpic_iobus.c
+++ sys/powerpc/psim/openpic_iobus.c
@@ -69,6 +69,7 @@
/* Device interface */
DEVMETHOD(device_probe, openpic_iobus_probe),
DEVMETHOD(device_attach, openpic_iobus_attach),
+ DEVMETHOD(bus_new_pass, openpic_new_pass),
/* PIC interface */
DEVMETHOD(pic_config, openpic_config),
@@ -88,7 +89,8 @@
sizeof(struct openpic_softc)
};
-DRIVER_MODULE(openpic, iobus, openpic_iobus_driver, openpic_devclass, 0, 0);
+EARLY_DRIVER_MODULE(openpic, iobus, openpic_iobus_driver, openpic_devclass, 0,
+ 0, BUS_PASS_INTERRUPT);
static int
openpic_iobus_probe(device_t dev)

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 18, 1:28 AM (3 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29814260
Default Alt Text
D7585.diff (20 KB)

Event Timeline