summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2018-03-30 19:38:01 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2018-03-30 19:38:01 +0000
commit955d3523b749aac368c3f7a58c33e08a1e42e951 (patch)
tree73ca9edddd90338ffcfdce2fca140bf7500eb3c6 /sys/arch
parent91609c278705d1ef7720a043e367b61c94cdb638 (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.imx6
-rw-r--r--sys/arch/armv7/imx/imxgpio.c374
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);
- }
- }
-}