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"); + +}