Example #1
0
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);
}
Example #2
0
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));
}