Home | History | Annotate | Line # | Download | only in sunxi
sunxi_gpio.c revision 1.37
      1 /* $NetBSD: sunxi_gpio.c,v 1.37 2021/08/07 16:18:45 thorpej Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2017 Jared McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "opt_soc.h"
     30 
     31 #include <sys/cdefs.h>
     32 __KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.37 2021/08/07 16:18:45 thorpej Exp $");
     33 
     34 #include <sys/param.h>
     35 #include <sys/bus.h>
     36 #include <sys/device.h>
     37 #include <sys/intr.h>
     38 #include <sys/systm.h>
     39 #include <sys/mutex.h>
     40 #include <sys/kmem.h>
     41 #include <sys/gpio.h>
     42 #include <sys/bitops.h>
     43 #include <sys/lwp.h>
     44 
     45 #include <dev/fdt/fdtvar.h>
     46 #include <dev/gpio/gpiovar.h>
     47 
     48 #include <arm/sunxi/sunxi_gpio.h>
     49 
     50 #define	SUNXI_GPIO_MAX_EINT_BANK	5
     51 #define	SUNXI_GPIO_MAX_EINT		32
     52 
     53 #define	SUNXI_GPIO_MAX_BANK		26
     54 
     55 #define	SUNXI_GPIO_PORT(port)		(0x24 * (port))
     56 #define SUNXI_GPIO_CFG(port, pin)	(SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8)))
     57 #define  SUNXI_GPIO_CFG_PINMASK(pin)	(0x7U << (((pin) % 8) * 4))
     58 #define	SUNXI_GPIO_DATA(port)		(SUNXI_GPIO_PORT(port) + 0x10)
     59 #define	SUNXI_GPIO_DRV(port, pin)	(SUNXI_GPIO_PORT(port) + 0x14 + (0x4 * ((pin) / 16)))
     60 #define  SUNXI_GPIO_DRV_PINMASK(pin)	(0x3U << (((pin) % 16) * 2))
     61 #define	SUNXI_GPIO_PULL(port, pin)	(SUNXI_GPIO_PORT(port) + 0x1c + (0x4 * ((pin) / 16)))
     62 #define	 SUNXI_GPIO_PULL_DISABLE	0
     63 #define	 SUNXI_GPIO_PULL_UP		1
     64 #define	 SUNXI_GPIO_PULL_DOWN		2
     65 #define  SUNXI_GPIO_PULL_PINMASK(pin)	(0x3U << (((pin) % 16) * 2))
     66 #define	SUNXI_GPIO_INT_CFG(bank, eint)	(0x200 + (0x20 * (bank)) + (0x4 * ((eint) / 8)))
     67 #define	 SUNXI_GPIO_INT_MODEMASK(eint)	(0xfU << (((eint) % 8) * 4))
     68 #define	  SUNXI_GPIO_INT_MODE_POS_EDGE		0x0
     69 #define	  SUNXI_GPIO_INT_MODE_NEG_EDGE		0x1
     70 #define	  SUNXI_GPIO_INT_MODE_HIGH_LEVEL	0x2
     71 #define	  SUNXI_GPIO_INT_MODE_LOW_LEVEL		0x3
     72 #define	  SUNXI_GPIO_INT_MODE_DOUBLE_EDGE	0x4
     73 #define	SUNXI_GPIO_INT_CTL(bank)	(0x210 + 0x20 * (bank))
     74 #define	SUNXI_GPIO_INT_STATUS(bank)	(0x214 + 0x20 * (bank))
     75 #define	SUNXI_GPIO_INT_DEBOUNCE(bank)	(0x218 + 0x20 * (bank))
     76 #define	  SUNXI_GPIO_INT_DEBOUNCE_CLK_PRESCALE	__BITS(6,4)
     77 #define	  SUNXI_GPIO_INT_DEBOUNCE_CLK_SEL	__BIT(0)
     78 #define	SUNXI_GPIO_GRP_CONFIG(bank)	(0x300 + 0x4 * (bank))
     79 #define	 SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK	0xf
     80 
     81 static const struct device_compatible_entry compat_data[] = {
     82 #ifdef SOC_SUN4I_A10
     83 	{ .compat = "allwinner,sun4i-a10-pinctrl",
     84 	  .data = &sun4i_a10_padconf },
     85 #endif
     86 #ifdef SOC_SUN5I_A13
     87 	{ .compat = "allwinner,sun5i-a13-pinctrl",
     88 	  .data = &sun5i_a13_padconf },
     89 	{ .compat = "nextthing,gr8-pinctrl",
     90 	  .data = &sun5i_a13_padconf },
     91 #endif
     92 #ifdef SOC_SUN6I_A31
     93 	{ .compat = "allwinner,sun6i-a31-pinctrl",
     94 	  .data = &sun6i_a31_padconf },
     95 	{ .compat = "allwinner,sun6i-a31-r-pinctrl",
     96 	  .data = &sun6i_a31_r_padconf },
     97 #endif
     98 #ifdef SOC_SUN7I_A20
     99 	{ .compat = "allwinner,sun7i-a20-pinctrl",
    100 	  .data = &sun7i_a20_padconf },
    101 #endif
    102 #ifdef SOC_SUN8I_A83T
    103 	{ .compat = "allwinner,sun8i-a83t-pinctrl",
    104 	  .data = &sun8i_a83t_padconf },
    105 	{ .compat = "allwinner,sun8i-a83t-r-pinctrl",
    106 	  .data = &sun8i_a83t_r_padconf },
    107 #endif
    108 #ifdef SOC_SUN8I_H3
    109 	{ .compat = "allwinner,sun8i-h3-pinctrl",
    110 	  .data = &sun8i_h3_padconf },
    111 	{ .compat = "allwinner,sun8i-h3-r-pinctrl",
    112 	  .data = &sun8i_h3_r_padconf },
    113 #endif
    114 #ifdef SOC_SUN9I_A80
    115 	{ .compat = "allwinner,sun9i-a80-pinctrl",
    116 	  .data = &sun9i_a80_padconf },
    117 	{ .compat = "allwinner,sun9i-a80-r-pinctrl",
    118 	  .data = &sun9i_a80_r_padconf },
    119 #endif
    120 #ifdef SOC_SUN50I_A64
    121 	{ .compat = "allwinner,sun50i-a64-pinctrl",
    122 	  .data = &sun50i_a64_padconf },
    123 	{ .compat = "allwinner,sun50i-a64-r-pinctrl",
    124 	  .data = &sun50i_a64_r_padconf },
    125 #endif
    126 #ifdef SOC_SUN50I_H5
    127 	{ .compat = "allwinner,sun50i-h5-pinctrl",
    128 	  .data = &sun8i_h3_padconf },
    129 	{ .compat = "allwinner,sun50i-h5-r-pinctrl",
    130 	  .data = &sun8i_h3_r_padconf },
    131 #endif
    132 #ifdef SOC_SUN50I_H6
    133 	{ .compat = "allwinner,sun50i-h6-pinctrl",
    134 	  .data = &sun50i_h6_padconf },
    135 	{ .compat = "allwinner,sun50i-h6-r-pinctrl",
    136 	  .data = &sun50i_h6_r_padconf },
    137 #endif
    138 	DEVICE_COMPAT_EOL
    139 };
    140 
    141 struct sunxi_gpio_eint {
    142 	int (*eint_func)(void *);
    143 	void *eint_arg;
    144 	bool eint_mpsafe;
    145 	int eint_bank;
    146 	int eint_num;
    147 };
    148 
    149 struct sunxi_gpio_softc {
    150 	device_t sc_dev;
    151 	bus_space_tag_t sc_bst;
    152 	bus_space_handle_t sc_bsh;
    153 	int sc_phandle;
    154 	const struct sunxi_gpio_padconf *sc_padconf;
    155 	kmutex_t sc_lock;
    156 
    157 	struct gpio_chipset_tag sc_gp;
    158 	gpio_pin_t *sc_pins;
    159 	device_t sc_gpiodev;
    160 
    161 	struct fdtbus_regulator *sc_pin_supply[SUNXI_GPIO_MAX_BANK];
    162 
    163 	u_int sc_eint_bank_max;
    164 
    165 	void *sc_ih;
    166 	struct sunxi_gpio_eint sc_eint[SUNXI_GPIO_MAX_EINT_BANK][SUNXI_GPIO_MAX_EINT];
    167 };
    168 
    169 struct sunxi_gpio_pin {
    170 	struct sunxi_gpio_softc *pin_sc;
    171 	const struct sunxi_gpio_pins *pin_def;
    172 	int pin_flags;
    173 	bool pin_actlo;
    174 };
    175 
    176 #define GPIO_READ(sc, reg) 		\
    177     bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
    178 #define GPIO_WRITE(sc, reg, val) 	\
    179     bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
    180 
    181 static int	sunxi_gpio_match(device_t, cfdata_t, void *);
    182 static void	sunxi_gpio_attach(device_t, device_t, void *);
    183 
    184 CFATTACH_DECL_NEW(sunxi_gpio, sizeof(struct sunxi_gpio_softc),
    185 	sunxi_gpio_match, sunxi_gpio_attach, NULL, NULL);
    186 
    187 static const struct sunxi_gpio_pins *
    188 sunxi_gpio_lookup(struct sunxi_gpio_softc *sc, uint8_t port, uint8_t pin)
    189 {
    190 	const struct sunxi_gpio_pins *pin_def;
    191 	u_int n;
    192 
    193 	for (n = 0; n < sc->sc_padconf->npins; n++) {
    194 		pin_def = &sc->sc_padconf->pins[n];
    195 		if (pin_def->port == port && pin_def->pin == pin)
    196 			return pin_def;
    197 	}
    198 
    199 	return NULL;
    200 }
    201 
    202 static const struct sunxi_gpio_pins *
    203 sunxi_gpio_lookup_byname(struct sunxi_gpio_softc *sc, const char *name)
    204 {
    205 	const struct sunxi_gpio_pins *pin_def;
    206 	u_int n;
    207 
    208 	for (n = 0; n < sc->sc_padconf->npins; n++) {
    209 		pin_def = &sc->sc_padconf->pins[n];
    210 		if (strcmp(pin_def->name, name) == 0)
    211 			return pin_def;
    212 	}
    213 
    214 	return NULL;
    215 }
    216 
    217 static int
    218 sunxi_gpio_setfunc(struct sunxi_gpio_softc *sc,
    219     const struct sunxi_gpio_pins *pin_def, const char *func)
    220 {
    221 	uint32_t cfg;
    222 	u_int n;
    223 
    224 	KASSERT(mutex_owned(&sc->sc_lock));
    225 
    226 	const bus_size_t cfg_reg = SUNXI_GPIO_CFG(pin_def->port, pin_def->pin);
    227 	const uint32_t cfg_mask = SUNXI_GPIO_CFG_PINMASK(pin_def->pin);
    228 
    229 	for (n = 0; n < SUNXI_GPIO_MAXFUNC; n++) {
    230 		if (pin_def->functions[n] == NULL)
    231 			continue;
    232 		if (strcmp(pin_def->functions[n], func) == 0) {
    233 			cfg = GPIO_READ(sc, cfg_reg);
    234 			cfg &= ~cfg_mask;
    235 			cfg |= __SHIFTIN(n, cfg_mask);
    236 #ifdef SUNXI_GPIO_DEBUG
    237 			device_printf(sc->sc_dev, "P%c%02d cfg %08x -> %08x\n",
    238 			    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, cfg_reg), cfg);
    239 #endif
    240 			GPIO_WRITE(sc, cfg_reg, cfg);
    241 			return 0;
    242 		}
    243 	}
    244 
    245 	/* Function not found */
    246 	device_printf(sc->sc_dev, "function '%s' not supported on P%c%02d\n",
    247 	    func, pin_def->port + 'A', pin_def->pin);
    248 
    249 	return ENXIO;
    250 }
    251 
    252 static int
    253 sunxi_gpio_setpull(struct sunxi_gpio_softc *sc,
    254     const struct sunxi_gpio_pins *pin_def, int flags)
    255 {
    256 	uint32_t pull;
    257 
    258 	KASSERT(mutex_owned(&sc->sc_lock));
    259 
    260 	const bus_size_t pull_reg = SUNXI_GPIO_PULL(pin_def->port, pin_def->pin);
    261 	const uint32_t pull_mask = SUNXI_GPIO_PULL_PINMASK(pin_def->pin);
    262 
    263 	pull = GPIO_READ(sc, pull_reg);
    264 	pull &= ~pull_mask;
    265 	if (flags & GPIO_PIN_PULLUP)
    266 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_UP, pull_mask);
    267 	else if (flags & GPIO_PIN_PULLDOWN)
    268 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_DOWN, pull_mask);
    269 	else
    270 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_DISABLE, pull_mask);
    271 #ifdef SUNXI_GPIO_DEBUG
    272 	device_printf(sc->sc_dev, "P%c%02d pull %08x -> %08x\n",
    273 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, pull_reg), pull);
    274 #endif
    275 	GPIO_WRITE(sc, pull_reg, pull);
    276 
    277 	return 0;
    278 }
    279 
    280 static int
    281 sunxi_gpio_setdrv(struct sunxi_gpio_softc *sc,
    282     const struct sunxi_gpio_pins *pin_def, int drive_strength)
    283 {
    284 	uint32_t drv;
    285 
    286 	KASSERT(mutex_owned(&sc->sc_lock));
    287 
    288 	if (drive_strength < 10 || drive_strength > 40)
    289 		return EINVAL;
    290 
    291 	const bus_size_t drv_reg = SUNXI_GPIO_DRV(pin_def->port, pin_def->pin);
    292 	const uint32_t drv_mask = SUNXI_GPIO_DRV_PINMASK(pin_def->pin);
    293 
    294 	drv = GPIO_READ(sc, drv_reg);
    295 	drv &= ~drv_mask;
    296 	drv |= __SHIFTIN((drive_strength / 10) - 1, drv_mask);
    297 #ifdef SUNXI_GPIO_DEBUG
    298 	device_printf(sc->sc_dev, "P%c%02d drv %08x -> %08x\n",
    299 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, drv_reg), drv);
    300 #endif
    301 	GPIO_WRITE(sc, drv_reg, drv);
    302 
    303 	return 0;
    304 }
    305 
    306 static int
    307 sunxi_gpio_ctl(struct sunxi_gpio_softc *sc, const struct sunxi_gpio_pins *pin_def,
    308     int flags)
    309 {
    310 	KASSERT(mutex_owned(&sc->sc_lock));
    311 
    312 	if (flags & GPIO_PIN_INPUT)
    313 		return sunxi_gpio_setfunc(sc, pin_def, "gpio_in");
    314 	if (flags & GPIO_PIN_OUTPUT)
    315 		return sunxi_gpio_setfunc(sc, pin_def, "gpio_out");
    316 
    317 	return EINVAL;
    318 }
    319 
    320 static void *
    321 sunxi_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
    322 {
    323 	struct sunxi_gpio_softc * const sc = device_private(dev);
    324 	const struct sunxi_gpio_pins *pin_def;
    325 	struct sunxi_gpio_pin *gpin;
    326 	const u_int *gpio = data;
    327 	int error;
    328 
    329 	if (len != 16)
    330 		return NULL;
    331 
    332 	const uint8_t port = be32toh(gpio[1]) & 0xff;
    333 	const uint8_t pin = be32toh(gpio[2]) & 0xff;
    334 	const bool actlo = be32toh(gpio[3]) & 1;
    335 
    336 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    337 	if (pin_def == NULL)
    338 		return NULL;
    339 
    340 	mutex_enter(&sc->sc_lock);
    341 	error = sunxi_gpio_ctl(sc, pin_def, flags);
    342 	mutex_exit(&sc->sc_lock);
    343 
    344 	if (error != 0)
    345 		return NULL;
    346 
    347 	gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
    348 	gpin->pin_sc = sc;
    349 	gpin->pin_def = pin_def;
    350 	gpin->pin_flags = flags;
    351 	gpin->pin_actlo = actlo;
    352 
    353 	return gpin;
    354 }
    355 
    356 static void
    357 sunxi_gpio_release(device_t dev, void *priv)
    358 {
    359 	struct sunxi_gpio_softc * const sc = device_private(dev);
    360 	struct sunxi_gpio_pin *pin = priv;
    361 
    362 	mutex_enter(&sc->sc_lock);
    363 	sunxi_gpio_ctl(pin->pin_sc, pin->pin_def, GPIO_PIN_INPUT);
    364 	mutex_exit(&sc->sc_lock);
    365 
    366 	kmem_free(pin, sizeof(*pin));
    367 }
    368 
    369 static int
    370 sunxi_gpio_read(device_t dev, void *priv, bool raw)
    371 {
    372 	struct sunxi_gpio_softc * const sc = device_private(dev);
    373 	struct sunxi_gpio_pin *pin = priv;
    374 	const struct sunxi_gpio_pins *pin_def = pin->pin_def;
    375 	uint32_t data;
    376 	int val;
    377 
    378 	KASSERT(sc == pin->pin_sc);
    379 
    380 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    381 	const uint32_t data_mask = __BIT(pin_def->pin);
    382 
    383 	/* No lock required for reads */
    384 	data = GPIO_READ(sc, data_reg);
    385 	val = __SHIFTOUT(data, data_mask);
    386 	if (!raw && pin->pin_actlo)
    387 		val = !val;
    388 
    389 #ifdef SUNXI_GPIO_DEBUG
    390 	device_printf(dev, "P%c%02d rd %08x (%d %d)\n",
    391 	    pin_def->port + 'A', pin_def->pin, data,
    392 	    __SHIFTOUT(val, data_mask), val);
    393 #endif
    394 
    395 	return val;
    396 }
    397 
    398 static void
    399 sunxi_gpio_write(device_t dev, void *priv, int val, bool raw)
    400 {
    401 	struct sunxi_gpio_softc * const sc = device_private(dev);
    402 	struct sunxi_gpio_pin *pin = priv;
    403 	const struct sunxi_gpio_pins *pin_def = pin->pin_def;
    404 	uint32_t data;
    405 
    406 	KASSERT(sc == pin->pin_sc);
    407 
    408 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    409 	const uint32_t data_mask = __BIT(pin_def->pin);
    410 
    411 	if (!raw && pin->pin_actlo)
    412 		val = !val;
    413 
    414 	mutex_enter(&sc->sc_lock);
    415 	data = GPIO_READ(sc, data_reg);
    416 	data &= ~data_mask;
    417 	data |= __SHIFTIN(val, data_mask);
    418 #ifdef SUNXI_GPIO_DEBUG
    419 	device_printf(dev, "P%c%02d wr %08x -> %08x\n",
    420 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, data_reg), data);
    421 #endif
    422 	GPIO_WRITE(sc, data_reg, data);
    423 	mutex_exit(&sc->sc_lock);
    424 }
    425 
    426 static struct fdtbus_gpio_controller_func sunxi_gpio_funcs = {
    427 	.acquire = sunxi_gpio_acquire,
    428 	.release = sunxi_gpio_release,
    429 	.read = sunxi_gpio_read,
    430 	.write = sunxi_gpio_write,
    431 };
    432 
    433 static int
    434 sunxi_gpio_intr(void *priv)
    435 {
    436 	struct sunxi_gpio_softc * const sc = priv;
    437 	struct sunxi_gpio_eint *eint;
    438 	uint32_t status, bit;
    439 	u_int bank;
    440 	int ret = 0;
    441 
    442 	for (bank = 0; bank <= sc->sc_eint_bank_max; bank++) {
    443 		status = GPIO_READ(sc, SUNXI_GPIO_INT_STATUS(bank));
    444 		if (status == 0)
    445 			continue;
    446 		GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(bank), status);
    447 
    448 		while ((bit = ffs32(status)) != 0) {
    449 			status &= ~__BIT(bit - 1);
    450 			eint = &sc->sc_eint[bank][bit - 1];
    451 			if (eint->eint_func == NULL)
    452 				continue;
    453 			if (!eint->eint_mpsafe)
    454 				KERNEL_LOCK(1, curlwp);
    455 			ret |= eint->eint_func(eint->eint_arg);
    456 			if (!eint->eint_mpsafe)
    457 				KERNEL_UNLOCK_ONE(curlwp);
    458 		}
    459 	}
    460 
    461 	return ret;
    462 }
    463 
    464 static void *
    465 sunxi_intr_enable(struct sunxi_gpio_softc *sc,
    466     const struct sunxi_gpio_pins *pin_def, u_int mode, bool mpsafe,
    467     int (*func)(void *), void *arg)
    468 {
    469 	uint32_t val;
    470 	struct sunxi_gpio_eint *eint;
    471 
    472 	if (pin_def->functions[pin_def->eint_func] == NULL ||
    473 	    strcmp(pin_def->functions[pin_def->eint_func], "irq") != 0)
    474 		return NULL;
    475 
    476 	KASSERT(pin_def->eint_num < SUNXI_GPIO_MAX_EINT);
    477 
    478 	mutex_enter(&sc->sc_lock);
    479 
    480 	eint = &sc->sc_eint[pin_def->eint_bank][pin_def->eint_num];
    481 	if (eint->eint_func != NULL) {
    482 		mutex_exit(&sc->sc_lock);
    483 		return NULL;	/* in use */
    484 	}
    485 
    486 	/* Set function */
    487 	if (sunxi_gpio_setfunc(sc, pin_def, "irq") != 0) {
    488 		mutex_exit(&sc->sc_lock);
    489 		return NULL;
    490 	}
    491 
    492 	eint->eint_func = func;
    493 	eint->eint_arg = arg;
    494 	eint->eint_mpsafe = mpsafe;
    495 	eint->eint_bank = pin_def->eint_bank;
    496 	eint->eint_num = pin_def->eint_num;
    497 
    498 	/* Configure eint mode */
    499 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num));
    500 	val &= ~SUNXI_GPIO_INT_MODEMASK(eint->eint_num);
    501 	val |= __SHIFTIN(mode, SUNXI_GPIO_INT_MODEMASK(eint->eint_num));
    502 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num), val);
    503 
    504 	val = SUNXI_GPIO_INT_DEBOUNCE_CLK_SEL;
    505 	GPIO_WRITE(sc, SUNXI_GPIO_INT_DEBOUNCE(eint->eint_bank), val);
    506 
    507 	/* Enable eint */
    508 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank));
    509 	val |= __BIT(eint->eint_num);
    510 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val);
    511 
    512 	mutex_exit(&sc->sc_lock);
    513 
    514 	return eint;
    515 }
    516 
    517 static void
    518 sunxi_intr_disable(struct sunxi_gpio_softc *sc, struct sunxi_gpio_eint *eint)
    519 {
    520 	uint32_t val;
    521 
    522 	KASSERT(eint->eint_func != NULL);
    523 
    524 	mutex_enter(&sc->sc_lock);
    525 
    526 	/* Disable eint */
    527 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank));
    528 	val &= ~__BIT(eint->eint_num);
    529 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val);
    530 	GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(eint->eint_bank), __BIT(eint->eint_num));
    531 
    532 	eint->eint_func = NULL;
    533 	eint->eint_arg = NULL;
    534 	eint->eint_mpsafe = false;
    535 
    536 	mutex_exit(&sc->sc_lock);
    537 }
    538 
    539 static void *
    540 sunxi_fdt_intr_establish(device_t dev, u_int *specifier, int ipl, int flags,
    541     int (*func)(void *), void *arg, const char *xname)
    542 {
    543 	struct sunxi_gpio_softc * const sc = device_private(dev);
    544 	bool mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
    545 	const struct sunxi_gpio_pins *pin_def;
    546 	u_int mode;
    547 
    548 	if (ipl != IPL_VM) {
    549 		aprint_error_dev(dev, "%s: wrong IPL %d (expected %d)\n",
    550 		    __func__, ipl, IPL_VM);
    551 		return NULL;
    552 	}
    553 
    554 	/* 1st cell is the bank */
    555 	/* 2nd cell is the pin */
    556 	/* 3rd cell is flags */
    557 	const u_int port = be32toh(specifier[0]);
    558 	const u_int pin = be32toh(specifier[1]);
    559 	const u_int type = be32toh(specifier[2]) & 0xf;
    560 
    561 	switch (type) {
    562 	case FDT_INTR_TYPE_POS_EDGE:
    563 		mode = SUNXI_GPIO_INT_MODE_POS_EDGE;
    564 		break;
    565 	case FDT_INTR_TYPE_NEG_EDGE:
    566 		mode = SUNXI_GPIO_INT_MODE_NEG_EDGE;
    567 		break;
    568 	case FDT_INTR_TYPE_DOUBLE_EDGE:
    569 		mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE;
    570 		break;
    571 	case FDT_INTR_TYPE_HIGH_LEVEL:
    572 		mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL;
    573 		break;
    574 	case FDT_INTR_TYPE_LOW_LEVEL:
    575 		mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL;
    576 		break;
    577 	default:
    578 		aprint_error_dev(dev, "%s: unsupported irq type 0x%x\n",
    579 		    __func__, type);
    580 		return NULL;
    581 	}
    582 
    583 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    584 	if (pin_def == NULL)
    585 		return NULL;
    586 
    587 	return sunxi_intr_enable(sc, pin_def, mode, mpsafe, func, arg);
    588 }
    589 
    590 static void
    591 sunxi_fdt_intr_disestablish(device_t dev, void *ih)
    592 {
    593 	struct sunxi_gpio_softc * const sc = device_private(dev);
    594 	struct sunxi_gpio_eint * const eint = ih;
    595 
    596 	sunxi_intr_disable(sc, eint);
    597 }
    598 
    599 static bool
    600 sunxi_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
    601 {
    602 	struct sunxi_gpio_softc * const sc = device_private(dev);
    603 	const struct sunxi_gpio_pins *pin_def;
    604 
    605 	/* 1st cell is the bank */
    606 	/* 2nd cell is the pin */
    607 	/* 3rd cell is flags */
    608 	if (!specifier)
    609 		return false;
    610 	const u_int port = be32toh(specifier[0]);
    611 	const u_int pin = be32toh(specifier[1]);
    612 
    613 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    614 	if (pin_def == NULL)
    615 		return false;
    616 
    617 	snprintf(buf, buflen, "GPIO %s", pin_def->name);
    618 
    619 	return true;
    620 }
    621 
    622 static struct fdtbus_interrupt_controller_func sunxi_gpio_intrfuncs = {
    623 	.establish = sunxi_fdt_intr_establish,
    624 	.disestablish = sunxi_fdt_intr_disestablish,
    625 	.intrstr = sunxi_fdt_intrstr,
    626 };
    627 
    628 static void *
    629 sunxi_gpio_intr_establish(void *vsc, int pin, int ipl, int irqmode,
    630     int (*func)(void *), void *arg)
    631 {
    632 	struct sunxi_gpio_softc * const sc = vsc;
    633 	bool mpsafe = (irqmode & GPIO_INTR_MPSAFE) != 0;
    634 	int type = irqmode & GPIO_INTR_MODE_MASK;
    635 	const struct sunxi_gpio_pins *pin_def;
    636 	u_int mode;
    637 
    638 	switch (type) {
    639 	case GPIO_INTR_POS_EDGE:
    640 		mode = SUNXI_GPIO_INT_MODE_POS_EDGE;
    641 		break;
    642 	case GPIO_INTR_NEG_EDGE:
    643 		mode = SUNXI_GPIO_INT_MODE_NEG_EDGE;
    644 		break;
    645 	case GPIO_INTR_DOUBLE_EDGE:
    646 		mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE;
    647 		break;
    648 	case GPIO_INTR_HIGH_LEVEL:
    649 		mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL;
    650 		break;
    651 	case GPIO_INTR_LOW_LEVEL:
    652 		mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL;
    653 		break;
    654 	default:
    655 		aprint_error_dev(sc->sc_dev, "%s: unsupported irq type 0x%x\n",
    656 				 __func__, type);
    657 		return NULL;
    658 	}
    659 
    660 	if (pin < 0 || pin >= sc->sc_padconf->npins)
    661 		return NULL;
    662 	pin_def = &sc->sc_padconf->pins[pin];
    663 
    664 	return sunxi_intr_enable(sc, pin_def, mode, mpsafe, func, arg);
    665 }
    666 
    667 static void
    668 sunxi_gpio_intr_disestablish(void *vsc, void *ih)
    669 {
    670 	struct sunxi_gpio_softc * const sc = vsc;
    671 	struct sunxi_gpio_eint * const eint = ih;
    672 
    673 	sunxi_intr_disable(sc, eint);
    674 }
    675 
    676 static bool
    677 sunxi_gpio_intrstr(void *vsc, int pin, int irqmode, char *buf, size_t buflen)
    678 {
    679 	struct sunxi_gpio_softc * const sc = vsc;
    680 	const struct sunxi_gpio_pins *pin_def;
    681 
    682 	if (pin < 0 || pin >= sc->sc_padconf->npins)
    683 		return NULL;
    684 	pin_def = &sc->sc_padconf->pins[pin];
    685 
    686 	snprintf(buf, buflen, "GPIO %s", pin_def->name);
    687 
    688 	return true;
    689 }
    690 
    691 static const char *
    692 sunxi_pinctrl_parse_function(int phandle)
    693 {
    694 	const char *function;
    695 
    696 	function = fdtbus_pinctrl_parse_function(phandle);
    697 	if (function != NULL)
    698 		return function;
    699 
    700 	return fdtbus_get_string(phandle, "allwinner,function");
    701 }
    702 
    703 static const char *
    704 sunxi_pinctrl_parse_pins(int phandle, int *pins_len)
    705 {
    706 	const char *pins;
    707 	int len;
    708 
    709 	pins = fdtbus_pinctrl_parse_pins(phandle, pins_len);
    710 	if (pins != NULL)
    711 		return pins;
    712 
    713 	len = OF_getproplen(phandle, "allwinner,pins");
    714 	if (len > 0) {
    715 		*pins_len = len;
    716 		return fdtbus_get_prop(phandle, "allwinner,pins", pins_len);
    717 	}
    718 
    719 	return NULL;
    720 }
    721 
    722 static int
    723 sunxi_pinctrl_parse_bias(int phandle)
    724 {
    725 	u_int pull;
    726 	int bias;
    727 
    728 	bias = fdtbus_pinctrl_parse_bias(phandle, NULL);
    729 	if (bias != -1)
    730 		return bias;
    731 
    732 	if (of_getprop_uint32(phandle, "allwinner,pull", &pull) == 0) {
    733 		switch (pull) {
    734 		case 0:
    735 			bias = 0;
    736 			break;
    737 		case 1:
    738 			bias = GPIO_PIN_PULLUP;
    739 			break;
    740 		case 2:
    741 			bias = GPIO_PIN_PULLDOWN;
    742 			break;
    743 		}
    744 	}
    745 
    746 	return bias;
    747 }
    748 
    749 static int
    750 sunxi_pinctrl_parse_drive_strength(int phandle)
    751 {
    752 	int val;
    753 
    754 	val = fdtbus_pinctrl_parse_drive_strength(phandle);
    755 	if (val != -1)
    756 		return val;
    757 
    758 	if (of_getprop_uint32(phandle, "allwinner,drive", &val) == 0)
    759 		return (val + 1) * 10;
    760 
    761 	return -1;
    762 }
    763 
    764 static void
    765 sunxi_pinctrl_enable_regulator(struct sunxi_gpio_softc *sc,
    766     const struct sunxi_gpio_pins *pin_def)
    767 {
    768 	char supply_prop[16];
    769 	uint32_t val;
    770 	u_int uvol;
    771 	int error;
    772 
    773 	const char c = tolower(pin_def->name[1]);
    774 	if (c < 'a' || c > 'z')
    775 		return;
    776 	const int index = c - 'a';
    777 
    778 	if (sc->sc_pin_supply[index] != NULL) {
    779 		/* Already enabled */
    780 		return;
    781 	}
    782 
    783 	snprintf(supply_prop, sizeof(supply_prop), "vcc-p%c-supply", c);
    784 	sc->sc_pin_supply[index] = fdtbus_regulator_acquire(sc->sc_phandle, supply_prop);
    785 	if (sc->sc_pin_supply[index] == NULL)
    786 		return;
    787 
    788 	aprint_debug_dev(sc->sc_dev, "enable \"%s\"\n", supply_prop);
    789 	error = fdtbus_regulator_enable(sc->sc_pin_supply[index]);
    790 	if (error != 0)
    791 		aprint_error_dev(sc->sc_dev, "failed to enable %s: %d\n", supply_prop, error);
    792 
    793 	if (sc->sc_padconf->has_io_bias_config) {
    794 		error = fdtbus_regulator_get_voltage(sc->sc_pin_supply[index], &uvol);
    795 		if (error != 0) {
    796 			aprint_error_dev(sc->sc_dev, "failed to get %s voltage: %d\n",
    797 			    supply_prop, error);
    798 			uvol = 0;
    799 		}
    800 		if (uvol != 0) {
    801 			if (uvol <= 1800000)
    802 				val = 0x0;	/* 1.8V */
    803 			else if (uvol <= 2500000)
    804 				val = 0x6;	/* 2.5V */
    805 			else if (uvol <= 2800000)
    806 				val = 0x9;	/* 2.8V */
    807 			else if (uvol <= 3000000)
    808 				val = 0xa;	/* 3.0V */
    809 			else
    810 				val = 0xd;	/* 3.3V */
    811 
    812 			aprint_debug_dev(sc->sc_dev, "set io bias config for port %d to 0x%x\n",
    813 			    pin_def->port, val);
    814 			val = GPIO_READ(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port));
    815 			val &= ~SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK;
    816 			val |= __SHIFTIN(val, SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK);
    817 			GPIO_WRITE(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port), val);
    818 		}
    819 	}
    820 }
    821 
    822 static int
    823 sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len)
    824 {
    825 	struct sunxi_gpio_softc * const sc = device_private(dev);
    826 	const struct sunxi_gpio_pins *pin_def;
    827 	int pins_len;
    828 
    829 	if (len != 4)
    830 		return -1;
    831 
    832 	const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
    833 
    834 	/*
    835 	 * Required: pins, function
    836 	 * Optional: bias, drive strength
    837 	 */
    838 
    839 	const char *function = sunxi_pinctrl_parse_function(phandle);
    840 	if (function == NULL)
    841 		return -1;
    842 	const char *pins = sunxi_pinctrl_parse_pins(phandle, &pins_len);
    843 	if (pins == NULL)
    844 		return -1;
    845 
    846 	const int bias = sunxi_pinctrl_parse_bias(phandle);
    847 	const int drive_strength = sunxi_pinctrl_parse_drive_strength(phandle);
    848 
    849 	mutex_enter(&sc->sc_lock);
    850 
    851 	for (; pins_len > 0;
    852 	    pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) {
    853 		pin_def = sunxi_gpio_lookup_byname(sc, pins);
    854 		if (pin_def == NULL) {
    855 			aprint_error_dev(dev, "unknown pin name '%s'\n", pins);
    856 			continue;
    857 		}
    858 		if (sunxi_gpio_setfunc(sc, pin_def, function) != 0)
    859 			continue;
    860 
    861 		if (bias != -1)
    862 			sunxi_gpio_setpull(sc, pin_def, bias);
    863 
    864 		if (drive_strength != -1)
    865 			sunxi_gpio_setdrv(sc, pin_def, drive_strength);
    866 
    867 		sunxi_pinctrl_enable_regulator(sc, pin_def);
    868 	}
    869 
    870 	mutex_exit(&sc->sc_lock);
    871 
    872 	return 0;
    873 }
    874 
    875 static struct fdtbus_pinctrl_controller_func sunxi_pinctrl_funcs = {
    876 	.set_config = sunxi_pinctrl_set_config,
    877 };
    878 
    879 static int
    880 sunxi_gpio_pin_read(void *priv, int pin)
    881 {
    882 	struct sunxi_gpio_softc * const sc = priv;
    883 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    884 	uint32_t data;
    885 	int val;
    886 
    887 	KASSERT(pin < sc->sc_padconf->npins);
    888 
    889 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    890 	const uint32_t data_mask = __BIT(pin_def->pin);
    891 
    892 	/* No lock required for reads */
    893 	data = GPIO_READ(sc, data_reg);
    894 	val = __SHIFTOUT(data, data_mask);
    895 
    896 	return val;
    897 }
    898 
    899 static void
    900 sunxi_gpio_pin_write(void *priv, int pin, int val)
    901 {
    902 	struct sunxi_gpio_softc * const sc = priv;
    903 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    904 	uint32_t data;
    905 
    906 	KASSERT(pin < sc->sc_padconf->npins);
    907 
    908 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    909 	const uint32_t data_mask = __BIT(pin_def->pin);
    910 
    911 	mutex_enter(&sc->sc_lock);
    912 	data = GPIO_READ(sc, data_reg);
    913 	if (val)
    914 		data |= data_mask;
    915 	else
    916 		data &= ~data_mask;
    917 	GPIO_WRITE(sc, data_reg, data);
    918 	mutex_exit(&sc->sc_lock);
    919 }
    920 
    921 static void
    922 sunxi_gpio_pin_ctl(void *priv, int pin, int flags)
    923 {
    924 	struct sunxi_gpio_softc * const sc = priv;
    925 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    926 
    927 	KASSERT(pin < sc->sc_padconf->npins);
    928 
    929 	mutex_enter(&sc->sc_lock);
    930 	sunxi_gpio_ctl(sc, pin_def, flags);
    931 	sunxi_gpio_setpull(sc, pin_def, flags);
    932 	mutex_exit(&sc->sc_lock);
    933 }
    934 
    935 static void
    936 sunxi_gpio_attach_ports(struct sunxi_gpio_softc *sc)
    937 {
    938 	const struct sunxi_gpio_pins *pin_def;
    939 	struct gpio_chipset_tag *gp = &sc->sc_gp;
    940 	struct gpiobus_attach_args gba;
    941 	u_int pin;
    942 
    943 	gp->gp_cookie = sc;
    944 	gp->gp_pin_read = sunxi_gpio_pin_read;
    945 	gp->gp_pin_write = sunxi_gpio_pin_write;
    946 	gp->gp_pin_ctl = sunxi_gpio_pin_ctl;
    947 	gp->gp_intr_establish = sunxi_gpio_intr_establish;
    948 	gp->gp_intr_disestablish = sunxi_gpio_intr_disestablish;
    949 	gp->gp_intr_str = sunxi_gpio_intrstr;
    950 
    951 	const u_int npins = sc->sc_padconf->npins;
    952 	sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * npins, KM_SLEEP);
    953 
    954 	for (pin = 0; pin < sc->sc_padconf->npins; pin++) {
    955 		pin_def = &sc->sc_padconf->pins[pin];
    956 		sc->sc_pins[pin].pin_num = pin;
    957 		sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
    958 		    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
    959 		if (pin_def->functions[pin_def->eint_func] != NULL &&
    960 		    strcmp(pin_def->functions[pin_def->eint_func], "irq") == 0) {
    961 			sc->sc_pins[pin].pin_intrcaps =
    962 			    GPIO_INTR_POS_EDGE | GPIO_INTR_NEG_EDGE |
    963 			    GPIO_INTR_HIGH_LEVEL | GPIO_INTR_LOW_LEVEL |
    964 			    GPIO_INTR_DOUBLE_EDGE | GPIO_INTR_MPSAFE;
    965 		}
    966 		sc->sc_pins[pin].pin_state = sunxi_gpio_pin_read(sc, pin);
    967 		strlcpy(sc->sc_pins[pin].pin_defname, pin_def->name,
    968 		    sizeof(sc->sc_pins[pin].pin_defname));
    969 	}
    970 
    971 	memset(&gba, 0, sizeof(gba));
    972 	gba.gba_gc = gp;
    973 	gba.gba_pins = sc->sc_pins;
    974 	gba.gba_npins = npins;
    975 	sc->sc_gpiodev = config_found(sc->sc_dev, &gba, NULL, CFARGS_NONE);
    976 }
    977 
    978 static int
    979 sunxi_gpio_match(device_t parent, cfdata_t cf, void *aux)
    980 {
    981 	struct fdt_attach_args * const faa = aux;
    982 
    983 	return of_compatible_match(faa->faa_phandle, compat_data);
    984 }
    985 
    986 static void
    987 sunxi_gpio_attach(device_t parent, device_t self, void *aux)
    988 {
    989 	struct sunxi_gpio_softc * const sc = device_private(self);
    990 	struct fdt_attach_args * const faa = aux;
    991 	const int phandle = faa->faa_phandle;
    992 	char intrstr[128];
    993 	struct fdtbus_reset *rst;
    994 	struct clk *clk;
    995 	bus_addr_t addr;
    996 	bus_size_t size;
    997 	int child;
    998 
    999 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
   1000 		aprint_error(": couldn't get registers\n");
   1001 		return;
   1002 	}
   1003 
   1004 	if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
   1005 		if (clk_enable(clk) != 0) {
   1006 			aprint_error(": couldn't enable clock\n");
   1007 			return;
   1008 		}
   1009 
   1010 	if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
   1011 		if (fdtbus_reset_deassert(rst) != 0) {
   1012 			aprint_error(": couldn't de-assert reset\n");
   1013 			return;
   1014 		}
   1015 
   1016 	sc->sc_dev = self;
   1017 	sc->sc_phandle = phandle;
   1018 	sc->sc_bst = faa->faa_bst;
   1019 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
   1020 		aprint_error(": couldn't map registers\n");
   1021 		return;
   1022 	}
   1023 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
   1024 	sc->sc_padconf = of_compatible_lookup(phandle, compat_data)->data;
   1025 
   1026 	aprint_naive("\n");
   1027 	aprint_normal(": PIO\n");
   1028 
   1029 	fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs);
   1030 
   1031 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
   1032 		bool is_valid =
   1033 		    (of_hasprop(child, "function") && of_hasprop(child, "pins")) ||
   1034 		    (of_hasprop(child, "allwinner,function") && of_hasprop(child, "allwinner,pins"));
   1035 		if (!is_valid)
   1036 			continue;
   1037 		fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs);
   1038 	}
   1039 
   1040 	sunxi_gpio_attach_ports(sc);
   1041 
   1042 	/* Disable all external interrupts */
   1043 	for (int i = 0; i < sc->sc_padconf->npins; i++) {
   1044 		const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[i];
   1045 		if (pin_def->eint_func == 0)
   1046 			continue;
   1047 		GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(pin_def->eint_bank), __BIT(pin_def->eint_num));
   1048 		GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(pin_def->eint_bank), __BIT(pin_def->eint_num));
   1049 
   1050 		if (sc->sc_eint_bank_max < pin_def->eint_bank)
   1051 			sc->sc_eint_bank_max = pin_def->eint_bank;
   1052 	}
   1053 	KASSERT(sc->sc_eint_bank_max < SUNXI_GPIO_MAX_EINT_BANK);
   1054 
   1055 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
   1056 		aprint_error_dev(self, "failed to decode interrupt\n");
   1057 		return;
   1058 	}
   1059 	sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM,
   1060 	    FDT_INTR_MPSAFE, sunxi_gpio_intr, sc, device_xname(self));
   1061 	if (sc->sc_ih == NULL) {
   1062 		aprint_error_dev(self, "failed to establish interrupt on %s\n",
   1063 		    intrstr);
   1064 		return;
   1065 	}
   1066 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
   1067 	fdtbus_register_interrupt_controller(self, phandle,
   1068 	    &sunxi_gpio_intrfuncs);
   1069 }
   1070