Date: Wed, 28 Dec 2011 12:15:41 +0200 From: Aleksandr Rybalko <ray@dlink.ua> To: Oleksandr Tymoshenko <gonzo@FreeBSD.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r228925 - head/sys/mips/cavium Message-ID: <20111228121541.9698722c.ray@dlink.ua> In-Reply-To: <201112280557.pBS5v3HZ085555@svn.freebsd.org> References: <201112280557.pBS5v3HZ085555@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 28 Dec 2011 05:57:03 +0000 (UTC) Oleksandr Tymoshenko <gonzo@FreeBSD.org> wrote: >> Author: gonzo >> Date: Wed Dec 28 05:57:03 2011 >> New Revision: 228925 >> URL: http://svn.freebsd.org/changeset/base/228925 >> >> Log: >> - Add generic GPIO driver for Cavium Octeon. At the moment pin >> definition is hardcoded but will be changed later with more flexible >> way to define them. >> >> Added: >> head/sys/mips/cavium/octeon_gpio.c (contents, props changed) >> head/sys/mips/cavium/octeon_gpiovar.h (contents, props changed) >> Modified: >> head/sys/mips/cavium/files.octeon1 >> >> Modified: head/sys/mips/cavium/files.octeon1 >> ============================================================================== >> --- head/sys/mips/cavium/files.octeon1 Wed Dec 28 05:35:33 >> 2011 (r228924) +++ head/sys/mips/cavium/files.octeon1 >> Wed Dec 28 05:57:03 2011 (r228925) @@ -49,6 +49,8 @@ >> mips/cavium/usb/octusb_octeon.c option >> contrib/octeon-sdk/cvmx-usb.c optional octusb >> >> +mips/cavium/octeon_gpio.c optional gpio >> + >> # XXX Some files could be excluded in some configurations. Making >> # them optional but on in the default config would seem reasonable. >> contrib/octeon-sdk/cvmx-cmd-queue.c standard >> >> Added: head/sys/mips/cavium/octeon_gpio.c >> ============================================================================== >> --- /dev/null 00:00:00 1970 (empty, because file is >> newly added) +++ head/sys/mips/cavium/octeon_gpio.c Wed Dec >> 28 05:57:03 2011 (r228925) @@ -0,0 +1,494 @@ >> +/*- >> + * Copyright (c) 2011, Oleksandr Tymoshenko <gonzo@FreeBSD.org> >> + * All rights reserved. >> + * >> + * Redistribution and use in source and binary forms, with or >> without >> + * modification, are permitted provided that the following >> conditions >> + * are met: >> + * 1. Redistributions of source code must retain the above copyright >> + * notice unmodified, this list of conditions, and the following >> + * disclaimer. >> + * 2. Redistributions in binary form must reproduce the above >> copyright >> + * notice, this list of conditions and the following disclaimer >> in the >> + * documentation and/or other materials provided with the >> distribution. >> + * >> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS >> IS'' AND >> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >> TO, THE >> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A >> PARTICULAR PURPOSE >> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE >> LIABLE >> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >> CONSEQUENTIAL >> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >> SUBSTITUTE GOODS >> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >> INTERRUPTION) >> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >> CONTRACT, STRICT >> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING >> IN ANY WAY >> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE >> POSSIBILITY OF >> + * SUCH DAMAGE. >> + */ >> + >> +/* >> + * GPIO driver for Cavium Octeon >> + */ >> + >> +#include <sys/cdefs.h> >> +__FBSDID("$FreeBSD$"); >> + >> +#include <sys/param.h> >> +#include <sys/systm.h> >> +#include <sys/bus.h> >> + >> +#include <sys/kernel.h> >> +#include <sys/module.h> >> +#include <sys/rman.h> >> +#include <sys/lock.h> >> +#include <sys/mutex.h> >> +#include <sys/gpio.h> >> + >> +#include <machine/bus.h> >> +#include <machine/resource.h> >> + >> +#include <contrib/octeon-sdk/cvmx.h> >> +#include <contrib/octeon-sdk/cvmx-gpio.h> >> +#include <contrib/octeon-sdk/cvmx-interrupt.h> >> + >> +#include <mips/cavium/octeon_gpiovar.h> >> + >> +#include "gpio_if.h" >> + >> +#define DEFAULT_CAPS (GPIO_PIN_INPUT | >> GPIO_PIN_OUTPUT) + >> +struct octeon_gpio_pin { >> + const char *name; >> + int pin; >> + int flags; >> +}; >> + >> +/* >> + * on CAP100 GPIO 7 is "Factory defaults" button >> + * >> + */ >> +static struct octeon_gpio_pin octeon_gpio_pins[] = { >> + { "F/D", 7, GPIO_PIN_INPUT}, >> + { NULL, 0, 0}, >> +}; >> + >> +/* >> + * Helpers >> + */ >> +static void octeon_gpio_pin_configure(struct octeon_gpio_softc *sc, >> + struct gpio_pin *pin, uint32_t flags); >> + >> +/* >> + * Driver stuff >> + */ >> +static void octeon_gpio_identify(driver_t *, device_t); >> +static int octeon_gpio_probe(device_t dev); >> +static int octeon_gpio_attach(device_t dev); >> +static int octeon_gpio_detach(device_t dev); >> +static int octeon_gpio_filter(void *arg); >> +static void octeon_gpio_intr(void *arg); >> + >> +/* >> + * GPIO interface >> + */ >> +static int octeon_gpio_pin_max(device_t dev, int *maxpin); >> +static int octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, >> uint32_t *caps); +static int octeon_gpio_pin_getflags(device_t dev, >> uint32_t pin, uint32_t >> + *flags); >> +static int octeon_gpio_pin_getname(device_t dev, uint32_t pin, char >> *name); +static int octeon_gpio_pin_setflags(device_t dev, uint32_t >> pin, uint32_t flags); +static int octeon_gpio_pin_set(device_t dev, >> uint32_t pin, unsigned int value); +static int octeon_gpio_pin_get >> (device_t dev, uint32_t pin, unsigned int *val); +static int >> octeon_gpio_pin_toggle(device_t dev, uint32_t pin); + >> +static void >> +octeon_gpio_pin_configure(struct octeon_gpio_softc *sc, struct >> gpio_pin *pin, >> + unsigned int flags) >> +{ >> + uint32_t mask; >> + cvmx_gpio_bit_cfgx_t gpio_cfgx; >> + >> + mask = 1 << pin->gp_pin; >> + GPIO_LOCK(sc); >> + >> + /* >> + * Manage input/output >> + */ >> + if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { >> + gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX >> (pin->gp_pin)); >> + pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); >> + if (flags & GPIO_PIN_OUTPUT) { >> + pin->gp_flags |= GPIO_PIN_OUTPUT; >> + gpio_cfgx.s.tx_oe = 1; >> + } >> + else { >> + pin->gp_flags |= GPIO_PIN_INPUT; >> + gpio_cfgx.s.tx_oe = 0; >> + } >> + if (flags & GPIO_PIN_INVIN) >> + gpio_cfgx.s.rx_xor = 1; >> + else >> + gpio_cfgx.s.rx_xor = 0; >> + cvmx_write_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin), >> gpio_cfgx.u64); >> + } >> + >> + GPIO_UNLOCK(sc); >> +} >> + >> +static int >> +octeon_gpio_pin_max(device_t dev, int *maxpin) >> +{ >> + >> + *maxpin = OCTEON_GPIO_PINS - 1; >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + *caps = sc->gpio_pins[i].gp_caps; >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t >> *flags) +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + *flags = sc->gpio_pins[i].gp_flags; >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_getname(device_t dev, uint32_t pin, char *name) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) >> +{ >> + int i; >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + /* Filter out unwanted flags */ >> + if ((flags &= sc->gpio_pins[i].gp_caps) != flags) >> + return (EINVAL); >> + >> + /* Can't mix input/output together */ >> + if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == >> + (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) >> + return (EINVAL); >> + >> + octeon_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + if (value) >> + cvmx_gpio_set(1 << pin); >> + else >> + cvmx_gpio_clear(1 << pin); >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + uint64_t state; >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + state = cvmx_gpio_read(); >> + *val = (state & (1 << pin)) ? 1 : 0; >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_pin_toggle(device_t dev, uint32_t pin) >> +{ >> + int i; >> + uint64_t state; >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + >> + for (i = 0; i < sc->gpio_npins; i++) { >> + if (sc->gpio_pins[i].gp_pin == pin) >> + break; >> + } >> + >> + if (i >= sc->gpio_npins) >> + return (EINVAL); >> + >> + GPIO_LOCK(sc); >> + /* >> + * XXX: Need to check if read returns actual state of >> output >> + * pins or we need to keep this information by ourself >> + */ >> + state = cvmx_gpio_read(); >> + if (state & (1 << pin)) >> + cvmx_gpio_clear(1 << pin); >> + else >> + cvmx_gpio_set(1 << pin); >> + GPIO_UNLOCK(sc); >> + >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_filter(void *arg) >> +{ >> + cvmx_gpio_bit_cfgx_t gpio_cfgx; >> + void **cookie = arg; >> + struct octeon_gpio_softc *sc = *cookie; >> + long int irq = (cookie - sc->gpio_intr_cookies); >> + >> + if ((irq < 0) || (irq >= OCTEON_GPIO_IRQS)) >> + return (FILTER_STRAY); >> + >> + gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(irq)); >> + /* Clear rising edge detector */ >> + if (gpio_cfgx.s.int_type == OCTEON_GPIO_IRQ_EDGE) >> + cvmx_gpio_interrupt_clear(1 << irq); >> + /* disable interrupt */ >> + gpio_cfgx.s.int_en = 0; >> + cvmx_write_csr(CVMX_GPIO_BIT_CFGX(irq), gpio_cfgx.u64); >> + >> + return (FILTER_SCHEDULE_THREAD); >> +} >> + >> +static void >> +octeon_gpio_intr(void *arg) >> +{ >> + cvmx_gpio_bit_cfgx_t gpio_cfgx; >> + void **cookie = arg; >> + struct octeon_gpio_softc *sc = *cookie; >> + long int irq = (cookie - sc->gpio_intr_cookies); >> + >> + if ((irq < 0) || (irq >= OCTEON_GPIO_IRQS)) { >> + printf("%s: invalid GPIO IRQ: %ld\n", >> + __func__, irq); >> + return; >> + } >> + >> + GPIO_LOCK(sc); >> + gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(irq)); >> + /* disable interrupt */ >> + gpio_cfgx.s.int_en = 1; >> + cvmx_write_csr(CVMX_GPIO_BIT_CFGX(irq), gpio_cfgx.u64); >> + >> + /* TODO: notify bus here or something */ >> + printf("GPIO IRQ for pin %ld\n", irq); >> + GPIO_UNLOCK(sc); >> +} >> + >> +static void >> +octeon_gpio_identify(driver_t *drv, device_t parent) >> +{ >> + >> + BUS_ADD_CHILD(parent, 0, "gpio", 0); >> +} >> + >> +static int >> +octeon_gpio_probe(device_t dev) >> +{ >> + >> + device_set_desc(dev, "Cavium Octeon GPIO driver"); >> + return (0); >> +} >> + >> +static int >> +octeon_gpio_attach(device_t dev) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + struct octeon_gpio_pin *pinp; >> + cvmx_gpio_bit_cfgx_t gpio_cfgx; >> + >> + int i; >> + >> + KASSERT((device_get_unit(dev) == 0), >> + ("octeon_gpio: Only one gpio module supported")); >> + >> + mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), >> MTX_NETWORK_LOCK, >> + MTX_DEF); >> + >> + for ( i = 0; i < OCTEON_GPIO_IRQS; i++) { >> + if ((sc->gpio_irq_res[i] = bus_alloc_resource(dev, >> + SYS_RES_IRQ, &sc->gpio_irq_rid[i], >> + CVMX_IRQ_GPIO0 + i, CVMX_IRQ_GPIO0 + i, 1, >> + RF_SHAREABLE | RF_ACTIVE)) == NULL) { >> + device_printf(dev, "unable to allocate IRQ >> resource\n"); >> + return (ENXIO); >> + } >> + >> + sc->gpio_intr_cookies[i] = sc; >> + if ((bus_setup_intr(dev, sc->gpio_irq_res[i], >> INTR_TYPE_MISC, >> + octeon_gpio_filter, octeon_gpio_intr, >> + &(sc->gpio_intr_cookies[i]), &sc->gpio_ih[i]))) >> { >> + device_printf(dev, >> + "WARNING: unable to register interrupt >> handler\n"); >> + return (ENXIO); >> + } >> + } >> + >> + sc->dev = dev; >> + /* Configure all pins as input */ >> + /* disable interrupts for all pins */ >> + pinp = octeon_gpio_pins; >> + i = 0; >> + while (pinp->name) { >> + strncpy(sc->gpio_pins[i].gp_name, pinp->name, >> GPIOMAXNAME); >> + sc->gpio_pins[i].gp_pin = pinp->pin; >> + sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; >> + sc->gpio_pins[i].gp_flags = 0; >> + octeon_gpio_pin_configure(sc, &sc->gpio_pins[i], >> pinp->flags); >> + pinp++; >> + i++; >> + } >> + >> + sc->gpio_npins = i; >> + >> +#if 0 >> + /* >> + * Sample: how to enable edge-triggered interrupt >> + * for GPIO pin >> + */ >> + gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(7)); >> + gpio_cfgx.s.int_en = 1; >> + gpio_cfgx.s.int_type = OCTEON_GPIO_IRQ_EDGE; >> + cvmx_write_csr(CVMX_GPIO_BIT_CFGX(7), gpio_cfgx.u64); >> +#endif >> + >> + if (bootverbose) { >> + for (i = 0; i < 16; i++) { >> + gpio_cfgx.u64 = cvmx_read_csr >> (CVMX_GPIO_BIT_CFGX(i)); >> + device_printf(dev, "[pin%d] output=%d, >> invinput=%d, intr=%d, intr_type=%s\n", >> + i, gpio_cfgx.s.tx_oe, >> gpio_cfgx.s.rx_xor, >> + gpio_cfgx.s.int_en, >> gpio_cfgx.s.int_type ? "rising edge" : "level"); >> + } >> + } >> + >> + device_add_child(dev, "gpioc", device_get_unit(dev)); >> + device_add_child(dev, "gpiobus", device_get_unit(dev)); >> + return (bus_generic_attach(dev)); >> +} >> + >> +static int >> +octeon_gpio_detach(device_t dev) >> +{ >> + struct octeon_gpio_softc *sc = device_get_softc(dev); >> + int i; >> + >> + KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not >> initialized")); + >> + for ( i = 0; i < OCTEON_GPIO_IRQS; i++) { >> + bus_release_resource(dev, SYS_RES_IRQ, >> + sc->gpio_irq_rid[i], sc->gpio_irq_res[i]); >> + } >> + bus_generic_detach(dev); >> + >> + mtx_destroy(&sc->gpio_mtx); >> + >> + return(0); >> +} >> + >> +static device_method_t octeon_gpio_methods[] = { >> + DEVMETHOD(device_identify, octeon_gpio_identify), >> + DEVMETHOD(device_probe, octeon_gpio_probe), >> + DEVMETHOD(device_attach, octeon_gpio_attach), >> + DEVMETHOD(device_detach, octeon_gpio_detach), >> + >> + /* GPIO protocol */ >> + DEVMETHOD(gpio_pin_max, octeon_gpio_pin_max), >> + DEVMETHOD(gpio_pin_getname, octeon_gpio_pin_getname), >> + DEVMETHOD(gpio_pin_getflags, octeon_gpio_pin_getflags), >> + DEVMETHOD(gpio_pin_getcaps, octeon_gpio_pin_getcaps), >> + DEVMETHOD(gpio_pin_setflags, octeon_gpio_pin_setflags), >> + DEVMETHOD(gpio_pin_get, octeon_gpio_pin_get), >> + DEVMETHOD(gpio_pin_set, octeon_gpio_pin_set), >> + DEVMETHOD(gpio_pin_toggle, octeon_gpio_pin_toggle), >> + {0, 0}, >> +}; >> + >> +static driver_t octeon_gpio_driver = { >> + "gpio", >> + octeon_gpio_methods, >> + sizeof(struct octeon_gpio_softc), >> +}; >> +static devclass_t octeon_gpio_devclass; >> + >> +DRIVER_MODULE(octeon_gpio, ciu, octeon_gpio_driver, >> octeon_gpio_devclass, 0, 0); >> >> Added: head/sys/mips/cavium/octeon_gpiovar.h >> ============================================================================== >> --- /dev/null 00:00:00 1970 (empty, because file is >> newly added) +++ head/sys/mips/cavium/octeon_gpiovar.h Wed >> Dec 28 05:57:03 2011 (r228925) @@ -0,0 +1,55 @@ >> +/*- >> + * Copyright (c) 2011, Oleksandr Tymoshenko <gonzo@FreeBSD.org> >> + * All rights reserved. >> + * >> + * Redistribution and use in source and binary forms, with or >> without >> + * modification, are permitted provided that the following >> conditions >> + * are met: >> + * 1. Redistributions of source code must retain the above copyright >> + * notice unmodified, this list of conditions, and the following >> + * disclaimer. >> + * 2. Redistributions in binary form must reproduce the above >> copyright >> + * notice, this list of conditions and the following disclaimer >> in the >> + * documentation and/or other materials provided with the >> distribution. >> + * >> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS >> IS'' AND >> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >> TO, THE >> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A >> PARTICULAR PURPOSE >> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE >> LIABLE >> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >> CONSEQUENTIAL >> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >> SUBSTITUTE GOODS >> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >> INTERRUPTION) >> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >> CONTRACT, STRICT >> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING >> IN ANY WAY >> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE >> POSSIBILITY OF >> + * SUCH DAMAGE. >> + * >> + * $FreeBSD$ >> + * >> + */ >> + >> +#ifndef __OCTEON_GPIOVAR_H__ >> +#define __OCTEON_GPIOVAR_H__ >> + >> +#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->gpio_mtx) >> +#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->gpio_mtx) >> +#define GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->gpio_mtx, >> MA_OWNED) + >> +#define OCTEON_GPIO_IRQ_LEVEL 0 >> +#define OCTEON_GPIO_IRQ_EDGE 1 >> + >> +#define OCTEON_GPIO_PINS 24 >> +#define OCTEON_GPIO_IRQS 16 >> + >> +struct octeon_gpio_softc { >> + device_t dev; >> + struct mtx gpio_mtx; >> + struct resource *gpio_irq_res >> [OCTEON_GPIO_IRQS]; >> + int gpio_irq_rid[OCTEON_GPIO_IRQS]; >> + void *gpio_ih[OCTEON_GPIO_IRQS]; >> + void *gpio_intr_cookies >> [OCTEON_GPIO_IRQS]; >> + int gpio_npins; >> + struct gpio_pin gpio_pins[OCTEON_GPIO_PINS]; >> +}; >> + >> +#endif /* __OCTEON_GPIOVAR_H__ */ Thank you very much Oleksandr! Oleksandr, can you please avoid define board depended futures in a SoC drivers in future '{ "F/D", 7, GPIO_PIN_INPUT}'? So others will be able to use driver in different boards w/o modification (just by define it in hints/FDT or so). Thanks again! WBW -- Alexandr Rybalko <ray@dlink.ua> aka Alex RAY <ray@ddteam.net>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111228121541.9698722c.ray>