diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-03-30 19:38:01 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-03-30 19:38:01 +0000 |
commit | 955d3523b749aac368c3f7a58c33e08a1e42e951 (patch) | |
tree | 73ca9edddd90338ffcfdce2fca140bf7500eb3c6 /sys/arch | |
parent | 91609c278705d1ef7720a043e367b61c94cdb638 (diff) |
Move imxgpio(4) to sys/dev/fdt so it can be shared between arm64 and armv7.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/armv7/imx/files.imx | 6 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxgpio.c | 374 |
2 files changed, 1 insertions, 379 deletions
diff --git a/sys/arch/armv7/imx/files.imx b/sys/arch/armv7/imx/files.imx index 1b9c8d5ad6a..bc56cbb8f25 100644 --- a/sys/arch/armv7/imx/files.imx +++ b/sys/arch/armv7/imx/files.imx @@ -1,4 +1,4 @@ -# $OpenBSD: files.imx,v 1.23 2018/03/30 09:26:14 patrick Exp $ +# $OpenBSD: files.imx,v 1.24 2018/03/30 19:38:00 patrick Exp $ device imxccm attach imxccm at fdt @@ -16,10 +16,6 @@ device imxanatop attach imxanatop at fdt file arch/armv7/imx/imxanatop.c imxanatop -device imxgpio -attach imxgpio at fdt -file arch/armv7/imx/imxgpio.c imxgpio - device imxiic: i2cbus attach imxiic at fdt file arch/armv7/imx/imxiic.c imxiic diff --git a/sys/arch/armv7/imx/imxgpio.c b/sys/arch/armv7/imx/imxgpio.c deleted file mode 100644 index c81667ba3b0..00000000000 --- a/sys/arch/armv7/imx/imxgpio.c +++ /dev/null @@ -1,374 +0,0 @@ -/* $OpenBSD: imxgpio.c,v 1.14 2018/03/30 19:30:57 patrick Exp $ */ -/* - * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> - * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/device.h> -#include <sys/malloc.h> -#include <sys/evcount.h> - -#include <machine/bus.h> -#include <machine/fdt.h> -#include <machine/intr.h> - -#include <dev/ofw/openfirm.h> -#include <dev/ofw/ofw_gpio.h> -#include <dev/ofw/fdt.h> - -/* iMX6 registers */ -#define GPIO_DR 0x00 -#define GPIO_GDIR 0x04 -#define GPIO_PSR 0x08 -#define GPIO_ICR1 0x0C -#define GPIO_ICR2 0x10 -#define GPIO_IMR 0x14 -#define GPIO_ISR 0x18 -#define GPIO_EDGE_SEL 0x1C - -#define GPIO_NUM_PINS 32 - -struct intrhand { - int (*ih_func)(void *); /* handler */ - void *ih_arg; /* arg for handler */ - int ih_ipl; /* IPL_* */ - int ih_irq; /* IRQ number */ - int ih_level; /* GPIO level */ - struct evcount ih_count; - char *ih_name; - void *ih_sc; -}; - -struct imxgpio_softc { - struct device sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - int sc_node; - - void *sc_ih_h; - void *sc_ih_l; - int sc_ipl; - int sc_irq; - struct intrhand *sc_handlers[GPIO_NUM_PINS]; - struct interrupt_controller sc_ic; - - struct gpio_controller sc_gc; -}; - -int imxgpio_match(struct device *, void *, void *); -void imxgpio_attach(struct device *, struct device *, void *); - -void imxgpio_config_pin(void *, uint32_t *, int); -int imxgpio_get_pin(void *, uint32_t *); -void imxgpio_set_pin(void *, uint32_t *, int); - -int imxgpio_intr(void *); -void *imxgpio_intr_establish(void *, int *, int, int (*)(void *), - void *, char *); -void imxgpio_intr_disestablish(void *); -void imxgpio_recalc_ipl(struct imxgpio_softc *); - - -struct cfattach imxgpio_ca = { - sizeof (struct imxgpio_softc), imxgpio_match, imxgpio_attach -}; - -struct cfdriver imxgpio_cd = { - NULL, "imxgpio", DV_DULL -}; - -int -imxgpio_match(struct device *parent, void *match, void *aux) -{ - struct fdt_attach_args *faa = aux; - - return OF_is_compatible(faa->fa_node, "fsl,imx35-gpio"); -} - -void -imxgpio_attach(struct device *parent, struct device *self, void *aux) -{ - struct imxgpio_softc *sc = (struct imxgpio_softc *)self; - struct fdt_attach_args *faa = aux; - - if (faa->fa_nreg < 1) - return; - - sc->sc_node = faa->fa_node; - sc->sc_iot = faa->fa_iot; - if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, - faa->fa_reg[0].size, 0, &sc->sc_ioh)) - panic("imxgpio_attach: bus_space_map failed!"); - - sc->sc_gc.gc_node = faa->fa_node; - sc->sc_gc.gc_cookie = sc; - sc->sc_gc.gc_config_pin = imxgpio_config_pin; - sc->sc_gc.gc_get_pin = imxgpio_get_pin; - sc->sc_gc.gc_set_pin = imxgpio_set_pin; - gpio_controller_register(&sc->sc_gc); - - sc->sc_ipl = IPL_NONE; - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR, 0); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_ISR, ~0); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_EDGE_SEL, 0); - - sc->sc_ic.ic_node = faa->fa_node; - sc->sc_ic.ic_cookie = sc; - sc->sc_ic.ic_establish = imxgpio_intr_establish; - sc->sc_ic.ic_disestablish = imxgpio_intr_disestablish; - arm_intr_register_fdt(&sc->sc_ic); - - printf("\n"); - - /* XXX - SYSCONFIG */ - /* XXX - CTRL */ - /* XXX - DEBOUNCE */ -} - -void -imxgpio_config_pin(void *cookie, uint32_t *cells, int config) -{ - struct imxgpio_softc *sc = cookie; - uint32_t pin = cells[0]; - uint32_t val; - - if (pin >= GPIO_NUM_PINS) - return; - - val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_GDIR); - if (config & GPIO_CONFIG_OUTPUT) - val |= 1 << pin; - else - val &= ~(1 << pin); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_GDIR, val); -} - -int -imxgpio_get_pin(void *cookie, uint32_t *cells) -{ - struct imxgpio_softc *sc = cookie; - uint32_t pin = cells[0]; - uint32_t flags = cells[1]; - uint32_t reg; - int val; - - reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_DR); - reg &= (1 << pin); - val = (reg >> pin) & 1; - if (flags & GPIO_ACTIVE_LOW) - val = !val; - return val; -} - -void -imxgpio_set_pin(void *cookie, uint32_t *cells, int val) -{ - struct imxgpio_softc *sc = cookie; - uint32_t pin = cells[0]; - uint32_t flags = cells[1]; - uint32_t reg; - - reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_DR); - if (flags & GPIO_ACTIVE_LOW) - val = !val; - if (val) - reg |= (1 << pin); - else - reg &= ~(1 << pin); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_DR, reg); -} - -int -imxgpio_intr(void *cookie) -{ - struct imxgpio_softc *sc = (struct imxgpio_softc *)cookie; - struct intrhand *ih; - uint32_t status, pending, mask; - int pin, s; - - status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_ISR); - mask = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR); - - status &= mask; - pending = status; - - while (pending) { - pin = ffs(pending) - 1; - - if ((ih = sc->sc_handlers[pin]) != NULL) { - s = splraise(ih->ih_ipl); - if (ih->ih_func(ih->ih_arg)) - ih->ih_count.ec_count++; - splx(s); - } - - pending &= ~(1 << pin); - } - - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_ISR, status); - - return 1; -} - -void * -imxgpio_intr_establish(void *cookie, int *cells, int ipl, - int (*func)(void *), void *arg, char *name) -{ - struct imxgpio_softc *sc = (struct imxgpio_softc *)cookie; - struct intrhand *ih; - int s, val, reg, shift; - int irqno = cells[0]; - int level = cells[1]; - - if (irqno < 0 || irqno >= GPIO_NUM_PINS) - panic("%s: bogus irqnumber %d: %s", __func__, - irqno, name); - - if (sc->sc_handlers[irqno] != NULL) - panic("%s: irqnumber %d reused: %s", __func__, - irqno, name); - - ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK); - ih->ih_func = func; - ih->ih_arg = arg; - ih->ih_ipl = ipl; - ih->ih_irq = irqno; - ih->ih_name = name; - ih->ih_level = level; - ih->ih_sc = sc; - - s = splhigh(); - - sc->sc_handlers[irqno] = ih; - - if (name != NULL) - evcount_attach(&ih->ih_count, name, &ih->ih_irq); - -#ifdef DEBUG_INTC - printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl, - ih->ih_name); -#endif - - imxgpio_recalc_ipl(sc); - - switch (level) { - case 1: /* rising */ - val = 2; - break; - case 2: /* falling */ - val = 3; - break; - case 4: /* high */ - val = 1; - break; - case 8: /* low */ - val = 0; - break; - default: - panic("%s: unsupported trigger type", __func__); - } - - if (irqno < 16) { - reg = GPIO_ICR1; - shift = irqno << 1; - } else { - reg = GPIO_ICR2; - shift = (irqno - 16) << 1; - } - - bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, - bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg) & ~(0x3 << shift)); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, - bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg) | val << shift); - - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR, - bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR) | 1 << irqno); - - splx(s); - return (ih); -} - -void -imxgpio_intr_disestablish(void *cookie) -{ - struct intrhand *ih = cookie; - struct imxgpio_softc *sc = ih->ih_sc; - uint32_t mask; - int s; - - s = splhigh(); - -#ifdef DEBUG_INTC - printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl, - ih->ih_name); -#endif - - mask = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR); - mask &= ~(1 << ih->ih_irq); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_IMR, mask); - - sc->sc_handlers[ih->ih_irq] = NULL; - if (ih->ih_name != NULL) - evcount_detach(&ih->ih_count); - free(ih, M_DEVBUF, sizeof(*ih)); - - imxgpio_recalc_ipl(sc); - - splx(s); -} - -void -imxgpio_recalc_ipl(struct imxgpio_softc *sc) -{ - struct intrhand *ih; - int pin; - int max = IPL_NONE; - int min = IPL_HIGH; - - for (pin = 0; pin < GPIO_NUM_PINS; pin++) { - ih = sc->sc_handlers[pin]; - if (ih == NULL) - continue; - - if (ih->ih_ipl > max) - max = ih->ih_ipl; - - if (ih->ih_ipl < min) - min = ih->ih_ipl; - } - - if (max == IPL_NONE) - min = IPL_NONE; - - if (sc->sc_ipl != max) { - sc->sc_ipl = max; - - if (sc->sc_ih_l != NULL) - arm_intr_disestablish_fdt(sc->sc_ih_l); - - if (sc->sc_ih_h != NULL) - arm_intr_disestablish_fdt(sc->sc_ih_h); - - if (sc->sc_ipl != IPL_NONE) { - sc->sc_ih_l = arm_intr_establish_fdt_idx(sc->sc_node, 0, - sc->sc_ipl, imxgpio_intr, sc, sc->sc_dev.dv_xname); - sc->sc_ih_h = arm_intr_establish_fdt_idx(sc->sc_node, 1, - sc->sc_ipl, imxgpio_intr, sc, sc->sc_dev.dv_xname); - } - } -} |