Module Name: src
Committed By: marty
Date: Sat Dec 19 21:42:31 UTC 2015
Modified Files:
src/sys/arch/arm/samsung: exynos_gpio.c exynos_var.h files.exynos
src/sys/arch/evbarm/conf: EXYNOS
Added Files:
src/sys/arch/arm/samsung: exynos_pinctrl.c
Log Message:
XU4 GPIO FDT broken snapshot
This is broken. exynos_gpio_bank_config and the call to it are wrong, and
the acquire function doesn't work.
But I'm in over my head and I need to discuss this:
There is a problem with the dtd: it doesn't have addresses for the individual
gpios. Do I add the addresses to it, or go back to the old version where I
have them hard coded in the driver.
There is a problem with creating the gpio device entries: I suspect I really
need to treat the pinctrl devices as busses and create the gpios as attached
to those busses, but I'm not familiar with how to do that in NetBSD. At the
minimum, a pointer to a similar situation would give me code to follow.
This is different than the usual bus attachment in that the gpios aren't
devices in the dtd (they don't have "compatible" properties) so they don't
get an attach routine called. An alternative to generating the bus
attachments might be to add "compatible" properties to the GPIO entries
in the dtd. so that they do get attached in the normal way.
If I'm going to modify the DTD, then it should be checked in, so a decision
on where to check them in would be nice, even if it does mean spreading them
all over because of license issues. (This DTD is GPL v2)
To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/samsung/exynos_gpio.c \
src/sys/arch/arm/samsung/files.exynos
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/samsung/exynos_pinctrl.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/samsung/exynos_var.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/conf/EXYNOS
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/samsung/exynos_gpio.c
diff -u src/sys/arch/arm/samsung/exynos_gpio.c:1.13 src/sys/arch/arm/samsung/exynos_gpio.c:1.14
--- src/sys/arch/arm/samsung/exynos_gpio.c:1.13 Fri Dec 11 04:03:44 2015
+++ src/sys/arch/arm/samsung/exynos_gpio.c Sat Dec 19 21:42:31 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_gpio.c,v 1.13 2015/12/11 04:03:44 marty Exp $ */
+/* $NetBSD: exynos_gpio.c,v 1.14 2015/12/19 21:42:31 marty Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.13 2015/12/11 04:03:44 marty Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.14 2015/12/19 21:42:31 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -49,6 +49,9 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.
#include <arm/samsung/exynos_reg.h>
#include <arm/samsung/exynos_io.h>
#include <arm/samsung/exynos_intr.h>
+#include <arm/samsung/exynos_pinctrl.h>
+
+#include <dev/fdt/fdtvar.h>
struct exynos_gpio_pin_cfg {
uint32_t cfg;
@@ -62,9 +65,9 @@ struct exynos_gpio_softc;
struct exynos_gpio_bank {
const char bank_name[6];
- struct exynos_gpio_softc *bank_sc;
device_t bank_dev;
struct gpio_chipset_tag bank_gc;
+ struct exynos_gpio_softc *bank_softc;
gpio_pin_t bank_pins[8];
const bus_addr_t bank_core_offset;
@@ -74,172 +77,42 @@ struct exynos_gpio_bank {
uint8_t bank_pin_inuse_mask;
bus_space_handle_t bank_bsh;
struct exynos_gpio_pin_cfg bank_cfg;
+ struct exynos_gpio_bank * bank_next;
};
struct exynos_gpio_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
-
- struct exynos_gpio_bank *sc_banks;
};
struct exynos_gpio_pin {
struct exynos_gpio_softc *pin_sc;
- const struct exynos_gpio_bank *pin_bank;
int pin_no;
u_int pin_flags;
+ int pin_actlo;
+ const struct exynos_gpio_bank *pin_bank;
};
-#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o))
-#define GPIO_GRP(v, s, o, n, b) \
- { \
- .bank_name = #n, \
- .bank_core_offset = GPIO_REG(v,s,o), \
- .bank_bits = b, \
- }
-
-static struct exynos_gpio_bank exynos5_banks[] = {
- GPIO_GRP(5, MUXA, 0x0000, gpy7, 8),
- GPIO_GRP(5, MUXA, 0x0C00, gpx0, 8),
- GPIO_GRP(5, MUXA, 0x0C20, gpx1, 8),
- GPIO_GRP(5, MUXA, 0x0C40, gpx2, 8),
- GPIO_GRP(5, MUXA, 0x0C60, gpx3, 8),
-
- GPIO_GRP(5, MUXB, 0x0000, gpc0, 8),
- GPIO_GRP(5, MUXB, 0x0020, gpc1, 8),
- GPIO_GRP(5, MUXB, 0x0040, gpc2, 7),
- GPIO_GRP(5, MUXB, 0x0060, gpc3, 4),
- GPIO_GRP(5, MUXB, 0x0080, gpc4, 2),
- GPIO_GRP(5, MUXB, 0x00A0, gpd1, 8),
- GPIO_GRP(5, MUXB, 0x00C0, gpy0, 6),
- GPIO_GRP(5, MUXB, 0x00E0, gpy1, 4),
- GPIO_GRP(5, MUXB, 0x0100, gpy2, 6),
- GPIO_GRP(5, MUXB, 0x0120, gpy3, 8),
- GPIO_GRP(5, MUXB, 0x0140, gpy4, 8),
- GPIO_GRP(5, MUXB, 0x0160, gpy5, 8),
- GPIO_GRP(5, MUXB, 0x0180, gpy6, 8),
-
- GPIO_GRP(5, MUXC, 0x0000, gpe0, 8),
- GPIO_GRP(5, MUXC, 0x0020, gpe1, 2),
- GPIO_GRP(5, MUXC, 0x0040, gpf0, 6),
- GPIO_GRP(5, MUXC, 0x0060, gpf1, 8),
- GPIO_GRP(5, MUXC, 0x0080, gpg0, 8),
- GPIO_GRP(5, MUXC, 0x00A0, gpg1, 8),
- GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2),
- GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4),
-
- GPIO_GRP(5, MUXD, 0x0000, gpa0, 8),
- GPIO_GRP(5, MUXD, 0x0020, gpa1, 6),
- GPIO_GRP(5, MUXD, 0x0040, gpa2, 8),
- GPIO_GRP(5, MUXD, 0x0060, gpb0, 5),
- GPIO_GRP(5, MUXD, 0x0080, gpb1, 5),
- GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4),
- GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8),
- GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2),
- GPIO_GRP(5, MUXD, 0x0100, gph0, 4),
+struct exynos_gpio_bank *exynos_gpio_banks;
-// GPIO_GRP(5, MUXE, 0x0000, gpz0, 7),
+static void exynos_gpio_pin_ctl(void *cookie, int pin, int flags);
+static void *exynos_gpio_fdt_acquire(device_t, const void *,
+ size_t, int);
+static void exynos_gpio_fdt_release(device_t, void *);
+
+static int exynos_gpio_fdt_read(device_t, void *);
+static void exynos_gpio_fdt_write(device_t, void *, int);
+//static int exynos_gpio_cfprint(void *, const char *);
+
+struct fdtbus_gpio_controller_func exynos_gpio_funcs = {
+ .acquire = exynos_gpio_fdt_acquire,
+ .release = exynos_gpio_fdt_release,
+ .read = exynos_gpio_fdt_read,
+ .write = exynos_gpio_fdt_write
};
-static int exynos_gpio_match(device_t, cfdata_t, void *);
-static void exynos_gpio_attach(device_t, device_t, void *);
-
-static int exynos_gpio_pin_read(void *, int);
-static void exynos_gpio_pin_write(void *, int, int);
-static void exynos_gpio_pin_ctl(void *, int, int);
-static int exynos_gpio_cfprint(void *, const char *);
-struct exynos_gpio_pin *exynos_gpio_acquire(const char *pinname, u_int flags);
-
-/* force these structures in DATA segment */
-static struct exynos_gpio_bank *exynos_gpio_banks = NULL;
-static int exynos_n_gpio_banks = 0;
-
-static struct exynos_gpio_softc exynos_gpio_sc = {};
-
-CFATTACH_DECL_NEW(exynos_gpio, sizeof(struct exynos_gpio_softc),
- exynos_gpio_match, exynos_gpio_attach, NULL, NULL);
-
-static int
-exynos_gpio_match(device_t parent, cfdata_t cf, void *aux)
-{
-#ifdef DIAGNOSTIC
- struct exyo_attach_args * const exyoaa = aux;
- struct exyo_locators *loc = &exyoaa->exyo_loc;
-#endif
-
- /* no locators expected */
- KASSERT(loc->loc_offset == 0);
- KASSERT(loc->loc_size == 0);
- KASSERT(loc->loc_port == EXYOCF_PORT_DEFAULT);
-
- /* there can only be one */
- if (exynos_gpio_sc.sc_dev != NULL)
- return 0;
- return 1;
-}
-
-
-#if NGPIO > 0
-static void
-exynos_gpio_attach_banks(device_t self)
-{
- struct exynos_gpio_softc * const sc = &exynos_gpio_sc;
- struct exynos_gpio_bank *bank;
- struct gpiobus_attach_args gba;
- size_t pin_count = 0;
- int i, bit, mask, pincaps, data;
-
- if (exynos_n_gpio_banks == 0)
- return;
-
- /* find out how many pins we can offer */
- pin_count = 0;
- for (i = 0; i < exynos_n_gpio_banks; i++) {
- pin_count += exynos_gpio_banks[i].bank_bits;
- }
-
- /* if no pins available, don't proceed */
- if (pin_count == 0)
- return;
-
- /* allocate pin data */
- sc->sc_banks = exynos_gpio_banks;
- KASSERT(sc->sc_banks);
-
- pincaps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
- GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
-
- for (i = 0; i < exynos_n_gpio_banks; i++) {
- bank = &sc->sc_banks[i];
- bank->bank_sc = sc;
- bank->bank_gc.gp_cookie = bank;
- bank->bank_gc.gp_pin_read = exynos_gpio_pin_read;
- bank->bank_gc.gp_pin_write = exynos_gpio_pin_write;
- bank->bank_gc.gp_pin_ctl = exynos_gpio_pin_ctl;
- mask = bank->bank_pin_mask & ~bank->bank_pin_inuse_mask;
- if (mask == 0)
- continue;
- data = bus_space_read_1(sc->sc_bst, bank->bank_bsh,
- EXYNOS_GPIO_DAT);
- for (bit = 0; mask != 0; mask >>= 1, data >>= 1, bit++) {
- if (mask & 1) {
- bank->bank_pins[bit].pin_num = bit + (i << 3);
- bank->bank_pins[bit].pin_caps = pincaps;
- bank->bank_pins[bit].pin_flags = pincaps;
- bank->bank_pins[bit].pin_state = (data & 1) != 0;
- }
- }
- memset(&gba, 0, sizeof(gba));
- gba.gba_gc = &bank->bank_gc;
- gba.gba_pins = bank->bank_pins;
- gba.gba_npins = bit; /* MJF? */
- bank->bank_dev = config_found_ia(self, "gpiobus", &gba,
- exynos_gpio_cfprint);
- }
-}
-#endif
-
+#if 0
static int
exynos_gpio_cfprint(void *priv, const char *pnp)
{
@@ -254,79 +127,7 @@ exynos_gpio_cfprint(void *priv, const ch
return UNCONF;
}
-
-static void
-exynos_gpio_attach(device_t parent, device_t self, void *aux)
-{
- struct exynos_gpio_softc * const sc = &exynos_gpio_sc;
- struct exyo_attach_args * const exyoaa = aux;
-
- sc->sc_dev = self;
- sc->sc_bst = exyoaa->exyo_core_bst;
- sc->sc_bsh = exyoaa->exyo_core_bsh;
-
- exynos_gpio_bootstrap();
- if (exynos_n_gpio_banks == 0) {
- printf(": disabled, no pins defined\n");
- return;
- }
-
- KASSERT(exynos_gpio_banks);
- KASSERT(exynos_n_gpio_banks);
-
- aprint_naive("\n");
- aprint_normal("\n");
-
-#if NGPIO > 0
- exynos_gpio_attach_banks(self);
#endif
-}
-
-static void
-exynos_gpio_set_pin_func(struct exynos_gpio_pin_cfg *cfg,
- int pin, int func)
-{
- const u_int shift = (pin & 7) << 2;
-
- cfg->cfg &= ~(0x0f << shift);
- cfg->cfg |= func << shift;
-}
-
-
-static void
-exynos_gpio_set_pin_pull(struct exynos_gpio_pin_cfg *cfg, int pin, int pull)
-{
- const u_int shift = (pin & 7) << 1;
-
- cfg->pud &= ~(0x3 << shift);
- cfg->pud |= pull << shift;
-}
-
-static int
-exynos_gpio_pin_read(void *cookie, int pin)
-{
- struct exynos_gpio_bank * const bank = cookie;
-
- KASSERT(pin < bank->bank_bits);
- return (bus_space_read_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
- EXYNOS_GPIO_DAT) >> pin) & 1;
-}
-
-static void
-exynos_gpio_pin_write(void *cookie, int pin, int value)
-{
- struct exynos_gpio_bank * const bank = cookie;
- int val;
-
- KASSERT(pin < bank->bank_bits);
- val = bus_space_read_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
- EXYNOS_GPIO_DAT);
- val &= ~__BIT(pin);
- if (value)
- val |= __BIT(pin);
- bus_space_write_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
- EXYNOS_GPIO_DAT, val);
-}
static void
exynos_gpio_update_cfg_regs(struct exynos_gpio_bank *bank,
@@ -371,6 +172,7 @@ exynos_gpio_pin_ctl(void *cookie, int pi
{
struct exynos_gpio_bank * const bank = cookie;
struct exynos_gpio_pin_cfg ncfg = bank->bank_cfg;
+ u_int shift;
int pull;
/* honour pullup requests */
@@ -379,67 +181,74 @@ exynos_gpio_pin_ctl(void *cookie, int pi
pull = EXYNOS_GPIO_PIN_PULL_UP;
if (flags & GPIO_PIN_PULLDOWN)
pull = EXYNOS_GPIO_PIN_PULL_DOWN;
- exynos_gpio_set_pin_pull(&ncfg, pin, pull);
+ shift = (pin & 7) << 1;
+ ncfg.pud &= ~(0x3 << shift);
+ ncfg.pud |= pull << shift;
/* honour i/o */
- if (flags & GPIO_PIN_INPUT)
- exynos_gpio_set_pin_func(&ncfg, pin, EXYNOS_GPIO_FUNC_INPUT);
- if (flags & GPIO_PIN_OUTPUT)
- exynos_gpio_set_pin_func(&ncfg, pin, EXYNOS_GPIO_FUNC_OUTPUT);
+ if (flags & GPIO_PIN_INPUT) {
+ ncfg.cfg &= ~(0x0f << shift);
+ ncfg.cfg |= EXYNOS_GPIO_FUNC_INPUT << shift;
+ } else if (flags & GPIO_PIN_OUTPUT) {
+ ncfg.cfg &= ~(0x0f << shift);
+ ncfg.cfg |= EXYNOS_GPIO_FUNC_OUTPUT << shift;
+ }
/* update any config registers that changed */
exynos_gpio_update_cfg_regs(bank, &ncfg);
}
-/* bootstrapping */
void
-exynos_gpio_bootstrap(void)
+exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent, int node)
{
- bus_space_tag_t bst = &exynos_bs_tag;
- struct exynos_gpio_bank *bank;
- struct gpio_chipset_tag *gc_tag;
- int i;
-
- /* determine what we're running on */
- if (IS_EXYNOS5_P()) {
- exynos_gpio_banks = exynos5_banks;
- exynos_n_gpio_banks = __arraycount(exynos5_banks);
- }
+// bus_space_tag_t bst = &exynos_bs_tag; /* MJF: This is wrong */
+ struct exynos_gpio_bank *bank = kmem_zalloc(sizeof(*bank), KM_SLEEP);
+// struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+// struct gpiobus_attach_args gba;
+ char result[64];
+// int data;
+// int error;
+
+ /*error =*/ OF_getprop(node, "name", result, sizeof(result));
+ printf(" GPIO %s\n", result);
+ if (exynos_gpio_banks)
+ bank->bank_next = exynos_gpio_banks;
+ exynos_gpio_banks = bank;
+ /* MJF: TODO: process all of the node properties */
+#if 0
+// pincaps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
+// GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
- if (exynos_n_gpio_banks == 0)
- return;
-
- /* init banks */
- for (i = 0; i < exynos_n_gpio_banks; i++) {
- bank = &exynos_gpio_banks[i];
- gc_tag = &bank->bank_gc;
-
- bus_space_subregion(&exynos_bs_tag, exynos_core_bsh,
- bank->bank_core_offset, EXYNOS_GPIO_GRP_SIZE,
- &bank->bank_bsh);
- KASSERT(&bank->bank_bsh);
-
- bank->bank_pin_mask = __BIT(bank->bank_bits) - 1;
- bank->bank_pin_inuse_mask = 0;
-
- gc_tag->gp_cookie = bank;
- gc_tag->gp_pin_read = exynos_gpio_pin_read;
- gc_tag->gp_pin_write = exynos_gpio_pin_write;
- gc_tag->gp_pin_ctl = exynos_gpio_pin_ctl;
-
- /* read in our initial settings */
- bank->bank_cfg.cfg = bus_space_read_4(bst, bank->bank_bsh,
- EXYNOS_GPIO_CON);
- bank->bank_cfg.pud = bus_space_read_4(bst, bank->bank_bsh,
- EXYNOS_GPIO_PUD);
- bank->bank_cfg.drv = bus_space_read_4(bst, bank->bank_bsh,
- EXYNOS_GPIO_DRV);
- bank->bank_cfg.conpwd = bus_space_read_4(bst, bank->bank_bsh,
- EXYNOS_GPIO_CONPWD);
- bank->bank_cfg.pudpwd = bus_space_read_4(bst, bank->bank_bsh,
- EXYNOS_GPIO_PUDPWD);
- }
+// data = bus_space_read_1(sc->sc_bst, bank->bank_bsh,
+// EXYNOS_GPIO_DAT);
+ sc->sc_dev = parent->sc_dev;
+ sc->sc_bst = parent->sc_bst;
+
+ memset(&gba, 0, sizeof(gba));
+ gba.gba_gc = &bank->bank_gc;
+ gba.gba_pins = bank->bank_pins;
+// gba.gba_npins = bit; /* MJF? */
+ bank->bank_dev = config_found_ia(parent->sc_dev, "gpiobus", &gba,
+ exynos_gpio_cfprint);
+
+ bank->bank_pin_mask = __BIT(bank->bank_bits) - 1;
+ bank->bank_pin_inuse_mask = 0;
+
+
+ /* read in our initial settings */
+ bank->bank_cfg.cfg = bus_space_read_4(bst, bank->bank_bsh,
+ EXYNOS_GPIO_CON);
+ bank->bank_cfg.pud = bus_space_read_4(bst, bank->bank_bsh,
+ EXYNOS_GPIO_PUD);
+ bank->bank_cfg.drv = bus_space_read_4(bst, bank->bank_bsh,
+ EXYNOS_GPIO_DRV);
+ bank->bank_cfg.conpwd = bus_space_read_4(bst, bank->bank_bsh,
+ EXYNOS_GPIO_CONPWD);
+ bank->bank_cfg.pudpwd = bus_space_read_4(bst, bank->bank_bsh,
+ EXYNOS_GPIO_PUDPWD);
+ /* MJF: TODO: Configure from the node data, if present */
+#endif
}
/*
@@ -453,8 +262,8 @@ static const struct exynos_gpio_bank *
exynos_gpio_pin_lookup(const char *pinname, int *ppin)
{
char bankname[5];
- u_int n;
int pin;
+ struct exynos_gpio_bank *bank;
KASSERT(strlen(pinname) == 2 || strlen(pinname) == 3);
@@ -465,21 +274,21 @@ exynos_gpio_pin_lookup(const char *pinna
bankname[3] = pinname[3]; /* D */
pin = pinname[5] - '0'; /* skip the '-' */
- for (n = 0; n < __arraycount(exynos_gpio_banks); n++) {
- const struct exynos_gpio_bank *pb =
- &exynos_gpio_banks[n];
- if (strcmp(pb->bank_name, bankname) == 0) {
+ for (bank = exynos_gpio_banks; bank; bank = bank->bank_next)
+ if (strcmp(bank->bank_name, bankname) == 0) {
*ppin = pin;
- return pb;
+ return bank;
}
- }
return NULL;
}
-struct exynos_gpio_pin *
-exynos_gpio_acquire(const char *pinname, u_int flags)
+static void *
+exynos_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags)
{
+ /* MJF: This is wrong. data is a u_int but I need a name */
+// const u_int *gpio = data;
+ const char *pinname = data;
const struct exynos_gpio_bank *bank;
struct exynos_gpio_pin *gpin;
int pin;
@@ -489,12 +298,57 @@ exynos_gpio_acquire(const char *pinname,
return NULL;
gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP);
- gpin->pin_sc = bank->bank_sc;
+ gpin->pin_sc = bank->bank_softc;
gpin->pin_bank = bank;
gpin->pin_no = pin;
gpin->pin_flags = flags;
+ gpin->pin_actlo = 0;
exynos_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, gpin->pin_flags);
return gpin;
}
+
+static void
+exynos_gpio_fdt_release(device_t dev, void *priv)
+{
+ struct exynos_gpio_pin *gpin = priv;
+
+ kmem_free(gpin, sizeof(*gpin));
+}
+
+static int
+exynos_gpio_fdt_read(device_t dev, void *priv)
+{
+ struct exynos_gpio_pin *gpin = priv;
+ int val;
+
+ val = (bus_space_read_1(gpin->pin_sc->sc_bst,
+ gpin->pin_sc->sc_bsh,
+ EXYNOS_GPIO_DAT) >> gpin->pin_no) & 1;
+
+ if (gpin->pin_actlo)
+ val = !val;
+
+ return val;
+}
+
+static void
+exynos_gpio_fdt_write(device_t dev, void *priv, int val)
+{
+ struct exynos_gpio_pin *gpin = priv;
+
+ if (gpin->pin_actlo)
+ val = !val;
+
+ val = bus_space_read_1(gpin->pin_sc->sc_bst,
+ gpin->pin_sc->sc_bsh,
+ EXYNOS_GPIO_DAT);
+ val &= ~__BIT(gpin->pin_no);
+ if (val)
+ val |= __BIT(gpin->pin_no);
+ bus_space_write_1(gpin->pin_sc->sc_bst,
+ gpin->pin_sc->sc_bsh,
+ EXYNOS_GPIO_DAT, val);
+
+}
Index: src/sys/arch/arm/samsung/files.exynos
diff -u src/sys/arch/arm/samsung/files.exynos:1.13 src/sys/arch/arm/samsung/files.exynos:1.14
--- src/sys/arch/arm/samsung/files.exynos:1.13 Thu Dec 17 22:39:37 2015
+++ src/sys/arch/arm/samsung/files.exynos Sat Dec 19 21:42:31 2015
@@ -1,4 +1,4 @@
-# $NetBSD: files.exynos,v 1.13 2015/12/17 22:39:37 marty Exp $
+# $NetBSD: files.exynos,v 1.14 2015/12/19 21:42:31 marty Exp $
#
# Configuration info for Samsung Exynos SoC ARM Peripherals
#
@@ -74,10 +74,16 @@ file arch/arm/samsung/exynos_sscom.c exy
defflag opt_sscom.h SSCOM0CONSOLE SSCOM1CONSOLE
defparam opt_sscom.h SSCOM_FREQ
+# PINCTL
+device exyopctl : gpiobus
+attach exyopctl at fdt with exynos_pinctrl
+file arch/arm/samsung/exynos_pinctrl.c exynos_pinctl | exyo_io needs-flag
+file arch/arm/samsung/exynos_gpio.c exynos_pinctl | exyo_io needs-flag
+
# GPIO
-device exyogpio : gpiobus
-attach exyogpio at exyo with exynos_gpio
-file arch/arm/samsung/exynos_gpio.c exynos_gpio | exyo_io needs-flag
+#device exyogpio : gpiobus
+#attach exyogpio at fdt with exynos_gpio
+#file arch/arm/samsung/exynos_gpio.c exynos_gpio | exyo_io needs-flag
# USB2 Host Controller (EHCI/OHCI)
device exyousb { }
Index: src/sys/arch/arm/samsung/exynos_var.h
diff -u src/sys/arch/arm/samsung/exynos_var.h:1.20 src/sys/arch/arm/samsung/exynos_var.h:1.21
--- src/sys/arch/arm/samsung/exynos_var.h:1.20 Tue Dec 15 23:13:51 2015
+++ src/sys/arch/arm/samsung/exynos_var.h Sat Dec 19 21:42:31 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_var.h,v 1.20 2015/12/15 23:13:51 marty Exp $ */
+/* $NetBSD: exynos_var.h,v 1.21 2015/12/19 21:42:31 marty Exp $ */
/*-
* Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -125,7 +125,8 @@ extern bus_space_handle_t exynos_sysreg_
extern void exynos_bootstrap(vaddr_t, vaddr_t);
extern void exynos_dma_bootstrap(psize_t memsize);
-extern void exynos_gpio_bootstrap(void);
+struct exynos_pinctrl_softc;
+extern void exynos_gpio_bank_config(struct exynos_pinctrl_softc *, int);
extern void exynos_wdt_reset(void);
extern void exynos_init_clkout_for_usb(void); // board specific
Index: src/sys/arch/evbarm/conf/EXYNOS
diff -u src/sys/arch/evbarm/conf/EXYNOS:1.2 src/sys/arch/evbarm/conf/EXYNOS:1.3
--- src/sys/arch/evbarm/conf/EXYNOS:1.2 Thu Dec 17 22:40:49 2015
+++ src/sys/arch/evbarm/conf/EXYNOS Sat Dec 19 21:42:31 2015
@@ -1,5 +1,5 @@
#
-# $NetBSD: EXYNOS,v 1.2 2015/12/17 22:40:49 marty Exp $
+# $NetBSD: EXYNOS,v 1.3 2015/12/19 21:42:31 marty Exp $
#
# ODROID-XU -- ODROID-XU4 Exynos5422 based kernel
#
@@ -209,6 +209,9 @@ fdt* at simplebus?
fregulator* at fdt?
+#interrupt controller
+gic* at fdt?
+
# Exynos SoC
exyo0 at mainbus?
@@ -223,8 +226,12 @@ sscom* at fdt? # UART ?
exyowdt0 at fdt? # watchdog
# GPIO
-exyogpio0 at exyo0
-gpio* at exyogpio?
+exyopctl0 at fdt?
+exyopctl1 at fdt?
+exyopctl2 at fdt?
+exyopctl3 at fdt?
+exyopctl4 at fdt?
+#gpio* at exyogpio?
# On-board USB
exyousb* at exyo0
Added files:
Index: src/sys/arch/arm/samsung/exynos_pinctrl.c
diff -u /dev/null src/sys/arch/arm/samsung/exynos_pinctrl.c:1.1
--- /dev/null Sat Dec 19 21:42:31 2015
+++ src/sys/arch/arm/samsung/exynos_pinctrl.c Sat Dec 19 21:42:31 2015
@@ -0,0 +1,110 @@
+/* $NetBSD: exynos_pinctrl.c,v 1.1 2015/12/19 21:42:31 marty Exp $ */
+
+/*-
+* Copyright (c) 2015 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Marty Fouts
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "opt_exynos.h"
+#include "opt_arm_debug.h"
+#include "gpio.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.1 2015/12/19 21:42:31 marty Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/gpio.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#include <arm/samsung/exynos_reg.h>
+#include <arm/samsung/exynos_io.h>
+#include <arm/samsung/exynos_intr.h>
+#include <arm/samsung/exynos_pinctrl.h>
+
+#include <dev/fdt/fdtvar.h>
+
+static int exynos_pinctrl_match(device_t, cfdata_t, void *);
+static void exynos_pinctrl_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc),
+ exynos_pinctrl_match, exynos_pinctrl_attach, NULL, NULL);
+
+static int
+exynos_pinctrl_match(device_t parent, cfdata_t cf, void *aux)
+{
+ const char * const compatible[] = { "samsung,exynos5422-pinctrl",
+ NULL };
+ struct fdt_attach_args * const faa = aux;
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+exynos_pinctrl_attach(device_t parent, device_t self, void *aux)
+{
+ struct exynos_pinctrl_softc * const sc
+ = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+ struct fdt_attach_args * const faa = aux;
+ bus_addr_t addr;
+ bus_size_t size;
+ int error;
+ int child;
+
+ if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+ aprint_error(": couldn't get registers\n");
+ return;
+ }
+
+ printf(" pinctl @ 0x%08x\n", (uint)addr);
+ sc->sc_dev = self;
+ sc->sc_bst = faa->faa_bst;
+ error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+ if (error) {
+ aprint_error(": couldn't map %#llx: %d",
+ (uint64_t)addr, error);
+ return;
+ }
+
+ for (child = OF_child(faa->faa_phandle); child;
+ child = OF_peer(child)) {
+ char result[64];
+ error = OF_getprop(child, "gpio-controller", result,
+ sizeof(result));
+ if (error == -1)
+ continue;
+ exynos_gpio_bank_config(sc,child);
+ }
+
+ aprint_naive("\n");
+ aprint_normal("\n");
+
+}