Example #1
0
static int
mv_cp110_icu_attach(device_t dev)
{
	struct mv_cp110_icu_softc *sc;
	phandle_t node, msi_parent;

	sc = device_get_softc(dev);
	sc->dev = dev;
	node = ofw_bus_get_node(dev);

	if (OF_getencprop(node, "msi-parent", &msi_parent,
	    sizeof(phandle_t)) <= 0) {
		device_printf(dev, "cannot find msi-parent property\n");
		return (ENXIO);
	}

	if ((sc->parent = OF_device_from_xref(msi_parent)) == NULL) {
		device_printf(dev, "cannot find msi-parent device\n");
		return (ENXIO);
	}
	if (bus_alloc_resources(dev, mv_cp110_icu_res_spec, &sc->res) != 0) {
		device_printf(dev, "cannot allocate resources for device\n");
		return (ENXIO);
	}

	if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
		device_printf(dev, "Cannot register ICU\n");
		goto fail;
	}
	return (0);

fail:
	bus_release_resources(dev, mv_cp110_icu_res_spec, &sc->res);
	return (ENXIO);
}
Example #2
0
static int
rt1310_pic_attach(struct rt1310_intc_softc *sc)
{
	struct intr_pic *pic;
	int error;
	uint32_t irq;
	const char *name;
	intptr_t xref;

	name = device_get_nameunit(sc->dev);
	for (irq = 0; irq < INTC_NIRQS; irq++) {
		sc->ri_isrcs[irq].ri_irq = irq;

		error = intr_isrc_register(&sc->ri_isrcs[irq].ri_isrc,
		    sc->dev, 0, "%s,%u", name, irq);
		if (error != 0)
			return (error);
	}

	xref = OF_xref_from_node(ofw_bus_get_node(sc->dev));
	pic = intr_pic_register(sc->dev, xref);
	if (pic == NULL)
		return (ENXIO);

	return (intr_pic_claim_root(sc->dev, xref, rt1310_intr, sc, 0));
}
Example #3
0
static int
tegra_gpio_pic_attach(struct tegra_gpio_softc *sc)
{
	int error;
	uint32_t irq;
	const char *name;

	sc->isrcs = malloc(sizeof(*sc->isrcs) * sc->gpio_npins, M_DEVBUF,
	    M_WAITOK | M_ZERO);

	name = device_get_nameunit(sc->dev);
	for (irq = 0; irq < sc->gpio_npins; irq++) {
		sc->isrcs[irq].irq = irq;
		sc->isrcs[irq].cfgreg = 0;
		error = intr_isrc_register(&sc->isrcs[irq].isrc,
		    sc->dev, 0, "%s,%u", name, irq);
		if (error != 0)
			return (error); /* XXX deregister ISRCs */
	}
	if (intr_pic_register(sc->dev,
	    OF_xref_from_node(ofw_bus_get_node(sc->dev))) == NULL)
		return (ENXIO);

	return (0);
}
Example #4
0
static int
ti_gpio_pic_attach(struct ti_gpio_softc *sc)
{
	int error;
	uint32_t irq;
	const char *name;

	sc->sc_isrcs = malloc(sizeof(*sc->sc_isrcs) * sc->sc_maxpin, M_DEVBUF,
	    M_WAITOK | M_ZERO);

	name = device_get_nameunit(sc->sc_dev);
	for (irq = 0; irq < sc->sc_maxpin; irq++) {
		sc->sc_isrcs[irq].tgi_irq = irq;
		sc->sc_isrcs[irq].tgi_mask = TI_GPIO_MASK(irq);
		sc->sc_isrcs[irq].tgi_mode = GPIO_INTR_CONFORM;

		error = intr_isrc_register(&sc->sc_isrcs[irq].tgi_isrc,
		    sc->sc_dev, 0, "%s,%u", name, irq);
		if (error != 0)
			return (error); /* XXX deregister ISRCs */
	}
	if (intr_pic_register(sc->sc_dev,
	    OF_xref_from_node(ofw_bus_get_node(sc->sc_dev))) == NULL)
		return (ENXIO);

	return (0);
}
Example #5
0
static int
mtk_pic_attach(device_t dev)
{
	struct mtk_pic_softc *sc;
	intptr_t xref = pic_xref(dev);

	sc = device_get_softc(dev);

	if (bus_alloc_resources(dev, mtk_pic_spec, sc->pic_res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	sc->pic_dev = dev;

	/* Initialize mutex */
	mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN);

	/* Set the number of interrupts */
	sc->nirqs = nitems(sc->pic_irqs);

	/* Mask all interrupts */
	WRITE4(sc, MTK_INTDIS, 0xFFFFFFFF);

	/* But enable interrupt generation/masking */
	WRITE4(sc, MTK_INTENA, 0x00000000);

	/* Set all interrupts to type 0 */
	WRITE4(sc, MTK_INTTYPE, 0xFFFFFFFF);

	/* Register the interrupts */
	if (mtk_pic_register_isrcs(sc) != 0) {
		device_printf(dev, "could not register PIC ISRCs\n");
		goto cleanup;
	}

	/*
	 * 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;
	}

	if (bus_setup_intr(dev, sc->pic_res[1], INTR_TYPE_CLK,
	    mtk_pic_intr, NULL, sc, &sc->pic_intrhand)) {
		device_printf(dev, "could not setup irq handler\n");
		intr_pic_deregister(dev, xref);
		goto cleanup;
	}
	return (0);

cleanup:
	bus_release_resources(dev, mtk_pic_spec, sc->pic_res);
	return(ENXIO);
}
Example #6
0
static int
aw_nmi_attach(device_t dev)
{
	struct aw_nmi_softc *sc;
	phandle_t xref;

	sc = device_get_softc(dev);
	sc->dev = dev;

	if (bus_alloc_resources(dev, aw_nmi_res_spec, sc->res) != 0) {
		device_printf(dev, "can't allocate device resources\n");
		return (ENXIO);
	}
	if ((bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC,
	    aw_nmi_intr, NULL, sc, &sc->intrcookie))) {
		device_printf(dev, "unable to register interrupt handler\n");
		bus_release_resources(dev, aw_nmi_res_spec, sc->res);
		return (ENXIO);
	}

	switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
	case A20_NMI:
		sc->enable_reg = A20_NMI_IRQ_ENABLE_REG;
		break;
	case A31_NMI:
		sc->enable_reg = A31_NMI_IRQ_ENABLE_REG;
		break;
	}

	/* Disable and clear interrupts */
	SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
	SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK);

	xref = OF_xref_from_node(ofw_bus_get_node(dev));
	/* Register our isrc */
	sc->intr.irq = 0;
	sc->intr.pol = INTR_POLARITY_CONFORM;
	sc->intr.tri = INTR_TRIGGER_CONFORM;
	if (intr_isrc_register(&sc->intr.isrc, sc->dev, 0, "%s,%u",
	      device_get_nameunit(sc->dev), sc->intr.irq) != 0)
		goto error;

	if (intr_pic_register(dev, (intptr_t)xref) == NULL) {
		device_printf(dev, "could not register pic\n");
		goto error;
	}
	return (0);

error:
	bus_teardown_intr(dev, sc->res[1], sc->intrcookie);
	bus_release_resources(dev, aw_nmi_res_spec, sc->res);
	return (ENXIO);
}
Example #7
0
static int
gic_v3_acpi_attach(device_t dev)
{
	struct gic_v3_softc *sc;
	int err;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->gic_bus = GIC_BUS_ACPI;

	err = gic_v3_acpi_count_regions(dev);
	if (err != 0)
		goto error;

	err = gic_v3_attach(dev);
	if (err != 0)
		goto error;

	sc->gic_pic = intr_pic_register(dev, ACPI_INTR_XREF);
	if (sc->gic_pic == NULL) {
		device_printf(dev, "could not register PIC\n");
		err = ENXIO;
		goto error;
	}

	if (intr_pic_claim_root(dev, ACPI_INTR_XREF, arm_gic_v3_intr, sc,
	    GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) {
		err = ENXIO;
		goto error;
	}

	/*
	 * Try to register the ITS driver to this GIC. The GIC will act as
	 * a bus in that case. Failure here will not affect the main GIC
	 * functionality.
	 */
	gic_v3_acpi_bus_attach(dev);

	if (device_get_children(dev, &sc->gic_children, &sc->gic_nchildren) !=0)
		sc->gic_nchildren = 0;

	return (0);

error:
	if (bootverbose) {
		device_printf(dev,
		    "Failed to attach. Error %d\n", err);
	}
	/* Failure so free resources */
	gic_v3_detach(dev);

	return (err);
}
Example #8
0
static int
tegra_lic_attach(device_t dev)
{
	struct tegra_lic_sc *sc;
	phandle_t node;
	phandle_t parent_xref;
	int i, rv;

	sc = device_get_softc(dev);
	sc->dev = dev;
	node = ofw_bus_get_node(dev);

	rv = OF_getencprop(node, "interrupt-parent", &parent_xref,
	    sizeof(parent_xref));
	if (rv <= 0) {
		device_printf(dev, "Cannot read parent node property\n");
		goto fail;
	}
	sc->parent = OF_device_from_xref(parent_xref);
	if (sc->parent == NULL) {
		device_printf(dev, "Cannott find parent controller\n");
		goto fail;
	}

	if (bus_alloc_resources(dev, lic_spec, sc->mem_res)) {
		device_printf(dev, "Cannott allocate resources\n");
		goto fail;
	}

	/* Disable all interrupts, route all to irq */
	for (i = 0; i < nitems(lic_spec); i++) {
		if (sc->mem_res[i] == NULL)
			continue;
		WR4(sc, i, LIC_CPU_IER_CLR, 0xFFFFFFFF);
		WR4(sc, i, LIC_CPU_IEP_CLASS, 0);
	}


	if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
		device_printf(dev, "Cannot register PIC\n");
		goto fail;
	}
	return (0);

fail:
	bus_release_resources(dev, lic_spec, sc->mem_res);
	return (ENXIO);
}
Example #9
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 #10
0
static int
omap4_wugen_attach(device_t dev)
{
	struct omap4_wugen_sc *sc;
	phandle_t node;
	phandle_t parent_xref;
	int rid, rv;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	node = ofw_bus_get_node(dev);

	rv = OF_getencprop(node, "interrupt-parent", &parent_xref,
	    sizeof(parent_xref));
	if (rv <= 0) {
		device_printf(dev, "can't read parent node property\n");
		goto fail;
	}
	sc->sc_parent = OF_device_from_xref(parent_xref);
	if (sc->sc_parent == NULL) {
		device_printf(dev, "can't find parent controller\n");
		goto fail;
	}

	rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_mem_res == NULL) {
		device_printf(dev, "can't allocate resources\n");
		return (ENXIO);
	}

	if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
		device_printf(dev, "can't register PIC\n");
		goto fail;
	}
	return (0);

