1/*- 2 * Copyright (c) 2011, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * SUCH DAMAGE. 26 */ 27 28/* 29 * GPIO driver for Cavium Octeon 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/mips/cavium/octeon_gpio.c 277996 2015-01-31 19:32:14Z loos $"); |
34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/bus.h> 38 39#include <sys/kernel.h> 40#include <sys/module.h> 41#include <sys/rman.h> --- 4 unchanged lines hidden (view full) --- 46#include <machine/bus.h> 47#include <machine/resource.h> 48 49#include <contrib/octeon-sdk/cvmx.h> 50#include <contrib/octeon-sdk/cvmx-gpio.h> 51#include <mips/cavium/octeon_irq.h> 52 53#include <mips/cavium/octeon_gpiovar.h> |
54#include <dev/gpio/gpiobusvar.h> |
55 56#include "gpio_if.h" 57 58#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 59 60struct octeon_gpio_pin { 61 const char *name; 62 int pin; --- 23 unchanged lines hidden (view full) --- 86static int octeon_gpio_attach(device_t dev); 87static int octeon_gpio_detach(device_t dev); 88static int octeon_gpio_filter(void *arg); 89static void octeon_gpio_intr(void *arg); 90 91/* 92 * GPIO interface 93 */ |
94static device_t octeon_gpio_get_bus(device_t); |
95static int octeon_gpio_pin_max(device_t dev, int *maxpin); 96static int octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); 97static int octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t 98 *flags); 99static int octeon_gpio_pin_getname(device_t dev, uint32_t pin, char *name); 100static int octeon_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); 101static int octeon_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); 102static int octeon_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); --- 28 unchanged lines hidden (view full) --- 131 else 132 gpio_cfgx.s.rx_xor = 0; 133 cvmx_write_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin), gpio_cfgx.u64); 134 } 135 136 GPIO_UNLOCK(sc); 137} 138 |
139static device_t 140octeon_gpio_get_bus(device_t dev) 141{ 142 struct octeon_gpio_softc *sc; 143 144 sc = device_get_softc(dev); 145 146 return (sc->busdev); 147} 148 |
149static int 150octeon_gpio_pin_max(device_t dev, int *maxpin) 151{ 152 153 *maxpin = OCTEON_GPIO_PINS - 1; 154 return (0); 155} 156 --- 284 unchanged lines hidden (view full) --- 441 if (bootverbose) { 442 for (i = 0; i < 16; i++) { 443 gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(i)); 444 device_printf(dev, "[pin%d] output=%d, invinput=%d, intr=%d, intr_type=%s\n", 445 i, gpio_cfgx.s.tx_oe, gpio_cfgx.s.rx_xor, 446 gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising edge" : "level"); 447 } 448 } |
449 sc->busdev = gpiobus_attach_bus(dev); 450 if (sc->busdev == NULL) { 451 octeon_gpio_detach(dev); 452 return (ENXIO); 453 } |
454 |
455 return (0); |
456} 457 458static int 459octeon_gpio_detach(device_t dev) 460{ 461 struct octeon_gpio_softc *sc = device_get_softc(dev); 462 int i; 463 464 KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); 465 466 for ( i = 0; i < OCTEON_GPIO_IRQS; i++) { 467 if (sc->gpio_ih[i]) 468 bus_teardown_intr(dev, sc->gpio_irq_res[i], 469 sc->gpio_ih[i]); 470 if (sc->gpio_irq_res[i]) 471 bus_release_resource(dev, SYS_RES_IRQ, 472 sc->gpio_irq_rid[i], sc->gpio_irq_res[i]); 473 } |
474 gpiobus_detach_bus(dev); |
475 mtx_destroy(&sc->gpio_mtx); 476 477 return(0); 478} 479 480static device_method_t octeon_gpio_methods[] = { 481 DEVMETHOD(device_identify, octeon_gpio_identify), 482 DEVMETHOD(device_probe, octeon_gpio_probe), 483 DEVMETHOD(device_attach, octeon_gpio_attach), 484 DEVMETHOD(device_detach, octeon_gpio_detach), 485 486 /* GPIO protocol */ |
487 DEVMETHOD(gpio_get_bus, octeon_gpio_get_bus), |
488 DEVMETHOD(gpio_pin_max, octeon_gpio_pin_max), 489 DEVMETHOD(gpio_pin_getname, octeon_gpio_pin_getname), 490 DEVMETHOD(gpio_pin_getflags, octeon_gpio_pin_getflags), 491 DEVMETHOD(gpio_pin_getcaps, octeon_gpio_pin_getcaps), 492 DEVMETHOD(gpio_pin_setflags, octeon_gpio_pin_setflags), 493 DEVMETHOD(gpio_pin_get, octeon_gpio_pin_get), 494 DEVMETHOD(gpio_pin_set, octeon_gpio_pin_set), 495 DEVMETHOD(gpio_pin_toggle, octeon_gpio_pin_toggle), 496 {0, 0}, 497}; 498 499static driver_t octeon_gpio_driver = { 500 "gpio", 501 octeon_gpio_methods, 502 sizeof(struct octeon_gpio_softc), 503}; 504static devclass_t octeon_gpio_devclass; 505 506DRIVER_MODULE(octeon_gpio, ciu, octeon_gpio_driver, octeon_gpio_devclass, 0, 0); |