Index: head/sys/arm64/arm64/gic.h =================================================================== --- head/sys/arm64/arm64/gic.h +++ head/sys/arm64/arm64/gic.h @@ -51,6 +51,16 @@ uint32_t nirqs; }; +DECLARE_CLASS(arm_gicv2m_driver); + +struct gicv2m_softc { + struct resource *sc_mem; + struct mtx sc_mutex; + u_int sc_spi_start; + u_int sc_spi_count; + u_int sc_spi_offset; +}; + int arm_gic_attach(device_t); #endif Index: head/sys/arm64/arm64/gic.c =================================================================== --- head/sys/arm64/arm64/gic.c +++ head/sys/arm64/arm64/gic.c @@ -355,22 +355,6 @@ #define GICv2M_MSI_SETSPI_NS 0x040 #define GICV2M_MSI_IIDR 0xFCC -struct gicv2m_softc { - struct resource *sc_mem; - struct mtx sc_mutex; - u_int sc_spi_start; - u_int sc_spi_count; - u_int sc_spi_offset; -}; - -static int -gicv2m_probe(device_t dev) -{ - - device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX"); - return (BUS_PROBE_DEFAULT); -} - static int gicv2m_attach(device_t dev) { @@ -478,7 +462,6 @@ static device_method_t arm_gicv2m_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, gicv2m_probe), DEVMETHOD(device_attach, gicv2m_attach), /* MSI/MSI-X */ @@ -489,9 +472,5 @@ { 0, 0 } }; -static devclass_t arm_gicv2m_devclass; - DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods, sizeof(struct gicv2m_softc)); -EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_driver, arm_gicv2m_devclass, - 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); Index: head/sys/arm64/arm64/gic_fdt.c =================================================================== --- head/sys/arm64/arm64/gic_fdt.c +++ head/sys/arm64/arm64/gic_fdt.c @@ -290,3 +290,38 @@ arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_fdt_driver, arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); + +static struct ofw_compat_data gicv2m_compat_data[] = { + {"arm,gic-v2m-frame", true}, + {NULL, false} +}; + +static int +arm_gicv2m_fdt_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, gicv2m_compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX"); + return (BUS_PROBE_DEFAULT); +} + +static device_method_t arm_gicv2m_fdt_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, arm_gicv2m_fdt_probe), + + /* End */ + DEVMETHOD_END +}; + +DEFINE_CLASS_1(gicv2m, arm_gicv2m_fdt_driver, arm_gicv2m_fdt_methods, + sizeof(struct gicv2m_softc), arm_gicv2m_driver); + +static devclass_t arm_gicv2m_fdt_devclass; + +EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_fdt_driver, + arm_gicv2m_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);