Example #1
0
static int
lpc_gpio_attach(device_t dev)
{
	struct lpc_gpio_softc *sc = device_get_softc(dev);
	int rid;

	sc->lg_dev = dev;

	rid = 0;
	sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->lg_res) {
		device_printf(dev, "cannot allocate memory window\n");
		return (ENXIO);
	}

	sc->lg_bst = rman_get_bustag(sc->lg_res);
	sc->lg_bsh = rman_get_bushandle(sc->lg_res);

	lpc_gpio_sc = sc;

	sc->lg_busdev = gpiobus_attach_bus(dev);
	if (sc->lg_busdev == NULL) {
		bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
		return (ENXIO);
	}

	return (0);
}
Example #2
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));
}
Example #3
0
static int
aml8726_gpio_attach(device_t dev)
{
	struct aml8726_gpio_softc *sc = device_get_softc(dev);
	phandle_t node;
	pcell_t prop;

	sc->dev = dev;

	node = ofw_bus_get_node(dev);

	if (OF_getencprop(node, "pin-count",
	    &prop, sizeof(prop)) <= 0) {
		device_printf(dev, "missing pin-count attribute in FDT\n");
		return (ENXIO);
	}
	sc->npins = prop;

	if (sc->npins > 32)
		return (ENXIO);

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

	/*
	 * The GPIOAO OUT bits occupy the upper word of the OEN register.
	 */
	if (rman_get_start(sc->res[1]) == rman_get_start(sc->res[0]))
	  if (sc->npins > 16) {
		device_printf(dev,
		    "too many pins for overlapping OEN and OUT\n");
		bus_release_resources(dev, aml8726_gpio_spec, sc->res);
		return (ENXIO);
		}

	AML_GPIO_LOCK_INIT(sc);

	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL) {
		AML_GPIO_LOCK_DESTROY(sc);
		bus_release_resources(dev, aml8726_gpio_spec, sc->res);
		return (ENXIO);
	}

	return (0);
}
Example #4
0
static int
a10_gpio_attach(device_t dev)
{
	int rid;
	phandle_t gpio;
	struct a10_gpio_softc *sc;

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

	mtx_init(&sc->sc_mtx, "a10 gpio", "gpio", MTX_SPIN);

	rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_mem_res) {
		device_printf(dev, "cannot allocate memory window\n");
		goto fail;
	}

	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (!sc->sc_irq_res) {
		device_printf(dev, "cannot allocate interrupt\n");
		goto fail;
	}

	/* Find our node. */
	gpio = ofw_bus_get_node(sc->sc_dev);
	if (!OF_hasprop(gpio, "gpio-controller"))
		/* Node is not a GPIO controller. */
		goto fail;

	/* Use the right pin data for the current SoC */
	switch (allwinner_soc_type()) {
#ifdef SOC_ALLWINNER_A10
	case ALLWINNERSOC_A10:
		sc->padconf = &a10_padconf;
		break;
#endif
#ifdef SOC_ALLWINNER_A20
	case ALLWINNERSOC_A20:
		sc->padconf = &a20_padconf;
		break;
#endif
#ifdef SOC_ALLWINNER_A31
	case ALLWINNERSOC_A31:
		sc->padconf = &a31_padconf;
		break;
#endif
#ifdef SOC_ALLWINNER_A31S
	case ALLWINNERSOC_A31S:
		sc->padconf = &a31s_padconf;
		break;
#endif
	default:
		return (ENOENT);
	}

	sc->sc_busdev = gpiobus_attach_bus(dev);
	if (sc->sc_busdev == NULL)
		goto fail;

	/*
	 * Register as a pinctrl device
	 */
	fdt_pinctrl_register(dev, "allwinner,pins");
	fdt_pinctrl_configure_tree(dev);

	return (0);

