Esempio n. 1
0
static int
mtk_pic_intr(void *arg)
{
	struct mtk_pic_softc *sc = arg;
	struct thread *td;
	uint32_t i, intr;

	td = curthread;
	/* Workaround: do not inflate intr nesting level */
	td->td_intr_nesting_level--;

#ifdef _notyet_
	intr = READ4(sc, MTK_IRQ1STAT);
	while ((i = fls(intr)) != 0) {
		i--;
		intr &= ~(1u << i);

		if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i),
		    curthread->td_intr_frame) != 0) {
			device_printf(sc->pic_dev,
			    "Stray interrupt %u detected\n", i);
			pic_irq_mask(sc, i);
			continue;
		}
	}

	KASSERT(i == 0, ("all interrupts handled"));
#endif

	intr = READ4(sc, MTK_IRQ0STAT);

	while ((i = fls(intr)) != 0) {
		i--;
		intr &= ~(1u << i);

		if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i),
		    curthread->td_intr_frame) != 0) {
			device_printf(sc->pic_dev,
				"Stray interrupt %u detected\n", i);
			pic_irq_mask(sc, i);
			continue;
		}
	}

	KASSERT(i == 0, ("all interrupts handled"));

	td->td_intr_nesting_level++;

	return (FILTER_HANDLED);
}
Esempio n. 2
0
static int
mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
    struct intr_irqsrc **isrcp)
{
	int error;
	u_int irq;
	struct mtk_gpio_softc *sc;

	sc = device_get_softc(dev);
	switch (data->type) {
	case INTR_MAP_DATA_FDT:
		error = (mtk_gpio_pic_map_fdt(sc, 
		    (struct intr_map_data_fdt *)data, &irq, NULL));
		break;
	case INTR_MAP_DATA_GPIO:
		error = (mtk_gpio_pic_map_gpio(sc, 
		    (struct intr_map_data_gpio *)data, &irq, NULL));
		break;
	default:
		error = EINVAL;
		break;
	}

	if (error != 0) {
		device_printf(dev, "Invalid map type\n");
		return (error);
	}

	*isrcp = PIC_INTR_ISRC(sc, irq);
	return (0);
}
Esempio n. 3
0
static int
mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
    struct intr_irqsrc **isrcp)
{
	struct mtk_gpio_softc *sc;

	sc = device_get_softc(dev);

	if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
	    data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->num_pins)
		return (EINVAL);

	*isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
	return (0);
}
Esempio n. 4
0
static int
apb_filter(void *arg)
{
	struct apb_softc *sc = arg;
	struct thread *td;
	uint32_t i, intr;

	td = curthread;
	/* Workaround: do not inflate intr nesting level */
	td->td_intr_nesting_level--;

	if(ar531x_soc >= AR531X_SOC_AR5315)
		intr = ATH_READ_REG(AR5315_SYSREG_BASE +
			AR5315_SYSREG_MISC_INTSTAT);
	else
		intr = ATH_READ_REG(AR5312_SYSREG_BASE +
			AR5312_SYSREG_MISC_INTSTAT);

	while ((i = fls(intr)) != 0) {
		i--;
		intr &= ~(1u << i);

		if(i == 1 && ar531x_soc < AR531X_SOC_AR5315) {
			ATH_READ_REG(AR5312_SYSREG_BASE +
			    AR5312_SYSREG_AHBPERR);
			ATH_READ_REG(AR5312_SYSREG_BASE +
			    AR5312_SYSREG_AHBDMAE);
		}

		if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i),
		    curthread->td_intr_frame) != 0) {
			device_printf(sc->apb_dev,
			    "Stray interrupt %u detected\n", i);
			apb_mask_irq((void*)i);
			continue;
		}
	}

	KASSERT(i == 0, ("all interrupts handled"));

	td->td_intr_nesting_level++;

	return (FILTER_HANDLED);

}
Esempio n. 5
0
static int
mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
    struct intr_irqsrc **isrcp)
{
	struct intr_map_data_fdt *daf;
	struct mtk_gpio_softc *sc;

	if (data->type != INTR_MAP_DATA_FDT)
		return (ENOTSUP);

	sc = device_get_softc(dev);
	daf = (struct intr_map_data_fdt *)data;

	if (daf->ncells != 1 || daf->cells[0] >= sc->num_pins)
		return (EINVAL);

	*isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
	return (0);
}
Esempio n. 6
0
static int
mtk_gpio_intr(void *arg)
{
	struct mtk_gpio_softc *sc;
	uint32_t i, interrupts;

	sc = arg;
	interrupts = MTK_READ_4(sc, GPIO_PIOINT);

	for (i = 0; interrupts != 0; i++, interrupts >>= 1) {
		if ((interrupts & 0x1) == 0)
			continue;
		if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i),
		    curthread->td_intr_frame) != 0) {
			device_printf(sc->dev, "spurious interrupt %d\n", i);
		}
	}       

	return (FILTER_HANDLED);
}
Esempio n. 7
0
static int
mtk_pic_register_isrcs(struct mtk_gpio_softc *sc)
{
	int error;
	uint32_t irq;
	struct intr_irqsrc *isrc;
	const char *name;

	name = device_get_nameunit(sc->dev);
	for (irq = 0; irq < sc->num_pins; irq++) {
		sc->pins[irq].pin_irqsrc.irq = irq;
		isrc = PIC_INTR_ISRC(sc, irq);
		error = intr_isrc_register(isrc, sc->dev, 0, "%s", name);
		if (error != 0) {
			/* XXX call intr_isrc_deregister */
			device_printf(sc->dev, "%s failed", __func__);
			return (error);
		}
	}

	return (0);
}
Esempio n. 8
0
static int
apb_setup_intr(device_t bus, device_t child, struct resource *ires,
		int flags, driver_filter_t *filt, driver_intr_t *handler,
		void *arg, void **cookiep)
{
	struct apb_softc *sc = device_get_softc(bus);
	int error;
	int irq;
#ifndef INTRNG
	struct intr_event *event;
#endif

#ifdef INTRNG
	struct intr_irqsrc *isrc;
	const char *name;
	
	if ((rman_get_flags(ires) & RF_SHAREABLE) == 0)
		flags |= INTR_EXCL;

	irq = rman_get_start(ires);
	isrc = PIC_INTR_ISRC(sc, irq);
	if(isrc->isrc_event == 0) {
		error = intr_event_create(&isrc->isrc_event, (void *)irq,
		    0, irq, apb_mask_irq, apb_unmask_irq,
		    NULL, NULL, "apb intr%d:", irq);
		if(error != 0)
			return(error);
	}
	name = device_get_nameunit(child);
	error = intr_event_add_handler(isrc->isrc_event, name, filt, handler,
            arg, intr_priority(flags), flags, cookiep);
	return(error);
#else
	irq = rman_get_start(ires);

	if (irq > APB_IRQ_END)
		panic("%s: bad irq %d", __func__, irq);

	event = sc->sc_eventstab[irq];
	if (event == NULL) {
		error = intr_event_create(&event, (void *)irq, 0, irq, 
		    apb_mask_irq, apb_unmask_irq,
		    NULL, NULL,
		    "apb intr%d:", irq);

		if (error == 0) {
			sc->sc_eventstab[irq] = event;
			sc->sc_intr_counter[irq] =
			    mips_intrcnt_create(event->ie_name);
		}
		else
			return (error);
	}

	intr_event_add_handler(event, device_get_nameunit(child), filt,
	    handler, arg, intr_priority(flags), flags, cookiep);
	mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname);

	apb_unmask_irq((void*)irq);

	return (0);
#endif
}