The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/allwinner/aw_gpio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
    5  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
    6  * Copyright (c) 2012 Luiz Otavio O Souza.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  */
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/bus.h>
   37 
   38 #include <sys/kernel.h>
   39 #include <sys/module.h>
   40 #include <sys/rman.h>
   41 #include <sys/lock.h>
   42 #include <sys/mutex.h>
   43 #include <sys/gpio.h>
   44 #include <sys/proc.h>
   45 
   46 #include <machine/bus.h>
   47 #include <machine/resource.h>
   48 #include <machine/intr.h>
   49 
   50 #include <dev/gpio/gpiobusvar.h>
   51 #include <dev/ofw/ofw_bus.h>
   52 #include <dev/ofw/ofw_bus_subr.h>
   53 #include <dev/fdt/fdt_pinctrl.h>
   54 
   55 #include <arm/allwinner/aw_machdep.h>
   56 #include <arm/allwinner/allwinner_pinctrl.h>
   57 #include <dev/extres/clk/clk.h>
   58 #include <dev/extres/hwreset/hwreset.h>
   59 #include <dev/extres/regulator/regulator.h>
   60 
   61 #if defined(__aarch64__)
   62 #include "opt_soc.h"
   63 #endif
   64 
   65 #include "pic_if.h"
   66 #include "gpio_if.h"
   67 
   68 #define AW_GPIO_DEFAULT_CAPS    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |     \
   69           GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
   70 
   71 #define AW_GPIO_INTR_CAPS       (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |   \
   72           GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
   73 
   74 #define AW_GPIO_NONE            0
   75 #define AW_GPIO_PULLUP          1
   76 #define AW_GPIO_PULLDOWN        2
   77 
   78 #define AW_GPIO_INPUT           0
   79 #define AW_GPIO_OUTPUT          1
   80 
   81 #define AW_GPIO_DRV_MASK        0x3
   82 #define AW_GPIO_PUD_MASK        0x3
   83 
   84 #define AW_PINCTRL      1
   85 #define AW_R_PINCTRL    2
   86 
   87 struct aw_gpio_conf {
   88         struct allwinner_padconf *padconf;
   89         const char *banks;
   90 };
   91 
   92 /* Defined in aw_padconf.c */
   93 #ifdef SOC_ALLWINNER_A10
   94 extern struct allwinner_padconf a10_padconf;
   95 struct aw_gpio_conf a10_gpio_conf = {
   96         .padconf = &a10_padconf,
   97         .banks = "abcdefghi",
   98 };
   99 #endif
  100 
  101 /* Defined in a13_padconf.c */
  102 #ifdef SOC_ALLWINNER_A13
  103 extern struct allwinner_padconf a13_padconf;
  104 struct aw_gpio_conf a13_gpio_conf = {
  105         .padconf = &a13_padconf,
  106         .banks = "bcdefg",
  107 };
  108 #endif
  109 
  110 /* Defined in a20_padconf.c */
  111 #ifdef SOC_ALLWINNER_A20
  112 extern struct allwinner_padconf a20_padconf;
  113 struct aw_gpio_conf a20_gpio_conf = {
  114         .padconf = &a20_padconf,
  115         .banks = "abcdefghi",
  116 };
  117 #endif
  118 
  119 /* Defined in a31_padconf.c */
  120 #ifdef SOC_ALLWINNER_A31
  121 extern struct allwinner_padconf a31_padconf;
  122 struct aw_gpio_conf a31_gpio_conf = {
  123         .padconf = &a31_padconf,
  124         .banks = "abcdefgh",
  125 };
  126 #endif
  127 
  128 /* Defined in a31s_padconf.c */
  129 #ifdef SOC_ALLWINNER_A31S
  130 extern struct allwinner_padconf a31s_padconf;
  131 struct aw_gpio_conf a31s_gpio_conf = {
  132         .padconf = &a31s_padconf,
  133         .banks = "abcdefgh",
  134 };
  135 #endif
  136 
  137 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
  138 extern struct allwinner_padconf a31_r_padconf;
  139 struct aw_gpio_conf a31_r_gpio_conf = {
  140         .padconf = &a31_r_padconf,
  141         .banks = "lm",
  142 };
  143 #endif
  144 
  145 /* Defined in a33_padconf.c */
  146 #ifdef SOC_ALLWINNER_A33
  147 extern struct allwinner_padconf a33_padconf;
  148 struct aw_gpio_conf a33_gpio_conf = {
  149         .padconf = &a33_padconf,
  150         .banks = "bcdefgh",
  151 };
  152 #endif
  153 
  154 /* Defined in h3_padconf.c */
  155 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
  156 extern struct allwinner_padconf h3_padconf;
  157 extern struct allwinner_padconf h3_r_padconf;
  158 struct aw_gpio_conf h3_gpio_conf = {
  159         .padconf = &h3_padconf,
  160         .banks = "acdefg",
  161 };
  162 struct aw_gpio_conf h3_r_gpio_conf = {
  163         .padconf = &h3_r_padconf,
  164         .banks = "l",
  165 };
  166 #endif
  167 
  168 /* Defined in a83t_padconf.c */
  169 #ifdef SOC_ALLWINNER_A83T
  170 extern struct allwinner_padconf a83t_padconf;
  171 extern struct allwinner_padconf a83t_r_padconf;
  172 struct aw_gpio_conf a83t_gpio_conf = {
  173         .padconf = &a83t_padconf,
  174         .banks = "bcdefgh"
  175 };
  176 struct aw_gpio_conf a83t_r_gpio_conf = {
  177         .padconf = &a83t_r_padconf,
  178         .banks = "l",
  179 };
  180 #endif
  181 
  182 /* Defined in a64_padconf.c */
  183 #ifdef SOC_ALLWINNER_A64
  184 extern struct allwinner_padconf a64_padconf;
  185 extern struct allwinner_padconf a64_r_padconf;
  186 struct aw_gpio_conf a64_gpio_conf = {
  187         .padconf = &a64_padconf,
  188         .banks = "bcdefgh",
  189 };
  190 struct aw_gpio_conf a64_r_gpio_conf = {
  191         .padconf = &a64_r_padconf,
  192         .banks = "l",
  193 };
  194 #endif
  195 
  196 /* Defined in h6_padconf.c */
  197 #ifdef SOC_ALLWINNER_H6
  198 extern struct allwinner_padconf h6_padconf;
  199 extern struct allwinner_padconf h6_r_padconf;
  200 struct aw_gpio_conf h6_gpio_conf = {
  201         .padconf = &h6_padconf,
  202         .banks = "cdfgh",
  203 };
  204 struct aw_gpio_conf h6_r_gpio_conf = {
  205         .padconf = &h6_r_padconf,
  206         .banks = "lm",
  207 };
  208 #endif
  209 
  210 static struct ofw_compat_data compat_data[] = {
  211 #ifdef SOC_ALLWINNER_A10
  212         {"allwinner,sun4i-a10-pinctrl",         (uintptr_t)&a10_gpio_conf},
  213 #endif
  214 #ifdef SOC_ALLWINNER_A13
  215         {"allwinner,sun5i-a13-pinctrl",         (uintptr_t)&a13_gpio_conf},
  216 #endif
  217 #ifdef SOC_ALLWINNER_A20
  218         {"allwinner,sun7i-a20-pinctrl",         (uintptr_t)&a20_gpio_conf},
  219 #endif
  220 #ifdef SOC_ALLWINNER_A31
  221         {"allwinner,sun6i-a31-pinctrl",         (uintptr_t)&a31_gpio_conf},
  222 #endif
  223 #ifdef SOC_ALLWINNER_A31S
  224         {"allwinner,sun6i-a31s-pinctrl",        (uintptr_t)&a31s_gpio_conf},
  225 #endif
  226 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
  227         {"allwinner,sun6i-a31-r-pinctrl",       (uintptr_t)&a31_r_gpio_conf},
  228 #endif
  229 #ifdef SOC_ALLWINNER_A33
  230         {"allwinner,sun6i-a33-pinctrl",         (uintptr_t)&a33_gpio_conf},
  231 #endif
  232 #ifdef SOC_ALLWINNER_A83T
  233         {"allwinner,sun8i-a83t-pinctrl",        (uintptr_t)&a83t_gpio_conf},
  234         {"allwinner,sun8i-a83t-r-pinctrl",      (uintptr_t)&a83t_r_gpio_conf},
  235 #endif
  236 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
  237         {"allwinner,sun8i-h3-pinctrl",          (uintptr_t)&h3_gpio_conf},
  238         {"allwinner,sun50i-h5-pinctrl",         (uintptr_t)&h3_gpio_conf},
  239         {"allwinner,sun8i-h3-r-pinctrl",        (uintptr_t)&h3_r_gpio_conf},
  240 #endif
  241 #ifdef SOC_ALLWINNER_A64
  242         {"allwinner,sun50i-a64-pinctrl",        (uintptr_t)&a64_gpio_conf},
  243         {"allwinner,sun50i-a64-r-pinctrl",      (uintptr_t)&a64_r_gpio_conf},
  244 #endif
  245 #ifdef SOC_ALLWINNER_H6
  246         {"allwinner,sun50i-h6-pinctrl", (uintptr_t)&h6_gpio_conf},
  247         {"allwinner,sun50i-h6-r-pinctrl",       (uintptr_t)&h6_r_gpio_conf},
  248 #endif
  249         {NULL,  0}
  250 };
  251 
  252 struct clk_list {
  253         TAILQ_ENTRY(clk_list)   next;
  254         clk_t                   clk;
  255 };
  256 
  257 struct gpio_irqsrc {
  258         struct intr_irqsrc      isrc;
  259         u_int                   irq;
  260         uint32_t                mode;
  261         uint32_t                pin;
  262         uint32_t                bank;
  263         uint32_t                intnum;
  264         uint32_t                intfunc;
  265         uint32_t                oldfunc;
  266         bool                    enabled;
  267 };
  268 
  269 #define AW_GPIO_MEMRES          0
  270 #define AW_GPIO_IRQRES          1
  271 #define AW_GPIO_RESSZ           2
  272 
  273 struct aw_gpio_softc {
  274         device_t                sc_dev;
  275         device_t                sc_busdev;
  276         struct resource *       sc_res[AW_GPIO_RESSZ];
  277         struct mtx              sc_mtx;
  278         struct resource *       sc_mem_res;
  279         struct resource *       sc_irq_res;
  280         void *                  sc_intrhand;
  281         struct aw_gpio_conf     *conf;
  282         TAILQ_HEAD(, clk_list)          clk_list;
  283 
  284         struct gpio_irqsrc      *gpio_pic_irqsrc;
  285         int                     nirqs;
  286 };
  287 
  288 static struct resource_spec aw_gpio_res_spec[] = {
  289         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  290         { SYS_RES_IRQ,          0,      RF_ACTIVE | RF_SHAREABLE },
  291         { -1,                   0,      0 }
  292 };
  293 
  294 #define AW_GPIO_LOCK(_sc)               mtx_lock_spin(&(_sc)->sc_mtx)
  295 #define AW_GPIO_UNLOCK(_sc)             mtx_unlock_spin(&(_sc)->sc_mtx)
  296 #define AW_GPIO_LOCK_ASSERT(_sc)        mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
  297 
  298 #define AW_GPIO_GP_CFG(_bank, _idx)     0x00 + ((_bank) * 0x24) + ((_idx) << 2)
  299 #define AW_GPIO_GP_DAT(_bank)           0x10 + ((_bank) * 0x24)
  300 #define AW_GPIO_GP_DRV(_bank, _idx)     0x14 + ((_bank) * 0x24) + ((_idx) << 2)
  301 #define AW_GPIO_GP_PUL(_bank, _idx)     0x1c + ((_bank) * 0x24) + ((_idx) << 2)
  302 
  303 #define AW_GPIO_GP_INT_BASE(_bank)      (0x200 + 0x20 * _bank)
  304 
  305 #define AW_GPIO_GP_INT_CFG(_bank, _pin) (AW_GPIO_GP_INT_BASE(_bank) + (0x4 * ((_pin) / 8)))
  306 #define AW_GPIO_GP_INT_CTL(_bank)       (AW_GPIO_GP_INT_BASE(_bank) + 0x10)
  307 #define AW_GPIO_GP_INT_STA(_bank)       (AW_GPIO_GP_INT_BASE(_bank) + 0x14)
  308 #define AW_GPIO_GP_INT_DEB(_bank)       (AW_GPIO_GP_INT_BASE(_bank) + 0x18)
  309 
  310 #define AW_GPIO_INT_EDGE_POSITIVE       0x0
  311 #define AW_GPIO_INT_EDGE_NEGATIVE       0x1
  312 #define AW_GPIO_INT_LEVEL_HIGH          0x2
  313 #define AW_GPIO_INT_LEVEL_LOW           0x3
  314 #define AW_GPIO_INT_EDGE_BOTH           0x4
  315 
  316 static char *aw_gpio_parse_function(phandle_t node);
  317 static const char **aw_gpio_parse_pins(phandle_t node, int *pins_nb);
  318 static uint32_t aw_gpio_parse_bias(phandle_t node);
  319 static int aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive);
  320 
  321 static int aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value);
  322 static int aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
  323 static int aw_gpio_pin_get_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int *value);
  324 static int aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int value);
  325 
  326 static void aw_gpio_intr(void *arg);
  327 static void aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc);
  328 static void aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc);
  329 static void aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc);
  330 static int aw_gpio_register_isrcs(struct aw_gpio_softc *sc);
  331 
  332 #define AW_GPIO_WRITE(_sc, _off, _val)          \
  333         bus_write_4((_sc)->sc_res[AW_GPIO_MEMRES], _off, _val)
  334 #define AW_GPIO_READ(_sc, _off)         \
  335         bus_read_4((_sc)->sc_res[AW_GPIO_MEMRES], _off)
  336 
  337 static uint32_t
  338 aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin)
  339 {
  340         uint32_t bank, func, offset;
  341 
  342         /* Must be called with lock held. */
  343         AW_GPIO_LOCK_ASSERT(sc);
  344 
  345         if (pin > sc->conf->padconf->npins)
  346                 return (0);
  347         bank = sc->conf->padconf->pins[pin].port;
  348         pin = sc->conf->padconf->pins[pin].pin;
  349         offset = ((pin & 0x07) << 2);
  350 
  351         func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
  352 
  353         return ((func >> offset) & 0x7);
  354 }
  355 
  356 static int
  357 aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f)
  358 {
  359         uint32_t bank, data, offset;
  360 
  361         /* Check if the function exists in the padconf data */
  362         if (sc->conf->padconf->pins[pin].functions[f] == NULL)
  363                 return (EINVAL);
  364 
  365         /* Must be called with lock held. */
  366         AW_GPIO_LOCK_ASSERT(sc);
  367 
  368         bank = sc->conf->padconf->pins[pin].port;
  369         pin = sc->conf->padconf->pins[pin].pin;
  370         offset = ((pin & 0x07) << 2);
  371 
  372         data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
  373         data &= ~(7 << offset);
  374         data |= (f << offset);
  375         AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data);
  376 
  377         return (0);
  378 }
  379 
  380 static uint32_t
  381 aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin)
  382 {
  383         uint32_t bank, offset, val;
  384 
  385         /* Must be called with lock held. */
  386         AW_GPIO_LOCK_ASSERT(sc);
  387 
  388         bank = sc->conf->padconf->pins[pin].port;
  389         pin = sc->conf->padconf->pins[pin].pin;
  390         offset = ((pin & 0x0f) << 1);
  391 
  392         val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
  393 
  394         return ((val >> offset) & AW_GPIO_PUD_MASK);
  395 }
  396 
  397 static void
  398 aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state)
  399 {
  400         uint32_t bank, offset, val;
  401 
  402         if (aw_gpio_get_pud(sc, pin) == state)
  403                 return;
  404 
  405         /* Must be called with lock held. */
  406         AW_GPIO_LOCK_ASSERT(sc);
  407 
  408         bank = sc->conf->padconf->pins[pin].port;
  409         pin = sc->conf->padconf->pins[pin].pin;
  410         offset = ((pin & 0x0f) << 1);
  411 
  412         val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
  413         val &= ~(AW_GPIO_PUD_MASK << offset);
  414         val |= (state << offset);
  415         AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val);
  416 }
  417 
  418 static uint32_t
  419 aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin)
  420 {
  421         uint32_t bank, offset, val;
  422 
  423         /* Must be called with lock held. */
  424         AW_GPIO_LOCK_ASSERT(sc);
  425 
  426         bank = sc->conf->padconf->pins[pin].port;
  427         pin = sc->conf->padconf->pins[pin].pin;
  428         offset = ((pin & 0x0f) << 1);
  429 
  430         val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
  431 
  432         return ((val >> offset) & AW_GPIO_DRV_MASK);
  433 }
  434 
  435 static void
  436 aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive)
  437 {
  438         uint32_t bank, offset, val;
  439 
  440         if (aw_gpio_get_drv(sc, pin) == drive)
  441                 return;
  442 
  443         /* Must be called with lock held. */
  444         AW_GPIO_LOCK_ASSERT(sc);
  445 
  446         bank = sc->conf->padconf->pins[pin].port;
  447         pin = sc->conf->padconf->pins[pin].pin;
  448         offset = ((pin & 0x0f) << 1);
  449 
  450         val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
  451         val &= ~(AW_GPIO_DRV_MASK << offset);
  452         val |= (drive << offset);
  453         AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(bank, pin >> 4), val);
  454 }
  455 
  456 static int
  457 aw_gpio_pin_configure(struct aw_gpio_softc *sc, uint32_t pin, uint32_t flags)
  458 {
  459         u_int val;
  460         int err = 0;
  461 
  462         /* Must be called with lock held. */
  463         AW_GPIO_LOCK_ASSERT(sc);
  464 
  465         if (pin > sc->conf->padconf->npins)
  466                 return (EINVAL);
  467 
  468         /* Manage input/output. */
  469         if (flags & GPIO_PIN_INPUT) {
  470                 err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
  471         } else if ((flags & GPIO_PIN_OUTPUT) &&
  472             aw_gpio_get_function(sc, pin) != AW_GPIO_OUTPUT) {
  473                 if (flags & GPIO_PIN_PRESET_LOW) {
  474                         aw_gpio_pin_set_locked(sc, pin, 0);
  475                 } else if (flags & GPIO_PIN_PRESET_HIGH) {
  476                         aw_gpio_pin_set_locked(sc, pin, 1);
  477                 } else {
  478                         /* Read the pin and preset output to current state. */
  479                         err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
  480                         if (err == 0) {
  481                                 aw_gpio_pin_get_locked(sc, pin, &val);
  482                                 aw_gpio_pin_set_locked(sc, pin, val);
  483                         }
  484                 }
  485                 if (err == 0)
  486                         err = aw_gpio_set_function(sc, pin, AW_GPIO_OUTPUT);
  487         }
  488 
  489         if (err)
  490                 return (err);
  491 
  492         /* Manage Pull-up/pull-down. */
  493         if (flags & GPIO_PIN_PULLUP)
  494                 aw_gpio_set_pud(sc, pin, AW_GPIO_PULLUP);
  495         else if (flags & GPIO_PIN_PULLDOWN)
  496                 aw_gpio_set_pud(sc, pin, AW_GPIO_PULLDOWN);
  497         else
  498                 aw_gpio_set_pud(sc, pin, AW_GPIO_NONE);
  499 
  500         return (0);
  501 }
  502 
  503 static device_t
  504 aw_gpio_get_bus(device_t dev)
  505 {
  506         struct aw_gpio_softc *sc;
  507 
  508         sc = device_get_softc(dev);
  509 
  510         return (sc->sc_busdev);
  511 }
  512 
  513 static int
  514 aw_gpio_pin_max(device_t dev, int *maxpin)
  515 {
  516         struct aw_gpio_softc *sc;
  517 
  518         sc = device_get_softc(dev);
  519 
  520         *maxpin = sc->conf->padconf->npins - 1;
  521         return (0);
  522 }
  523 
  524 static int
  525 aw_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
  526 {
  527         struct aw_gpio_softc *sc;
  528 
  529         sc = device_get_softc(dev);
  530         if (pin >= sc->conf->padconf->npins)
  531                 return (EINVAL);
  532 
  533         *caps = AW_GPIO_DEFAULT_CAPS;
  534         if (sc->conf->padconf->pins[pin].eint_func != 0)
  535                 *caps |= AW_GPIO_INTR_CAPS;
  536 
  537         return (0);
  538 }
  539 
  540 static int
  541 aw_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
  542 {
  543         struct aw_gpio_softc *sc;
  544         uint32_t func;
  545         uint32_t pud;
  546 
  547         sc = device_get_softc(dev);
  548         if (pin >= sc->conf->padconf->npins)
  549                 return (EINVAL);
  550 
  551         AW_GPIO_LOCK(sc);
  552         func = aw_gpio_get_function(sc, pin);
  553         switch (func) {
  554         case AW_GPIO_INPUT:
  555                 *flags = GPIO_PIN_INPUT;
  556                 break;
  557         case AW_GPIO_OUTPUT:
  558                 *flags = GPIO_PIN_OUTPUT;
  559                 break;
  560         default:
  561                 *flags = 0;
  562                 break;
  563         }
  564 
  565         pud = aw_gpio_get_pud(sc, pin);
  566         switch (pud) {
  567         case AW_GPIO_PULLDOWN:
  568                 *flags |= GPIO_PIN_PULLDOWN;
  569                 break;
  570         case AW_GPIO_PULLUP:
  571                 *flags |= GPIO_PIN_PULLUP;
  572                 break;
  573         default:
  574                 break;
  575         }
  576 
  577         AW_GPIO_UNLOCK(sc);
  578 
  579         return (0);
  580 }
  581 
  582 static int
  583 aw_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
  584 {
  585         struct aw_gpio_softc *sc;
  586 
  587         sc = device_get_softc(dev);
  588         if (pin >= sc->conf->padconf->npins)
  589                 return (EINVAL);
  590 
  591         snprintf(name, GPIOMAXNAME - 1, "%s",
  592             sc->conf->padconf->pins[pin].name);
  593         name[GPIOMAXNAME - 1] = '\0';
  594 
  595         return (0);
  596 }
  597 
  598 static int
  599 aw_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
  600 {
  601         struct aw_gpio_softc *sc;
  602         int err;
  603 
  604         sc = device_get_softc(dev);
  605         if (pin > sc->conf->padconf->npins)
  606                 return (EINVAL);
  607 
  608         AW_GPIO_LOCK(sc);
  609         err = aw_gpio_pin_configure(sc, pin, flags);
  610         AW_GPIO_UNLOCK(sc);
  611 
  612         return (err);
  613 }
  614 
  615 static int
  616 aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin,
  617     unsigned int value)
  618 {
  619         uint32_t bank, data;
  620 
  621         AW_GPIO_LOCK_ASSERT(sc);
  622 
  623         if (pin > sc->conf->padconf->npins)
  624                 return (EINVAL);
  625 
  626         bank = sc->conf->padconf->pins[pin].port;
  627         pin = sc->conf->padconf->pins[pin].pin;
  628 
  629         data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
  630         if (value)
  631                 data |= (1 << pin);
  632         else
  633                 data &= ~(1 << pin);
  634         AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
  635 
  636         return (0);
  637 }
  638 
  639 static int
  640 aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
  641 {
  642         struct aw_gpio_softc *sc;
  643         int ret;
  644 
  645         sc = device_get_softc(dev);
  646 
  647         AW_GPIO_LOCK(sc);
  648         ret = aw_gpio_pin_set_locked(sc, pin, value);
  649         AW_GPIO_UNLOCK(sc);
  650 
  651         return (ret);
  652 }
  653 
  654 static int
  655 aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin,
  656     unsigned int *val)
  657 {
  658         uint32_t bank, reg_data;
  659 
  660         AW_GPIO_LOCK_ASSERT(sc);
  661 
  662         if (pin > sc->conf->padconf->npins)
  663                 return (EINVAL);
  664 
  665         bank = sc->conf->padconf->pins[pin].port;
  666         pin = sc->conf->padconf->pins[pin].pin;
  667 
  668         reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
  669         *val = (reg_data & (1 << pin)) ? 1 : 0;
  670 
  671         return (0);
  672 }
  673 
  674 static char *
  675 aw_gpio_parse_function(phandle_t node)
  676 {
  677         char *function;
  678 
  679         if (OF_getprop_alloc(node, "function",
  680             (void **)&function) != -1)
  681                 return (function);
  682         if (OF_getprop_alloc(node, "allwinner,function",
  683             (void **)&function) != -1)
  684                 return (function);
  685 
  686         return (NULL);
  687 }
  688 
  689 static const char **
  690 aw_gpio_parse_pins(phandle_t node, int *pins_nb)
  691 {
  692         const char **pinlist;
  693 
  694         *pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist);
  695         if (*pins_nb > 0)
  696                 return (pinlist);
  697 
  698         *pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins",
  699             &pinlist);
  700         if (*pins_nb > 0)
  701                 return (pinlist);
  702 
  703         return (NULL);
  704 }
  705 
  706 static uint32_t
  707 aw_gpio_parse_bias(phandle_t node)
  708 {
  709         uint32_t bias;
  710 
  711         if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1)
  712                 return (bias);
  713         if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1)
  714                 return (bias);
  715         if (OF_hasprop(node, "bias-disable"))
  716                 return (AW_GPIO_NONE);
  717         if (OF_hasprop(node, "bias-pull-up"))
  718                 return (AW_GPIO_PULLUP);
  719         if (OF_hasprop(node, "bias-pull-down"))
  720                 return (AW_GPIO_PULLDOWN);
  721 
  722         return (AW_GPIO_NONE);
  723 }
  724 
  725 static int
  726 aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive)
  727 {
  728         uint32_t drive_str;
  729 
  730         if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1)
  731                 return (0);
  732         if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1)
  733                 return (0);
  734         if (OF_getencprop(node, "drive-strength", &drive_str,
  735             sizeof(drive_str)) != -1) {
  736                 *drive = (drive_str / 10) - 1;
  737                 return (0);
  738         }
  739 
  740         return (1);
  741 }
  742 
  743 static int
  744 aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
  745 {
  746         struct aw_gpio_softc *sc;
  747         int ret;
  748 
  749         sc = device_get_softc(dev);
  750 
  751         AW_GPIO_LOCK(sc);
  752         ret = aw_gpio_pin_get_locked(sc, pin, val);
  753         AW_GPIO_UNLOCK(sc);
  754 
  755         return (ret);
  756 }
  757 
  758 static int
  759 aw_gpio_pin_toggle(device_t dev, uint32_t pin)
  760 {
  761         struct aw_gpio_softc *sc;
  762         uint32_t bank, data;
  763 
  764         sc = device_get_softc(dev);
  765         if (pin > sc->conf->padconf->npins)
  766                 return (EINVAL);
  767 
  768         bank = sc->conf->padconf->pins[pin].port;
  769         pin = sc->conf->padconf->pins[pin].pin;
  770 
  771         AW_GPIO_LOCK(sc);
  772         data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
  773         if (data & (1 << pin))
  774                 data &= ~(1 << pin);
  775         else
  776                 data |= (1 << pin);
  777         AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
  778         AW_GPIO_UNLOCK(sc);
  779 
  780         return (0);
  781 }
  782 
  783 static int
  784 aw_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
  785     uint32_t change_pins, uint32_t *orig_pins)
  786 {
  787         struct aw_gpio_softc *sc;
  788         uint32_t bank, data, pin;
  789 
  790         sc = device_get_softc(dev);
  791         if (first_pin > sc->conf->padconf->npins)
  792                 return (EINVAL);
  793 
  794         /*
  795          * We require that first_pin refers to the first pin in a bank, because
  796          * this API is not about convenience, it's for making a set of pins
  797          * change simultaneously (required) with reasonably high performance
  798          * (desired); we need to do a read-modify-write on a single register.
  799          */
  800         bank = sc->conf->padconf->pins[first_pin].port;
  801         pin = sc->conf->padconf->pins[first_pin].pin;
  802         if (pin != 0)
  803                 return (EINVAL);
  804 
  805         AW_GPIO_LOCK(sc);
  806         data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
  807         if ((clear_pins | change_pins) != 0) 
  808                 AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank),
  809                     (data & ~clear_pins) ^ change_pins);
  810         AW_GPIO_UNLOCK(sc);
  811 
  812         if (orig_pins != NULL)
  813                 *orig_pins = data;
  814 
  815         return (0);
  816 }
  817 
  818 static int
  819 aw_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
  820     uint32_t *pin_flags)
  821 {
  822         struct aw_gpio_softc *sc;
  823         uint32_t pin;
  824         int err;
  825 
  826         sc = device_get_softc(dev);
  827         if (first_pin > sc->conf->padconf->npins)
  828                 return (EINVAL);
  829 
  830         if (sc->conf->padconf->pins[first_pin].pin != 0)
  831                 return (EINVAL);
  832 
  833         /*
  834          * The configuration for a bank of pins is scattered among several
  835          * registers; we cannot g'tee to simultaneously change the state of all
  836          * the pins in the flags array.  So just loop through the array
  837          * configuring each pin for now.  If there was a strong need, it might
  838          * be possible to support some limited simultaneous config, such as
  839          * adjacent groups of 8 pins that line up the same as the config regs.
  840          */
  841         for (err = 0, pin = first_pin; err == 0 && pin < num_pins; ++pin) {
  842                 if (pin_flags[pin] & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
  843                         err = aw_gpio_pin_configure(sc, pin, pin_flags[pin]);
  844         }
  845 
  846         return (err);
  847 }
  848 
  849 static int
  850 aw_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
  851     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
  852 {
  853         struct aw_gpio_softc *sc;
  854         int i;
  855 
  856         sc = device_get_softc(bus);
  857 
  858         /* The GPIO pins are mapped as: <gpio-phandle bank pin flags>. */
  859         for (i = 0; i < sc->conf->padconf->npins; i++)
  860                 if (sc->conf->padconf->pins[i].port == gpios[0] &&
  861                     sc->conf->padconf->pins[i].pin == gpios[1]) {
  862                         *pin = i;
  863                         break;
  864                 }
  865         *flags = gpios[gcells - 1];
  866 
  867         return (0);
  868 }
  869 
  870 static int
  871 aw_find_pinnum_by_name(struct aw_gpio_softc *sc, const char *pinname)
  872 {
  873         int i;
  874 
  875         for (i = 0; i < sc->conf->padconf->npins; i++)
  876                 if (!strcmp(pinname, sc->conf->padconf->pins[i].name))
  877                         return i;
  878 
  879         return (-1);
  880 }
  881 
  882 static int
  883 aw_find_pin_func(struct aw_gpio_softc *sc, int pin, const char *func)
  884 {
  885         int i;
  886 
  887         for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++)
  888                 if (sc->conf->padconf->pins[pin].functions[i] &&
  889                     !strcmp(func, sc->conf->padconf->pins[pin].functions[i]))
  890                         return (i);
  891 
  892         return (-1);
  893 }
  894 
  895 static int
  896 aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
  897 {
  898         struct aw_gpio_softc *sc;
  899         phandle_t node;
  900         const char **pinlist = NULL;
  901         char *pin_function = NULL;
  902         uint32_t pin_drive, pin_pull;
  903         int pins_nb, pin_num, pin_func, i, ret;
  904         bool set_drive;
  905 
  906         sc = device_get_softc(dev);
  907         node = OF_node_from_xref(cfgxref);
  908         ret = 0;
  909         set_drive = false;
  910 
  911         /* Getting all prop for configuring pins */
  912         pinlist = aw_gpio_parse_pins(node, &pins_nb);
  913         if (pinlist == NULL)
  914                 return (ENOENT);
  915 
  916         pin_function = aw_gpio_parse_function(node);
  917         if (pin_function == NULL) {
  918                 ret = ENOENT;
  919                 goto out;
  920         }
  921 
  922         if (aw_gpio_parse_drive_strength(node, &pin_drive) == 0)
  923                 set_drive = true;
  924 
  925         pin_pull = aw_gpio_parse_bias(node);
  926 
  927         /* Configure each pin to the correct function, drive and pull */
  928         for (i = 0; i < pins_nb; i++) {
  929                 pin_num = aw_find_pinnum_by_name(sc, pinlist[i]);
  930                 if (pin_num == -1) {
  931                         ret = ENOENT;
  932                         goto out;
  933                 }
  934                 pin_func = aw_find_pin_func(sc, pin_num, pin_function);
  935                 if (pin_func == -1) {
  936                         ret = ENOENT;
  937                         goto out;
  938                 }
  939 
  940                 AW_GPIO_LOCK(sc);
  941 
  942                 if (aw_gpio_get_function(sc, pin_num) != pin_func)
  943                         aw_gpio_set_function(sc, pin_num, pin_func);
  944                 if (set_drive)
  945                         aw_gpio_set_drv(sc, pin_num, pin_drive);
  946                 if (pin_pull != AW_GPIO_NONE)
  947                         aw_gpio_set_pud(sc, pin_num, pin_pull);
  948 
  949                 AW_GPIO_UNLOCK(sc);
  950         }
  951 
  952  out:
  953         OF_prop_free(pinlist);
  954         OF_prop_free(pin_function);
  955         return (ret);
  956 }
  957 
  958 static void
  959 aw_gpio_enable_bank_supply(void *arg)
  960 {
  961         struct aw_gpio_softc *sc = arg;
  962         regulator_t vcc_supply;
  963         char bank_reg_name[16];
  964         int i, nbanks;
  965 
  966         nbanks = strlen(sc->conf->banks);
  967         for (i = 0; i < nbanks; i++) {
  968                 snprintf(bank_reg_name, sizeof(bank_reg_name), "vcc-p%c-supply",
  969                     sc->conf->banks[i]);
  970 
  971                 if (regulator_get_by_ofw_property(sc->sc_dev, 0, bank_reg_name, &vcc_supply) == 0) {
  972                         if (bootverbose)
  973                                 device_printf(sc->sc_dev,
  974                                     "Enabling regulator for gpio bank %c\n",
  975                                     sc->conf->banks[i]);
  976                         if (regulator_enable(vcc_supply) != 0) {
  977                                 device_printf(sc->sc_dev,
  978                                     "Cannot enable regulator for bank %c\n",
  979                                     sc->conf->banks[i]);
  980                         }
  981                 }
  982         }
  983 }
  984 
  985 static int
  986 aw_gpio_probe(device_t dev)
  987 {
  988 
  989         if (!ofw_bus_status_okay(dev))
  990                 return (ENXIO);
  991 
  992         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
  993                 return (ENXIO);
  994 
  995         device_set_desc(dev, "Allwinner GPIO/Pinmux controller");
  996         return (BUS_PROBE_DEFAULT);
  997 }
  998 
  999 static int
 1000 aw_gpio_attach(device_t dev)
 1001 {
 1002         int error;
 1003         phandle_t gpio;
 1004         struct aw_gpio_softc *sc;
 1005         struct clk_list *clkp, *clkp_tmp;
 1006         clk_t clk;
 1007         hwreset_t rst = NULL;
 1008         int off, err, clkret;
 1009 
 1010         sc = device_get_softc(dev);
 1011         sc->sc_dev = dev;
 1012 
 1013         mtx_init(&sc->sc_mtx, "aw gpio", "gpio", MTX_SPIN);
 1014 
 1015         if (bus_alloc_resources(dev, aw_gpio_res_spec, sc->sc_res) != 0) {
 1016                 device_printf(dev, "cannot allocate device resources\n");
 1017                 return (ENXIO);
 1018         }
 1019 
 1020         if (bus_setup_intr(dev, sc->sc_res[AW_GPIO_IRQRES],
 1021             INTR_TYPE_CLK | INTR_MPSAFE, NULL, aw_gpio_intr, sc,
 1022             &sc->sc_intrhand)) {
 1023                 device_printf(dev, "cannot setup interrupt handler\n");
 1024                 goto fail;
 1025         }
 1026 
 1027         /* Find our node. */
 1028         gpio = ofw_bus_get_node(sc->sc_dev);
 1029         if (!OF_hasprop(gpio, "gpio-controller"))
 1030                 /* Node is not a GPIO controller. */
 1031                 goto fail;
 1032 
 1033         /* Use the right pin data for the current SoC */
 1034         sc->conf = (struct aw_gpio_conf *)ofw_bus_search_compatible(dev,
 1035             compat_data)->ocd_data;
 1036 
 1037         if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
 1038                 error = hwreset_deassert(rst);
 1039                 if (error != 0) {
 1040                         device_printf(dev, "cannot de-assert reset\n");
 1041                         goto fail;
 1042                 }
 1043         }
 1044 
 1045         TAILQ_INIT(&sc->clk_list);
 1046         for (off = 0, clkret = 0; clkret == 0; off++) {
 1047                 clkret = clk_get_by_ofw_index(dev, 0, off, &clk);
 1048                 if (clkret != 0)
 1049                         break;
 1050                 err = clk_enable(clk);
 1051                 if (err != 0) {
 1052                         device_printf(dev, "Could not enable clock %s\n",
 1053                             clk_get_name(clk));
 1054                         goto fail;
 1055                 }
 1056                 clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO);
 1057                 clkp->clk = clk;
 1058                 TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
 1059         }
 1060         if (clkret != 0 && clkret != ENOENT) {
 1061                 device_printf(dev, "Could not find clock at offset %d (%d)\n",
 1062                     off, clkret);
 1063                 goto fail;
 1064         }
 1065 
 1066         aw_gpio_register_isrcs(sc);
 1067         intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
 1068 
 1069         sc->sc_busdev = gpiobus_attach_bus(dev);
 1070         if (sc->sc_busdev == NULL)
 1071                 goto fail;
 1072 
 1073         /*
 1074          * Register as a pinctrl device
 1075          */
 1076         fdt_pinctrl_register(dev, "pins");
 1077         fdt_pinctrl_configure_tree(dev);
 1078         fdt_pinctrl_register(dev, "allwinner,pins");
 1079         fdt_pinctrl_configure_tree(dev);
 1080 
 1081         config_intrhook_oneshot(aw_gpio_enable_bank_supply, sc);
 1082 
 1083         return (0);
 1084 
 1085 fail:
 1086         if (sc->sc_irq_res)
 1087                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
 1088         if (sc->sc_mem_res)
 1089                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
 1090         mtx_destroy(&sc->sc_mtx);
 1091 
 1092         /* Disable clock */
 1093         TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
 1094                 err = clk_disable(clkp->clk);
 1095                 if (err != 0)
 1096                         device_printf(dev, "Could not disable clock %s\n",
 1097                             clk_get_name(clkp->clk));
 1098                 err = clk_release(clkp->clk);
 1099                 if (err != 0)
 1100                         device_printf(dev, "Could not release clock %s\n",
 1101                             clk_get_name(clkp->clk));
 1102                 TAILQ_REMOVE(&sc->clk_list, clkp, next);
 1103                 free(clkp, M_DEVBUF);
 1104         }
 1105 
 1106         /* Assert resets */
 1107         if (rst) {
 1108                 hwreset_assert(rst);
 1109                 hwreset_release(rst);
 1110         }
 1111 
 1112         return (ENXIO);
 1113 }
 1114 
 1115 static int
 1116 aw_gpio_detach(device_t dev)
 1117 {
 1118 
 1119         return (EBUSY);
 1120 }
 1121 
 1122 static void
 1123 aw_gpio_intr(void *arg)
 1124 {
 1125         struct aw_gpio_softc *sc;
 1126         struct intr_irqsrc *isrc;
 1127         uint32_t reg;
 1128         int irq;
 1129 
 1130         sc = (struct aw_gpio_softc *)arg;
 1131 
 1132         AW_GPIO_LOCK(sc);
 1133         for (irq = 0; irq < sc->nirqs; irq++) {
 1134                 if (!sc->gpio_pic_irqsrc[irq].enabled)
 1135                         continue;
 1136 
 1137                 reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_STA(sc->gpio_pic_irqsrc[irq].bank));
 1138                 if (!(reg & (1 << sc->gpio_pic_irqsrc[irq].intnum)))
 1139                         continue;
 1140 
 1141                 isrc = &sc->gpio_pic_irqsrc[irq].isrc;
 1142                 if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) {
 1143                         aw_gpio_pic_disable_intr_locked(sc, isrc);
 1144                         aw_gpio_pic_post_filter(sc->sc_dev, isrc);
 1145                         device_printf(sc->sc_dev, "Stray irq %u disabled\n", irq);
 1146                 }
 1147         }
 1148         AW_GPIO_UNLOCK(sc);
 1149 }
 1150 
 1151 /*
 1152  * Interrupts support
 1153  */
 1154 
 1155 static int
 1156 aw_gpio_register_isrcs(struct aw_gpio_softc *sc)
 1157 {
 1158         const char *name;
 1159         int nirqs;
 1160         int pin;
 1161         int err;
 1162 
 1163         name = device_get_nameunit(sc->sc_dev);
 1164 
 1165         for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
 1166                 if (sc->conf->padconf->pins[pin].eint_func == 0)
 1167                         continue;
 1168 
 1169                 nirqs++;
 1170         }
 1171 
 1172         sc->gpio_pic_irqsrc = malloc(sizeof(*sc->gpio_pic_irqsrc) * nirqs,
 1173             M_DEVBUF, M_WAITOK | M_ZERO);
 1174         for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
 1175                 if (sc->conf->padconf->pins[pin].eint_func == 0)
 1176                         continue;
 1177 
 1178                 sc->gpio_pic_irqsrc[nirqs].pin = pin;
 1179                 sc->gpio_pic_irqsrc[nirqs].bank = sc->conf->padconf->pins[pin].eint_bank;
 1180                 sc->gpio_pic_irqsrc[nirqs].intnum = sc->conf->padconf->pins[pin].eint_num;
 1181                 sc->gpio_pic_irqsrc[nirqs].intfunc = sc->conf->padconf->pins[pin].eint_func;
 1182                 sc->gpio_pic_irqsrc[nirqs].irq = nirqs;
 1183                 sc->gpio_pic_irqsrc[nirqs].mode = GPIO_INTR_CONFORM;
 1184 
 1185                 err = intr_isrc_register(&sc->gpio_pic_irqsrc[nirqs].isrc,
 1186                     sc->sc_dev, 0, "%s,%s", name,
 1187                     sc->conf->padconf->pins[pin].functions[sc->conf->padconf->pins[pin].eint_func]);
 1188                 if (err) {
 1189                         device_printf(sc->sc_dev, "intr_isrs_register failed for irq %d\n", nirqs);
 1190                 }
 1191 
 1192                 nirqs++;
 1193         }
 1194 
 1195         sc->nirqs = nirqs;
 1196 
 1197         return (0);
 1198 }
 1199 
 1200 static void
 1201 aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc)
 1202 {
 1203         u_int irq;
 1204         uint32_t reg;
 1205 
 1206         AW_GPIO_LOCK_ASSERT(sc);
 1207         irq = ((struct gpio_irqsrc *)isrc)->irq;
 1208         reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
 1209         reg &= ~(1 << sc->gpio_pic_irqsrc[irq].intnum);
 1210         AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
 1211 
 1212         sc->gpio_pic_irqsrc[irq].enabled = false;
 1213 }
 1214 
 1215 static void
 1216 aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
 1217 {
 1218         struct aw_gpio_softc *sc;
 1219 
 1220         sc = device_get_softc(dev);
 1221 
 1222         AW_GPIO_LOCK(sc);
 1223         aw_gpio_pic_disable_intr_locked(sc, isrc);
 1224         AW_GPIO_UNLOCK(sc);
 1225 }
 1226 
 1227 static void
 1228 aw_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
 1229 {
 1230         struct aw_gpio_softc *sc;
 1231         u_int irq;
 1232         uint32_t reg;
 1233 
 1234         sc = device_get_softc(dev);
 1235         irq = ((struct gpio_irqsrc *)isrc)->irq;
 1236         AW_GPIO_LOCK(sc);
 1237         reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
 1238         reg |= 1 << sc->gpio_pic_irqsrc[irq].intnum;
 1239         AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
 1240         AW_GPIO_UNLOCK(sc);
 1241 
 1242         sc->gpio_pic_irqsrc[irq].enabled = true;
 1243 }
 1244 
 1245 static int
 1246 aw_gpio_pic_map_gpio(struct aw_gpio_softc *sc, struct intr_map_data_gpio *dag,
 1247     u_int *irqp, u_int *mode)
 1248 {
 1249         u_int irq;
 1250         int pin;
 1251 
 1252         irq = dag->gpio_pin_num;
 1253 
 1254         for (pin = 0; pin < sc->nirqs; pin++)
 1255                 if (sc->gpio_pic_irqsrc[pin].pin == irq)
 1256                         break;
 1257         if (pin == sc->nirqs) {
 1258                 device_printf(sc->sc_dev, "Invalid interrupt number %u\n", irq);
 1259                 return (EINVAL);
 1260         }
 1261 
 1262         switch (dag->gpio_intr_mode) {
 1263         case GPIO_INTR_LEVEL_LOW:
 1264         case GPIO_INTR_LEVEL_HIGH:
 1265         case GPIO_INTR_EDGE_RISING:
 1266         case GPIO_INTR_EDGE_FALLING:
 1267         case GPIO_INTR_EDGE_BOTH:
 1268                 break;
 1269         default:
 1270                 device_printf(sc->sc_dev, "Unsupported interrupt mode 0x%8x\n",
 1271                     dag->gpio_intr_mode);
 1272                 return (EINVAL);
 1273         }
 1274 
 1275         *irqp = pin;
 1276         if (mode != NULL)
 1277                 *mode = dag->gpio_intr_mode;
 1278 
 1279         return (0);
 1280 }
 1281 
 1282 static int
 1283 aw_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
 1284     struct intr_irqsrc **isrcp)
 1285 {
 1286         struct aw_gpio_softc *sc;
 1287         u_int irq;
 1288         int err;
 1289 
 1290         sc = device_get_softc(dev);
 1291         switch (data->type) {
 1292         case INTR_MAP_DATA_GPIO:
 1293                 err = aw_gpio_pic_map_gpio(sc,
 1294                     (struct intr_map_data_gpio *)data,
 1295                   &irq, NULL);
 1296                 break;
 1297         default:
 1298                 return (ENOTSUP);
 1299         };
 1300 
 1301         if (err == 0)
 1302                 *isrcp = &sc->gpio_pic_irqsrc[irq].isrc;
 1303         return (0);
 1304 }
 1305 
 1306 static int
 1307 aw_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
 1308     struct resource *res, struct intr_map_data *data)
 1309 {
 1310         struct aw_gpio_softc *sc;
 1311         uint32_t irqcfg;
 1312         uint32_t pinidx, reg;
 1313         u_int irq, mode;
 1314         int err;
 1315 
 1316         sc = device_get_softc(dev);
 1317 
 1318         err = 0;
 1319         switch (data->type) {
 1320         case INTR_MAP_DATA_GPIO:
 1321                 err = aw_gpio_pic_map_gpio(sc,
 1322                     (struct intr_map_data_gpio *)data,
 1323                   &irq, &mode);
 1324                 if (err != 0)
 1325                         return (err);
 1326                 break;
 1327         default:
 1328                 return (ENOTSUP);
 1329         };
 1330 
 1331         pinidx = (sc->gpio_pic_irqsrc[irq].intnum % 8) * 4;
 1332 
 1333         AW_GPIO_LOCK(sc);
 1334         switch (mode) {
 1335         case GPIO_INTR_LEVEL_LOW:
 1336                 irqcfg = AW_GPIO_INT_LEVEL_LOW << pinidx;
 1337                 break;
 1338         case GPIO_INTR_LEVEL_HIGH:
 1339                 irqcfg = AW_GPIO_INT_LEVEL_HIGH << pinidx;
 1340                 break;
 1341         case GPIO_INTR_EDGE_RISING:
 1342                 irqcfg = AW_GPIO_INT_EDGE_POSITIVE << pinidx;
 1343                 break;
 1344         case GPIO_INTR_EDGE_FALLING:
 1345                 irqcfg = AW_GPIO_INT_EDGE_NEGATIVE << pinidx;
 1346                 break;
 1347         case GPIO_INTR_EDGE_BOTH:
 1348                 irqcfg = AW_GPIO_INT_EDGE_BOTH << pinidx;
 1349                 break;
 1350         }
 1351 
 1352         /* Switch the pin to interrupt mode */
 1353         sc->gpio_pic_irqsrc[irq].oldfunc = aw_gpio_get_function(sc,
 1354             sc->gpio_pic_irqsrc[irq].pin);
 1355         aw_gpio_set_function(sc, sc->gpio_pic_irqsrc[irq].pin,
 1356             sc->gpio_pic_irqsrc[irq].intfunc);
 1357 
 1358         /* Write interrupt mode */
 1359         reg = AW_GPIO_READ(sc, 
 1360             AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
 1361             sc->gpio_pic_irqsrc[irq].intnum));
 1362         reg &= ~(0xF << pinidx);
 1363         reg |= irqcfg;
 1364         AW_GPIO_WRITE(sc,
 1365             AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
 1366             sc->gpio_pic_irqsrc[irq].intnum),
 1367             reg);
 1368 
 1369         AW_GPIO_UNLOCK(sc);
 1370 
 1371         return (0);
 1372 }
 1373 
 1374 static int
 1375 aw_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
 1376     struct resource *res, struct intr_map_data *data)
 1377 {
 1378         struct aw_gpio_softc *sc;
 1379         struct gpio_irqsrc *gi;
 1380 
 1381         sc = device_get_softc(dev);
 1382         gi = (struct gpio_irqsrc *)isrc;
 1383 
 1384         /* Switch back the pin to it's original function */
 1385         AW_GPIO_LOCK(sc);
 1386         aw_gpio_set_function(sc, gi->pin, gi->oldfunc);
 1387         AW_GPIO_UNLOCK(sc);
 1388 
 1389         return (0);
 1390 }
 1391 
 1392 static void
 1393 aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
 1394 {
 1395         struct aw_gpio_softc *sc;
 1396         struct gpio_irqsrc *gi;
 1397 
 1398         sc = device_get_softc(dev);
 1399         gi = (struct gpio_irqsrc *)isrc;
 1400 
 1401         arm_irq_memory_barrier(0);
 1402         AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
 1403 }
 1404 
 1405 static void
 1406 aw_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
 1407 {
 1408         struct aw_gpio_softc *sc;
 1409         struct gpio_irqsrc *gi;
 1410 
 1411         sc = device_get_softc(dev);
 1412         gi = (struct gpio_irqsrc *)isrc;
 1413 
 1414         arm_irq_memory_barrier(0);
 1415         AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
 1416         aw_gpio_pic_enable_intr(dev, isrc);
 1417 }
 1418 
 1419 static void
 1420 aw_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
 1421 {
 1422         struct aw_gpio_softc *sc;
 1423 
 1424         sc = device_get_softc(dev);
 1425         aw_gpio_pic_disable_intr_locked(sc, isrc);
 1426 }
 1427 
 1428 /*
 1429  * OFWBUS Interface
 1430  */
 1431 static phandle_t
 1432 aw_gpio_get_node(device_t dev, device_t bus)
 1433 {
 1434 
 1435         /* We only have one child, the GPIO bus, which needs our own node. */
 1436         return (ofw_bus_get_node(dev));
 1437 }
 1438 
 1439 static device_method_t aw_gpio_methods[] = {
 1440         /* Device interface */
 1441         DEVMETHOD(device_probe,         aw_gpio_probe),
 1442         DEVMETHOD(device_attach,        aw_gpio_attach),
 1443         DEVMETHOD(device_detach,        aw_gpio_detach),
 1444 
 1445         /* Interrupt controller interface */
 1446         DEVMETHOD(pic_disable_intr,     aw_gpio_pic_disable_intr),
 1447         DEVMETHOD(pic_enable_intr,      aw_gpio_pic_enable_intr),
 1448         DEVMETHOD(pic_map_intr,         aw_gpio_pic_map_intr),
 1449         DEVMETHOD(pic_setup_intr,       aw_gpio_pic_setup_intr),
 1450         DEVMETHOD(pic_teardown_intr,    aw_gpio_pic_teardown_intr),
 1451         DEVMETHOD(pic_post_filter,      aw_gpio_pic_post_filter),
 1452         DEVMETHOD(pic_post_ithread,     aw_gpio_pic_post_ithread),
 1453         DEVMETHOD(pic_pre_ithread,      aw_gpio_pic_pre_ithread),
 1454 
 1455         /* GPIO protocol */
 1456         DEVMETHOD(gpio_get_bus,         aw_gpio_get_bus),
 1457         DEVMETHOD(gpio_pin_max,         aw_gpio_pin_max),
 1458         DEVMETHOD(gpio_pin_getname,     aw_gpio_pin_getname),
 1459         DEVMETHOD(gpio_pin_getflags,    aw_gpio_pin_getflags),
 1460         DEVMETHOD(gpio_pin_getcaps,     aw_gpio_pin_getcaps),
 1461         DEVMETHOD(gpio_pin_setflags,    aw_gpio_pin_setflags),
 1462         DEVMETHOD(gpio_pin_get,         aw_gpio_pin_get),
 1463         DEVMETHOD(gpio_pin_set,         aw_gpio_pin_set),
 1464         DEVMETHOD(gpio_pin_toggle,      aw_gpio_pin_toggle),
 1465         DEVMETHOD(gpio_pin_access_32,   aw_gpio_pin_access_32),
 1466         DEVMETHOD(gpio_pin_config_32,   aw_gpio_pin_config_32),
 1467         DEVMETHOD(gpio_map_gpios,       aw_gpio_map_gpios),
 1468 
 1469         /* ofw_bus interface */
 1470         DEVMETHOD(ofw_bus_get_node,     aw_gpio_get_node),
 1471 
 1472         /* fdt_pinctrl interface */
 1473         DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins),
 1474 
 1475         DEVMETHOD_END
 1476 };
 1477 
 1478 static devclass_t aw_gpio_devclass;
 1479 
 1480 static driver_t aw_gpio_driver = {
 1481         "gpio",
 1482         aw_gpio_methods,
 1483         sizeof(struct aw_gpio_softc),
 1484 };
 1485 
 1486 EARLY_DRIVER_MODULE(aw_gpio, simplebus, aw_gpio_driver, aw_gpio_devclass, 0, 0,
 1487     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);

Cache object: cd448af7ca9709a66e2c0a7726fcd20a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.