fail:
	omap4_wugen_detach(dev);
	return (ENXIO);
}
Example #11
0
static int
mips_pic_attach(device_t dev)
{
	struct		mips_pic_softc *sc;
	intptr_t	xref = pic_xref(dev);

	if (pic_sc)
		return (ENXIO);

	sc = device_get_softc(dev);

	sc->pic_dev = dev;
	pic_sc = sc;

	/* Initialize mutex */
	mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN);

	/* Set the number of interrupts */
	sc->nirqs = nitems(sc->pic_irqs);

	/*
	 * Now, when everything is initialized, it's right time to
	 * register interrupt controller to interrupt framefork.
	 */
	if (intr_pic_register(dev, xref) != 0) {
		device_printf(dev, "could not register PIC\n");
		goto cleanup;
	}

	/* Claim our root controller role */
	if (intr_pic_claim_root(dev, xref, mips_pic_intr, sc, 0) != 0) {
		device_printf(dev, "could not set PIC as a root\n");
		intr_pic_unregister(dev, xref);
		goto cleanup;
	}

	return (0);

cleanup:
	return(ENXIO);
}
Example #12
0
static int
bcm_intc_pic_register(struct bcm_intc_softc *sc, intptr_t xref)
{
	struct bcm_intc_irqsrc *bii;
	int error;
	uint32_t irq;
	const char *name;

	name = device_get_nameunit(sc->sc_dev);
	for (irq = 0; irq < BCM_INTC_NIRQS; irq++) {
		bii = &sc->intc_isrcs[irq];
		bii->bii_irq = irq;
		if (IS_IRQ_BASIC(irq)) {
			bii->bii_disable_reg = INTC_DISABLE_BASIC;
			bii->bii_enable_reg = INTC_ENABLE_BASIC;
			bii->bii_mask = 1 << irq;
		} else if (IS_IRQ_BANK1(irq)) {
			bii->bii_disable_reg = INTC_DISABLE_BANK1;
			bii->bii_enable_reg = INTC_ENABLE_BANK1;
			bii->bii_mask = 1 << IRQ_BANK1(irq);
		} else if (IS_IRQ_BANK2(irq)) {
			bii->bii_disable_reg = INTC_DISABLE_BANK2;
			bii->bii_enable_reg = INTC_ENABLE_BANK2;
			bii->bii_mask = 1 << IRQ_BANK2(irq);
		} else
			return (ENXIO);

		error = intr_isrc_register(&bii->bii_isrc, sc->sc_dev, 0,
		    "%s,%u", name, irq);
		if (error != 0)
			return (error);
	}
	if (intr_pic_register(sc->sc_dev, xref) == NULL)
		return (ENXIO);

	return (0);
}
Example #13
0
static int
pl190_intc_attach(device_t dev)
{
	struct		pl190_intc_softc *sc;
	uint32_t	id;
	int		i, rid;
	struct		pl190_intc_irqsrc *isrcs;
	struct intr_pic *pic;
	int		error;
	uint32_t	irq;
	const char	*name;
	phandle_t	xref;

	sc = device_get_softc(dev);
	sc->dev = dev;
	mtx_init(&sc->mtx, device_get_nameunit(dev), "pl190",
	    MTX_SPIN);

	/* Request memory resources */
	rid = 0;
	sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->intc_res == NULL) {
		device_printf(dev, "Error: could not allocate memory resources\n");
		return (ENXIO);
	}

	/*
	 * All interrupts should use IRQ line
	 */
	INTC_VIC_WRITE_4(sc, VICINTSELECT, 0x00000000);
	/* Disable all interrupts */
	INTC_VIC_WRITE_4(sc, VICINTENCLEAR, 0xffffffff);

	id = 0;
	for (i = 3; i >= 0; i--) {
		id = (id << 8) |
		     (INTC_VIC_READ_4(sc, VICPERIPHID + i*4) & 0xff);
	}

	device_printf(dev, "Peripheral ID: %08x\n", id);

	id = 0;
	for (i = 3; i >= 0; i--) {
		id = (id << 8) |
		     (INTC_VIC_READ_4(sc, VICPRIMECELLID + i*4) & 0xff);
	}

	device_printf(dev, "PrimeCell ID: %08x\n", id);

	/* PIC attachment */
	isrcs = sc->isrcs;
	name = device_get_nameunit(sc->dev);
	for (irq = 0; irq < VIC_NIRQS; irq++) {
		isrcs[irq].irq = irq;
		error = intr_isrc_register(&isrcs[irq].isrc, sc->dev,
		    0, "%s,%u", name, irq);
		if (error != 0)
			return (error);
	}

	xref = OF_xref_from_node(ofw_bus_get_node(sc->dev));
	pic = intr_pic_register(sc->dev, xref);
	if (pic == NULL)
		return (ENXIO);

	return (intr_pic_claim_root(sc->dev, xref, pl190_intc_intr, sc, 0));
}
Example #14
0
static int
mv_mpic_attach(device_t dev)
{
	struct mv_mpic_softc *sc;
	int error;
	uint32_t val;

	sc = (struct mv_mpic_softc *)device_get_softc(dev);

	if (mv_mpic_sc != NULL)
		return (ENXIO);
	mv_mpic_sc = sc;

	sc->sc_dev = dev;

	mtx_init(&sc->mtx, "MPIC lock", NULL, MTX_SPIN);

	error = bus_alloc_resources(dev, mv_mpic_spec, sc->mpic_res);
	if (error) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}