fail:
	if (sc->sc_irq_res)
		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
	if (sc->sc_mem_res)
		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
	mtx_destroy(&sc->sc_mtx);

	return (ENXIO);
}
Example #5
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 #6
0
static int
bytgpio_attach(device_t dev)
{
	struct bytgpio_softc	*sc;
	ACPI_STATUS status;
	int uid;
	int pin;
	uint32_t reg, val;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_handle = acpi_get_handle(dev);
	status = acpi_GetInteger(sc->sc_handle, "_UID", &uid);
	if (ACPI_FAILURE(status)) {
		device_printf(dev, "failed to read _UID\n");
		return (ENXIO);
	}

	BYTGPIO_LOCK_INIT(sc);

	switch (uid) {
	case SCORE_UID:
		sc->sc_npins = SCORE_PINS;
		sc->sc_bank_prefix = SCORE_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_score_pins;
		break;
	case NCORE_UID:
		sc->sc_npins = NCORE_PINS;
		sc->sc_bank_prefix = NCORE_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_ncore_pins;
		break;
	case SUS_UID:
		sc->sc_npins = SUS_PINS;
		sc->sc_bank_prefix = SUS_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_sus_pins;
		break;
	default:
		device_printf(dev, "invalid _UID value: %d\n", uid);
		goto error;
	}

	sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF,
	    M_WAITOK | M_ZERO);

	sc->sc_mem_rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
	    SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
	if (sc->sc_mem_res == NULL) {
		device_printf(dev, "can't allocate resource\n");
		goto error;
	}

	for (pin = 0; pin < sc->sc_npins; pin++) {
	    reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0);
	    val = bytgpio_read_4(sc, reg);
	    sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
	}

	sc->sc_busdev = gpiobus_attach_bus(dev);
	if (sc->sc_busdev == NULL) {
		BYTGPIO_LOCK_DESTROY(sc);
		bus_release_resource(dev, SYS_RES_MEMORY,
		    sc->sc_mem_rid, sc->sc_mem_res);
		return (ENXIO);
	}

	return (0);

error:
	BYTGPIO_LOCK_DESTROY(sc);

	return (ENXIO);
}
static int
pad_attach(device_t dev)
{
	struct gpio_bank bank;
	struct pad_softc *sc;
	int pin_shift;
	int reg;
	int i;

	sc = device_get_softc(dev);

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

	sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
	switch (sc->model) {
	case EXYNOS5250:
		sc->pad_spec = pad_spec_5250;
		sc->gpio_map = gpio_map_5250;
		sc->interrupt_table = interrupt_table_5250;
		sc->gpio_npins = 253;
		sc->nports = 4;
		break;
	case EXYNOS5420:
		sc->pad_spec = pad_spec_5420;
		sc->gpio_map = gpio_map_5420;
		sc->interrupt_table = interrupt_table_5420;
		sc->gpio_npins = 232;
		sc->nports = 5;
		break;
	default:
		goto fail;
	};

	if (bus_alloc_resources(dev, sc->pad_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		goto fail;
	}

	/* Memory interface */

	for (i = 0; i < sc->nports; i++) {
		sc->bst[i] = rman_get_bustag(sc->res[i]);
		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
	};

	sc->dev = dev;

	gpio_sc = sc;

	for (i = 0; i < sc->nports; i++) {
		if ((bus_setup_intr(dev, sc->res[sc->nports + i],
			    INTR_TYPE_BIO | INTR_MPSAFE, port_intr,
			    NULL, sc, &sc->gpio_ih[i]))) {
			device_printf(dev,
			    "ERROR: Unable to register interrupt handler\n");
			goto fail;
		}
	}

	for (i = 0; i < sc->gpio_npins; i++) {
		sc->gpio_pins[i].gp_pin = i;
		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;

		if (get_bank(sc, i, &bank, &pin_shift) != 0)
			continue;

		pin_shift *= 4;

		reg = READ4(sc, bank.port, bank.con);
		if (reg & (PIN_OUT << pin_shift))
			sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT;
		else
			sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT;

		/* TODO: add other pin statuses */

		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
		    "pad%d.%d", device_get_unit(dev), i);
	}
	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL)
		goto fail;

	return (0);

