static int gic_acpi_attach(device_t dev) { struct arm_gic_softc *sc = device_get_softc(dev); intptr_t xref; int err; sc->gic_bus = GIC_BUS_ACPI; err = arm_gic_attach(dev); if (err != 0) return (err); xref = ACPI_INTR_XREF; /* * Now, when everything is initialized, it's right time to * register interrupt controller to interrupt framefork. */ if (intr_pic_register(dev, xref) == NULL) { device_printf(dev, "could not register PIC\n"); goto cleanup; } /* * Controller is root: */ if (intr_pic_claim_root(dev, xref, arm_gic_intr, sc, GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) { device_printf(dev, "could not set PIC as a root\n"); intr_pic_deregister(dev, xref); goto cleanup; } /* If we have children probe and attach them */ if (arm_gic_add_children(dev)) { bus_generic_probe(dev); return (bus_generic_attach(dev)); } return (0); cleanup: arm_gic_detach(dev); return(ENXIO); }
static int arm_gic_fdt_attach(device_t dev) { struct arm_gic_fdt_softc *sc = device_get_softc(dev); phandle_t root, child; struct gic_devinfo *dinfo; device_t cdev; int err; err = arm_gic_attach(dev); if (err != 0) return (err); root = ofw_bus_get_node(dev); sc->sc_host_cells = 1; OF_getencprop(OF_parent(root), "#address-cells", &sc->sc_host_cells, sizeof(sc->sc_host_cells)); sc->sc_addr_cells = 2; OF_getencprop(root, "#address-cells", &sc->sc_addr_cells, sizeof(sc->sc_addr_cells)); sc->sc_size_cells = 2; OF_getencprop(root, "#size-cells", &sc->sc_size_cells, sizeof(sc->sc_size_cells)); /* If we have no children don't probe for them */ child = OF_child(root); if (child == 0) return (0); if (gic_fill_ranges(root, sc) < 0) { device_printf(dev, "could not get ranges\n"); return (ENXIO); } for (; child != 0; child = OF_peer(child)) { dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&dinfo->obdinfo, child) != 0) { free(dinfo, M_DEVBUF); continue; } resource_list_init(&dinfo->rl); ofw_bus_reg_to_rl(dev, child, sc->sc_addr_cells, sc->sc_size_cells, &dinfo->rl); cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", dinfo->obdinfo.obd_name); resource_list_free(&dinfo->rl); ofw_bus_gen_destroy_devinfo(&dinfo->obdinfo); free(dinfo, M_DEVBUF); continue; } device_set_ivars(cdev, dinfo); } bus_generic_probe(dev); return (bus_generic_attach(dev)); }