#ifdef ARM_INTRNG
	if (sc->mpic_res[3] == NULL)
		device_printf(dev, "No interrupt to use.\n");
	else
		bus_setup_intr(dev, sc->mpic_res[3], INTR_TYPE_CLK,
		    mpic_intr, NULL, sc, &sc->intr_hand);
#endif

	sc->mpic_bst = rman_get_bustag(sc->mpic_res[0]);
	sc->mpic_bsh = rman_get_bushandle(sc->mpic_res[0]);

	sc->cpu_bst = rman_get_bustag(sc->mpic_res[1]);
	sc->cpu_bsh = rman_get_bushandle(sc->mpic_res[1]);

	if (sc->mpic_res[2] != NULL) {
		/* This is required only if MSIs are used. */
		sc->drbl_bst = rman_get_bustag(sc->mpic_res[2]);
		sc->drbl_bsh = rman_get_bushandle(sc->mpic_res[2]);
	}

	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
	    MPIC_CTRL, 1);
	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);

	val = MPIC_READ(mv_mpic_sc, MPIC_CTRL);
	sc->nirqs = MPIC_CTRL_NIRQS(val);

#ifdef ARM_INTRNG
	sc->mpic_isrcs = malloc(sc->nirqs * sizeof (*sc->mpic_isrcs), M_DEVBUF,
	    M_WAITOK | M_ZERO);

	if (intr_pic_register(dev, OF_xref_from_device(dev)) != 0) {
		device_printf(dev, "could not register PIC\n");
		bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
		return (ENXIO);
	}