fail:
	for (i = 0; i < sc->nports; i++) {
		if (sc->gpio_ih[i])
			bus_teardown_intr(dev, sc->res[sc->nports + i],
			    sc->gpio_ih[i]);
	}
	bus_release_resources(dev, sc->pad_spec, sc->res);
	mtx_destroy(&sc->sc_mtx);

	return (ENXIO);
}
Example #8
0
/**
 *	ti_gpio_attach - attach function for the driver
 *	@dev: gpio device handle
 *
 *	Allocates and sets up the driver context for all GPIO banks.  This function
 *	expects the memory ranges and IRQs to already be allocated to the driver.
 *
 *	LOCKING:
 *	None
 *
 *	RETURNS:
 *	Always returns 0
 */
static int
ti_gpio_attach(device_t dev)
{
	struct ti_gpio_softc *sc;
#ifndef INTRNG
	unsigned int i;
#endif
	int err;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	TI_GPIO_LOCK_INIT(sc);
	ti_gpio_pin_max(dev, &sc->sc_maxpin);
	sc->sc_maxpin++;

	sc->sc_mem_rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->sc_mem_rid, RF_ACTIVE);
	if (!sc->sc_mem_res) {
		device_printf(dev, "Error: could not allocate mem resources\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

	sc->sc_irq_rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &sc->sc_irq_rid, RF_ACTIVE);
	if (!sc->sc_irq_res) {
		device_printf(dev, "Error: could not allocate irq resources\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

	/*
	 * Register our interrupt filter for each of the IRQ resources.
	 */
	if (bus_setup_intr(dev, sc->sc_irq_res,
	    INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc,
	    &sc->sc_irq_hdl) != 0) {
		device_printf(dev,
		    "WARNING: unable to register interrupt filter\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

#ifdef INTRNG
	if (ti_gpio_pic_attach(sc) != 0) {
		device_printf(dev, "WARNING: unable to attach PIC\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}
#else
	/*
	 * Initialize the interrupt settings.  The default is active-low
	 * interrupts.
	 */
	sc->sc_irq_trigger = malloc(
	    sizeof(*sc->sc_irq_trigger) * sc->sc_maxpin,
	    M_DEVBUF, M_WAITOK | M_ZERO);
	sc->sc_irq_polarity = malloc(
	    sizeof(*sc->sc_irq_polarity) * sc->sc_maxpin,
	    M_DEVBUF, M_WAITOK | M_ZERO);
	for (i = 0; i < sc->sc_maxpin; i++) {
		sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL;
		sc->sc_irq_polarity[i] = INTR_POLARITY_LOW;
	}

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

	sc->sc_mask_args = malloc(sizeof(struct ti_gpio_mask_arg) * sc->sc_maxpin,
	    M_DEVBUF, M_WAITOK | M_ZERO);
#endif
	/* We need to go through each block and ensure the clocks are running and
	 * the module is enabled.  It might be better to do this only when the
	 * pins are configured which would result in less power used if the GPIO
	 * pins weren't used ... 
	 */
	if (sc->sc_mem_res != NULL) {
		/* Initialize the GPIO module. */
		err = ti_gpio_bank_init(dev);
		if (err != 0) {
			ti_gpio_detach(dev);
			return (err);
		}
	}

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

	return (0);
}
Example #9
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));
}
Example #10
0
/**
 *	ti_gpio_attach - attach function for the driver
 *	@dev: gpio device handle
 *
 *	Allocates and sets up the driver context for all GPIO banks.  This function
 *	expects the memory ranges and IRQs to already be allocated to the driver.
 *
 *	LOCKING:
 *	None
 *
 *	RETURNS:
 *	Always returns 0
 */
static int
ti_gpio_attach(device_t dev)
{
	struct ti_gpio_softc *sc;
	int err;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	TI_GPIO_LOCK_INIT(sc);
	ti_gpio_pin_max(dev, &sc->sc_maxpin);
	sc->sc_maxpin++;

	sc->sc_mem_rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->sc_mem_rid, RF_ACTIVE);
	if (!sc->sc_mem_res) {
		device_printf(dev, "Error: could not allocate mem resources\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

	sc->sc_irq_rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &sc->sc_irq_rid, RF_ACTIVE);
	if (!sc->sc_irq_res) {
		device_printf(dev, "Error: could not allocate irq resources\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

	/*
	 * Register our interrupt filter for each of the IRQ resources.
	 */
	if (bus_setup_intr(dev, sc->sc_irq_res,
	    INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc,
	    &sc->sc_irq_hdl) != 0) {
		device_printf(dev,
		    "WARNING: unable to register interrupt filter\n");
		ti_gpio_detach(dev);
		return (ENXIO);
	}

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

	/* We need to go through each block and ensure the clocks are running and
	 * the module is enabled.  It might be better to do this only when the
	 * pins are configured which would result in less power used if the GPIO
	 * pins weren't used ... 
	 */
	if (sc->sc_mem_res != NULL) {
		/* Initialize the GPIO module. */
		err = ti_gpio_bank_init(dev);
		if (err != 0) {
			ti_gpio_detach(dev);
			return (err);
		}
	}

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

	return (0);
}
Example #11
0
static int
octeon_gpio_attach(device_t dev)
{
    struct octeon_gpio_softc *sc = device_get_softc(dev);
    struct octeon_gpio_pin *pinp;
    cvmx_gpio_bit_cfgx_t gpio_cfgx;

    int i;

    KASSERT((device_get_unit(dev) == 0),
            ("octeon_gpio: Only one gpio module supported"));

    mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

    for ( i = 0; i < OCTEON_GPIO_IRQS; i++) {
        if ((sc->gpio_irq_res[i] = bus_alloc_resource(dev,
                                   SYS_RES_IRQ, &sc->gpio_irq_rid[i],
                                   OCTEON_IRQ_GPIO0 + i, OCTEON_IRQ_GPIO0 + i, 1,
                                   RF_SHAREABLE | RF_ACTIVE)) == NULL) {
            device_printf(dev, "unable to allocate IRQ resource\n");
            octeon_gpio_detach(dev);
            return (ENXIO);
        }

        sc->gpio_intr_cookies[i] = sc;
        if ((bus_setup_intr(dev, sc->gpio_irq_res[i], INTR_TYPE_MISC,
                            octeon_gpio_filter, octeon_gpio_intr,
                            &(sc->gpio_intr_cookies[i]), &sc->gpio_ih[i]))) {
            device_printf(dev,
                          "WARNING: unable to register interrupt handler\n");
            octeon_gpio_detach(dev);
            return (ENXIO);
        }
    }

    sc->dev = dev;
    /* Configure all pins as input */
    /* disable interrupts for all pins */
    pinp = octeon_gpio_pins;
    i = 0;
    while (pinp->name) {
        strncpy(sc->gpio_pins[i].gp_name, pinp->name, GPIOMAXNAME);
        sc->gpio_pins[i].gp_pin = pinp->pin;
        sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
        sc->gpio_pins[i].gp_flags = 0;
        octeon_gpio_pin_configure(sc, &sc->gpio_pins[i], pinp->flags);
        pinp++;
        i++;
    }

    sc->gpio_npins = i;

#if 0
    /*
     * Sample: how to enable edge-triggered interrupt
     * for GPIO pin
     */
    gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(7));
    gpio_cfgx.s.int_en = 1;
    gpio_cfgx.s.int_type = OCTEON_GPIO_IRQ_EDGE;
    cvmx_write_csr(CVMX_GPIO_BIT_CFGX(7), gpio_cfgx.u64);
#endif

    if (bootverbose) {
        for (i = 0; i < 16; i++) {
            gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(i));
            device_printf(dev, "[pin%d] output=%d, invinput=%d, intr=%d, intr_type=%s\n",
                          i, gpio_cfgx.s.tx_oe, gpio_cfgx.s.rx_xor,
                          gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising edge" : "level");
        }
    }
    sc->busdev = gpiobus_attach_bus(dev);
    if (sc->busdev == NULL) {
        octeon_gpio_detach(dev);
        return (ENXIO);
    }

    return (0);
}
Example #12
0
static int
rk30_gpio_attach(device_t dev)
{
	struct rk30_gpio_softc *sc = device_get_softc(dev);
	int i, rid;
	phandle_t gpio;
	unsigned long start;

	if (rk30_gpio_sc)
		return (ENXIO);
	sc->sc_dev = dev;
	mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);

	rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_mem_res) {
		device_printf(dev, "cannot allocate memory window\n");
		goto fail;
	}
	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
	/* Check the unit we are attaching by our base address. */
	sc->sc_bank = -1;
	start = rman_get_start(sc->sc_mem_res);
	for (i = 0; i < nitems(rk30_gpio_base_addr); i++) {
		if (rk30_gpio_base_addr[i] == start) {
			sc->sc_bank = i;
			break;
		}
	}
	if (sc->sc_bank == -1) {
		device_printf(dev,
		    "unsupported device unit (only GPIO0..3 are supported)\n");
		goto fail;
	}

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (!sc->sc_irq_res) {
		device_printf(dev, "cannot allocate interrupt\n");
		goto fail;
	}

	/* Find our node. */
	gpio = ofw_bus_get_node(sc->sc_dev);

	if (!OF_hasprop(gpio, "gpio-controller"))
		/* Node is not a GPIO controller. */
		goto fail;

	/* Initialize the software controlled pins. */
	for (i = 0; i < RK30_GPIO_PINS; i++) {
		snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
		    "pin %d", i);
		sc->sc_gpio_pins[i].gp_pin = i;
		sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS;
		sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i);
	}
	sc->sc_gpio_npins = i;
	rk30_gpio_sc = sc;
	rk30_gpio_init();
	sc->sc_busdev = gpiobus_attach_bus(dev);
	if (sc->sc_busdev == NULL)
		goto fail;

	return (0);

fail:
	if (sc->sc_irq_res)
		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
	if (sc->sc_mem_res)
		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
	mtx_destroy(&sc->sc_mtx);

	return (ENXIO);
}
Example #13
0
static int
mv_gpio_attach(device_t dev)
{
	int i, rv;
	struct mv_gpio_softc *sc;
	phandle_t node;
	pcell_t pincnt = 0;

	sc = (struct mv_gpio_softc *)device_get_softc(dev);
	if (sc == NULL)
		return (ENXIO);

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

	if (OF_getencprop(node, "pin-count", &pincnt, sizeof(pcell_t)) >= 0 ||
	    OF_getencprop(node, "ngpios", &pincnt, sizeof(pcell_t)) >= 0) {
		sc->pin_num = MIN(pincnt, MV_GPIO_MAX_NPINS);
		if (bootverbose)
			device_printf(dev, "%d pins available\n", sc->pin_num);
	} else {
		device_printf(dev, "ERROR: no pin-count or ngpios entry found!\n");
		return (ENXIO);
	}

	if (OF_getencprop(node, "offset", &sc->offset, sizeof(sc->offset)) == -1)
		sc->offset = 0;

	/* Assign generic capabilities to every gpio pin */
	for(i = 0; i < sc->pin_num; i++)
		sc->gpio_setup[i].gp_caps = GPIO_GENERIC_CAP;

	mtx_init(&sc->mutex, device_get_nameunit(dev), NULL, MTX_SPIN);

	sc->mem_rid = 0;
	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
		 RF_ACTIVE | RF_SHAREABLE );

	if (!sc->mem_res) {
		mtx_destroy(&sc->mutex);
		device_printf(dev, "could not allocate memory window\n");
		return (ENXIO);
	}

	sc->bst = rman_get_bustag(sc->mem_res);
	sc->bsh = rman_get_bushandle(sc->mem_res);

	rv = mv_gpio_setup_interrupts(sc, node);
	if (rv != 0)
		return (rv);

	sc->sc_busdev = gpiobus_attach_bus(dev);
	if (sc->sc_busdev == NULL) {
		mtx_destroy(&sc->mutex);
		bus_release_resource(dev, SYS_RES_IRQ,
			sc->irq_rid[i], sc->irq_res[i]);
		return (ENXIO);
	}

	return (0);
}