Ejemplo n.º 1
0
static inline void
intr_write_modify(struct tegra_gpio_softc *sc, bus_addr_t reg,
    struct tegra_gpio_irqsrc *tgi, uint32_t val, uint32_t mask)
{
	uint32_t tmp;
	int bit;

	bit = GPIO_BIT(tgi->irq);
	GPIO_LOCK(sc);
	tmp = bus_read_4(sc->mem_res, reg + GPIO_REGNUM(tgi->irq));
	tmp &= ~(mask << bit);
	tmp |= val << bit;
	bus_write_4(sc->mem_res, reg + GPIO_REGNUM(tgi->irq), tmp);
	GPIO_UNLOCK(sc);
}
Ejemplo n.º 2
0
static inline uint32_t
gpio_read(struct tegra_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin)
{
	int bit;
	uint32_t val;

	bit = GPIO_BIT(pin->gp_pin);
	val = bus_read_4(sc->mem_res, reg + GPIO_REGNUM(pin->gp_pin));
	return (val >> bit) & 1;
}
Ejemplo n.º 3
0
static int
tegra_gpio_intr(void *arg)
{
	u_int irq, i, j, val, basepin;
	struct tegra_gpio_softc *sc;
	struct trapframe *tf;
	struct tegra_gpio_irqsrc *tgi;
	struct tegra_gpio_irq_cookie *cookie;

	cookie = (struct tegra_gpio_irq_cookie *)arg;
	sc = cookie->sc;
	tf = curthread->td_intr_frame;

	for (i = 0; i < GPIO_REGS_IN_BANK; i++) {
		basepin  = cookie->bank_num * GPIO_REGS_IN_BANK *
		    GPIO_PINS_IN_REG + i * GPIO_PINS_IN_REG;

		val = bus_read_4(sc->mem_res, GPIO_INT_STA +
		    GPIO_REGNUM(basepin));
		val &= bus_read_4(sc->mem_res, GPIO_INT_ENB +
		    GPIO_REGNUM(basepin));
		/* Interrupt handling */
		for (j = 0; j < GPIO_PINS_IN_REG; j++) {
			if ((val & (1 << j)) == 0)
				continue;
			irq = basepin + j;
			tgi = &sc->isrcs[irq];
			if (!tegra_gpio_isrc_is_level(tgi))
				tegra_gpio_isrc_eoi(sc, tgi);
			if (intr_isrc_dispatch(&tgi->isrc, tf) != 0) {
				tegra_gpio_isrc_mask(sc, tgi, 0);
				if (tegra_gpio_isrc_is_level(tgi))
					tegra_gpio_isrc_eoi(sc, tgi);
				device_printf(sc->dev,
				    "Stray irq %u disabled\n", irq);
			}

		}
	}

	return (FILTER_HANDLED);
}
Ejemplo n.º 4
0
/* --------------------------------------------------------------------------
 *
 * Interrupts
 *
 */
static inline void
intr_write_masked(struct tegra_gpio_softc *sc, bus_addr_t reg,
    struct tegra_gpio_irqsrc *tgi, uint32_t val)
{
	uint32_t tmp;
	int bit;

	bit = GPIO_BIT(tgi->irq);
	tmp = 0x100 << bit;		/* mask */
	tmp |= (val & 1) << bit;	/* value */
	bus_write_4(sc->mem_res, reg + GPIO_REGNUM(tgi->irq), tmp);
}
Ejemplo n.º 5
0
/* --------------------------------------------------------------------------
 *
 * GPIO
 *
 */
static inline void
gpio_write_masked(struct tegra_gpio_softc *sc, bus_size_t reg,
    struct gpio_pin *pin, uint32_t val)
{
	uint32_t tmp;
	int bit;

	bit = GPIO_BIT(pin->gp_pin);
	tmp = 0x100 << bit;		/* mask */
	tmp |= (val & 1) << bit;	/* value */
	bus_write_4(sc->mem_res, reg + GPIO_REGNUM(pin->gp_pin), tmp);
}
Ejemplo n.º 6
0
static int
tegra_gpio_intr(void *arg)
{
	struct tegra_gpio_softc *sc;
	uint32_t val;
	int i;

	sc = arg;
	for (i = 0; i < NGPIO; i += GPIO_PINS_IN_REG) {
		/* Clear interrupt */
		val = bus_read_4(sc->mem_res, GPIO_INT_STA + GPIO_REGNUM(i));
		val &= bus_read_4(sc->mem_res, GPIO_INT_ENB + GPIO_REGNUM(i));
		bus_write_4(sc->mem_res, GPIO_INT_CLR + GPIO_REGNUM(i), val);
		/* Interrupt handling */
#ifdef not_yet
		for (j = 0; j < GPIO_PINS_IN_REG; j++) {
			if (val & (1 << j))
				handle_irq(i + j);
		}
		*/
#endif
	}
	return (FILTER_HANDLED);
}
Ejemplo n.º 7
0
static int
tegra_gpio_attach(device_t dev)
{
	struct tegra_gpio_softc *sc;
	int i, rid;

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

	/* Allocate bus_space resources. */
	rid = 0;
	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->mem_res == NULL) {
		device_printf(dev, "Cannot allocate memory resources\n");
		tegra_gpio_detach(dev);
		return (ENXIO);
	}

	sc->gpio_npins = NGPIO;
	for (i = 0; i < sc->gpio_npins; i++) {
		sc->gpio_pins[i].gp_pin = i;
		sc->gpio_pins[i].gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
		    GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | 
		    GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING |
		    GPIO_INTR_EDGE_BOTH;
		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, "gpio_%s.%d",
		    tegra_gpio_port_names[ i / GPIO_PINS_IN_REG],
		    i % GPIO_PINS_IN_REG);
		sc->gpio_pins[i].gp_flags =
		    gpio_read(sc, GPIO_OE, &sc->gpio_pins[i]) != 0 ?
		    GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
	}

	/* Init interrupt related registes. */
	for (i = 0; i < sc->gpio_npins; i += GPIO_PINS_IN_REG) {
		bus_write_4(sc->mem_res, GPIO_INT_ENB + GPIO_REGNUM(i), 0);
		bus_write_4(sc->mem_res, GPIO_INT_STA + GPIO_REGNUM(i), 0xFF);
		bus_write_4(sc->mem_res, GPIO_INT_CLR + GPIO_REGNUM(i), 0xFF);
	}

	/* Allocate interrupts. */
	for (i = 0; i < GPIO_NUM_BANKS; i++) {
		sc->irq_cookies[i].sc = sc;
		sc->irq_cookies[i].bank_num = i;
		rid = i;
		sc->irq_res[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ,
		    &rid, RF_ACTIVE);
		if (sc->irq_res[i] == NULL) {
			device_printf(dev, "Cannot allocate IRQ resources\n");
			tegra_gpio_detach(dev);
			return (ENXIO);
		}
		if ((bus_setup_intr(dev, sc->irq_res[i],
		    INTR_TYPE_MISC | INTR_MPSAFE, tegra_gpio_intr, NULL,
		    &sc->irq_cookies[i], &sc->irq_ih[i]))) {
			device_printf(dev,
			    "WARNING: unable to register interrupt handler\n");
			tegra_gpio_detach(dev);
			return (ENXIO);
		}
	}

	if (tegra_gpio_pic_attach(sc) != 0) {
		device_printf(dev, "WARNING: unable to attach PIC\n");
		tegra_gpio_detach(dev);
		return (ENXIO);
	}

	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL) {
		tegra_gpio_detach(dev);
		return (ENXIO);
	}

	return (bus_generic_attach(dev));
}