#endif

	mpic_unmask_msi();

	return (0);
}
Example #15
0
static int
apb_attach(device_t dev)
{
	struct apb_softc *sc = device_get_softc(dev);
#ifdef INTRNG
	intptr_t xref = pic_xref(dev);
	int miscirq;
#else
	int rid = 0;
#endif

	sc->apb_dev = dev;

	sc->apb_mem_rman.rm_type = RMAN_ARRAY;
	sc->apb_mem_rman.rm_descr = "APB memory window";

	if(ar531x_soc >= AR531X_SOC_AR5315) {
		if (rman_init(&sc->apb_mem_rman) != 0 ||
		    rman_manage_region(&sc->apb_mem_rman, 
			AR5315_APB_BASE, 
			AR5315_APB_BASE + AR5315_APB_SIZE - 1) != 0)
			panic("apb_attach: failed to set up memory rman");
	} else {
		if (rman_init(&sc->apb_mem_rman) != 0 ||
		    rman_manage_region(&sc->apb_mem_rman, 
			AR5312_APB_BASE, 
			AR5312_APB_BASE + AR5312_APB_SIZE - 1) != 0)
			panic("apb_attach: failed to set up memory rman");
	}

	sc->apb_irq_rman.rm_type = RMAN_ARRAY;
	sc->apb_irq_rman.rm_descr = "APB IRQ";

	if (rman_init(&sc->apb_irq_rman) != 0 ||
	    rman_manage_region(&sc->apb_irq_rman, 
			APB_IRQ_BASE, APB_IRQ_END) != 0)
		panic("apb_attach: failed to set up IRQ rman");

#ifndef INTRNG
	if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, 
	    apb_filter, NULL, sc, &sc->sc_misc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}
