svn commit: r228925 - head/sys/mips/cavium
Aleksandr Rybalko
ray at dlink.ua
Wed Dec 28 10:15:30 UTC 2011
On Wed, 28 Dec 2011 05:57:03 +0000 (UTC)
Oleksandr Tymoshenko <gonzo at 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 at 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 at 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 at dlink.ua>
aka Alex RAY <ray at ddteam.net>
More information about the svn-src-all
mailing list