Exemple #1
0
static int
tegra_gpio_attach(device_t dev)
{
	struct tegra_gpio_softc *sc;
	int i, rid;

	sc = device_get_softc(dev);
	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

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

	rid = 0;
	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(dev, "Cannot allocate IRQ resources\n");
		tegra_gpio_detach(dev);
		return (ENXIO);
	}

	sc->dev = dev;
	sc->gpio_npins = NGPIO;

	if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
	    tegra_gpio_intr, NULL, sc, &sc->gpio_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		tegra_gpio_detach(dev);
		return (ENXIO);
	}

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

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

	return (bus_generic_attach(dev));
}
Exemple #2
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));
}