#else
	/* Register the interrupts */
	if (apb_pic_register_isrcs(sc) != 0) {
		device_printf(dev, "could not register PIC ISRCs\n");
		return (ENXIO);
	}

	/*
	 * 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");
		return (ENXIO);
	}

	if(ar531x_soc >= AR531X_SOC_AR5315) {
		miscirq = AR5315_CPU_IRQ_MISC;
	} else {
		miscirq = AR5312_IRQ_MISC;
	}
	cpu_establish_hardintr("aric", apb_filter, NULL, sc, miscirq,
	    INTR_TYPE_MISC, NULL);
#endif

	/* mask all misc interrupt */
	if(ar531x_soc >= AR531X_SOC_AR5315) {
		ATH_WRITE_REG(AR5315_SYSREG_BASE
			+ AR5315_SYSREG_MISC_INTMASK, 0);
	} else {
		ATH_WRITE_REG(AR5312_SYSREG_BASE
			+ AR5312_SYSREG_MISC_INTMASK, 0);
	}

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	return (0);
}
Example #16
0
static int
gic_v3_fdt_attach(device_t dev)
{
	struct gic_v3_softc *sc;
	pcell_t redist_regions;
	intptr_t xref;
	int err;

	sc = device_get_softc(dev);
	sc->dev = dev;

	/*
	 * Recover number of the Re-Distributor regions.
	 */
	if (OF_getencprop(ofw_bus_get_node(dev), "#redistributor-regions",
	    &redist_regions, sizeof(redist_regions)) <= 0)
		sc->gic_redists.nregions = 1;
	else
		sc->gic_redists.nregions = redist_regions;

	err = gic_v3_attach(dev);
	if (err != 0)
		goto error;

	xref = OF_xref_from_node(ofw_bus_get_node(dev));
	sc->gic_pic = intr_pic_register(dev, xref);
	if (sc->gic_pic == NULL) {
		device_printf(dev, "could not register PIC\n");
		err = ENXIO;
		goto error;
	}

	/* Register xref */
	OF_device_register_xref(xref, dev);

	if (intr_pic_claim_root(dev, xref, arm_gic_v3_intr, sc,
	    GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) {
		err = ENXIO;
		goto error;
	}

	/*
	 * Try to register ITS to this GIC.
	 * GIC will act as a bus in that case.
	 * Failure here will not affect main GIC functionality.
	 */
	if (gic_v3_ofw_bus_attach(dev) != 0) {
		if (bootverbose) {
			device_printf(dev,
			    "Failed to attach ITS to this GIC\n");
		}
	}

	if (device_get_children(dev, &sc->gic_children, &sc->gic_nchildren) != 0)
		sc->gic_nchildren = 0;

	return (err);

error:
	if (bootverbose) {
		device_printf(dev,
		    "Failed to attach. Error %d\n", err);
	}
	/* Failure so free resources */
	gic_v3_detach(dev);

	return (err);
}
Example #17
0
static int
mtk_gpio_attach(device_t dev)
{
	struct mtk_gpio_softc *sc;
	phandle_t node;
	uint32_t i, num_pins;

	sc = device_get_softc(dev);
	sc->dev = dev;

	if (bus_alloc_resources(dev, mtk_gpio_spec, sc->res)) {
		device_printf(dev, "could not allocate resources for device\n");
		return (ENXIO);
	}

	MTK_GPIO_LOCK_INIT(sc);

	node = ofw_bus_get_node(dev);

	if (OF_hasprop(node, "clocks"))
		mtk_soc_start_clock(dev);
	if (OF_hasprop(node, "resets"))
		mtk_soc_reset_device(dev);

	if (OF_getprop(node, "ralink,register-map", sc->regs,
	    GPIO_PIOMAX) <= 0) {
		device_printf(dev, "Failed to read register map\n");
		return (ENXIO);
	}

	if (OF_hasprop(node, "ralink,num-gpios") && (OF_getencprop(node,
	    "ralink,num-gpios", &num_pins, sizeof(num_pins)) >= 0))
		sc->num_pins = num_pins;
	else
		sc->num_pins = MTK_GPIO_PINS;

	for (i = 0; i < sc->num_pins; i++) {
		sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
		    GPIO_PIN_INVIN | GPIO_PIN_INVOUT;
		sc->pins[i].intr_polarity = INTR_POLARITY_HIGH;
		sc->pins[i].intr_trigger = INTR_TRIGGER_EDGE;

		snprintf(sc->pins[i].pin_name, GPIOMAXNAME - 1, "gpio%c%d",
		    device_get_unit(dev) + 'a', i);
		sc->pins[i].pin_name[GPIOMAXNAME - 1] = '\0';

		mtk_gpio_pin_probe(sc, i);
	}

	if (mtk_pic_register_isrcs(sc) != 0) {
		device_printf(dev, "could not register PIC ISRCs\n");
		goto fail;
	}

	if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) {
		device_printf(dev, "could not register PIC\n");
		goto fail;
	}

	if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
	    mtk_gpio_intr, NULL, sc, &sc->intrhand) != 0)
		goto fail_pic;

	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL)
		goto fail_pic;

	return (0);
