예제 #1
0
파일: aintc.c 프로젝트: ChaosJohn/freebsd
static int
ti_aintc_attach(device_t dev)
{
	struct		ti_aintc_softc *sc = device_get_softc(dev);
	uint32_t x;

	sc->sc_dev = dev;

	if (ti_aintc_sc)
		return (ENXIO);

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

	sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]);
	sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]);

	ti_aintc_sc = sc;

	x = aintc_read_4(INTC_REVISION);
	device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);

	/* SoftReset */
	aintc_write_4(INTC_SYSCONFIG, 2);

	/* Wait for reset to complete */
	while(!(aintc_read_4(INTC_SYSSTATUS) & 1));

	/*Set Priority Threshold */
	aintc_write_4(INTC_THRESHOLD, 0xFF);

	return (0);
}
예제 #2
0
파일: aintc.c 프로젝트: LynYang/freebsd
void
arm_mask_irq(uintptr_t nb)
{
	uint32_t bit, block, value;
	
	bit = (nb % 32);
	block = (nb / 32);

	value = aintc_read_4(SW_INT_ENABLE_REG(block));
	value &= ~(1 << bit);
	aintc_write_4(SW_INT_ENABLE_REG(block), value);

	value = aintc_read_4(SW_INT_MASK_REG(block));
	value |= (1 << bit);
	aintc_write_4(SW_INT_MASK_REG(block), value);
}
예제 #3
0
static void
a10_intr_mask(struct a10_aintc_softc *sc, u_int irq)
{
	uint32_t bit, block, value;

	bit = (irq % 32);
	block = (irq / 32);

	mtx_lock_spin(&sc->mtx);
	value = aintc_read_4(sc, SW_INT_ENABLE_REG(block));
	value &= ~(1 << bit);
	aintc_write_4(sc, SW_INT_ENABLE_REG(block), value);

	value = aintc_read_4(sc, SW_INT_MASK_REG(block));
	value |= (1 << bit);
	aintc_write_4(sc, SW_INT_MASK_REG(block), value);
	mtx_unlock_spin(&sc->mtx);
}
예제 #4
0
파일: aintc.c 프로젝트: LynYang/freebsd
void
arm_unmask_irq(uintptr_t nb)
{
	uint32_t bit, block, value;

	bit = (nb % 32);
	block = (nb / 32);

	value = aintc_read_4(SW_INT_ENABLE_REG(block));
	value |= (1 << bit);
	aintc_write_4(SW_INT_ENABLE_REG(block), value);

	value = aintc_read_4(SW_INT_MASK_REG(block));
	value &= ~(1 << bit);
	aintc_write_4(SW_INT_MASK_REG(block), value);

	if(nb == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */
		aintc_write_4(SW_INT_IRQ_PENDING_REG(0), (1 << SW_INT_IRQNO_ENMI));
}
예제 #5
0
파일: aintc.c 프로젝트: LynYang/freebsd
int
arm_get_next_irq(int last_irq)
{
	uint32_t value;
	int i, b;

	for (i = 0; i < 3; i++) {
		value = aintc_read_4(SW_INT_IRQ_PENDING_REG(i));
		for (b = 0; b < 32; b++)
			if (value & (1 << b)) {
				return (i * 32 + b);
			}
	}

	return (-1);
}
예제 #6
0
static int
a10_pending_irq(struct a10_aintc_softc *sc)
{
	uint32_t value;
	int i, b;

	for (i = 0; i < 3; i++) {
		value = aintc_read_4(sc, SW_INT_IRQ_PENDING_REG(i));
		if (value == 0)
			continue;
		for (b = 0; b < 32; b++)
			if (value & (1 << b)) {
				return (i * 32 + b);
			}
	}

	return (-1);
}
예제 #7
0
파일: aintc.c 프로젝트: ChaosJohn/freebsd
DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0);

int
arm_get_next_irq(int last_irq)
{
	uint32_t active_irq;

	if (last_irq != -1) {
		aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5),
			1UL << (last_irq & 0x1F));
		aintc_write_4(INTC_CONTROL,1);
	}

	/* Get the next active interrupt */
	active_irq = aintc_read_4(INTC_SIR_IRQ);

	/* Check for spurious interrupt */
	if ((active_irq & 0xffffff80)) {
		device_printf(ti_aintc_sc->sc_dev,
			"Spurious interrupt detected (0x%08x)\n", active_irq);
		aintc_write_4(INTC_SIR_IRQ, 0);
		return -1;
	}

	if (active_irq != last_irq)
		return active_irq;
	else
		return -1;
}