On Wed, 28 Dec 2011 05:57:03 +0000 (UTC)
Oleksandr Tymoshenko <go...@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 <go...@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 <go...@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 <r...@dlink.ua> 
aka Alex RAY <r...@ddteam.net>
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to