fail_pic:
	intr_pic_deregister(dev, OF_xref_from_node(node));
fail:
	if(sc->intrhand != NULL)
		bus_teardown_intr(dev, sc->res[1], sc->intrhand);
	bus_release_resources(dev, mtk_gpio_spec, sc->res);
	MTK_GPIO_LOCK_DESTROY(sc);
	return (ENXIO);
}
Example #18
0
static int
mtk_gic_attach(device_t dev)
{
	struct mtk_gic_softc *sc;
	intptr_t xref = gic_xref(dev);
	int i;

	sc = device_get_softc(dev);

	if (bus_alloc_resources(dev, mtk_gic_spec, sc->gic_res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	sc->gic_dev = dev;

	/* Initialize mutex */
	mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN);

	/* Set the number of interrupts */
	sc->nirqs = nitems(sc->gic_irqs);

	/* Mask all interrupts */
	WRITE4(sc, MTK_INTDIS, 0xFFFFFFFF);

	/* All interrupts are of type level */
	WRITE4(sc, MTK_INTTRIG, 0x00000000);

	/* All interrupts are of positive polarity */
	WRITE4(sc, MTK_INTPOL, 0xFFFFFFFF);

	/*
	 * Route all interrupts to pin 0 on VPE 0;
	 */
	for (i = 0; i < 32; i++) {
		WRITE4(sc, MTK_MAPPIN(i), MTK_PIN_BITS(0));
		WRITE4(sc, MTK_MAPVPE(i, 0), MTK_VPE_BITS(0));
	}

	/* Register the interrupts */
	if (mtk_gic_register_isrcs(sc) != 0) {
		device_printf(dev, "could not register GIC ISRCs\n");
		goto cleanup;
	}

	/*
	 * 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;
	}

	cpu_establish_hardintr("gic", mtk_gic_intr, NULL, sc, 0, INTR_TYPE_CLK,
	    NULL);

	return (0);

cleanup:
	bus_release_resources(dev, mtk_gic_spec, sc->gic_res);
	return(ENXIO);
}