Moves all the duplicate code to a single function.
Verify for invalid modes and unwanted flags before pass the new flags to driver.
This commit is contained in:
parent
61c009a1a8
commit
667357dc9b
@ -302,20 +302,6 @@ a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->sc_gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & sc->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);
|
||||
|
||||
/* Can't mix pull-up/pull-down together. */
|
||||
if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
|
||||
(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
|
||||
return (EINVAL);
|
||||
|
||||
a10_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
|
@ -397,20 +397,6 @@ bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (bcm_gpio_pin_is_ro(sc, pin))
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & sc->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);
|
||||
|
||||
/* Can't mix pull-up/pull-down together. */
|
||||
if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
|
||||
(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
|
||||
return (EINVAL);
|
||||
|
||||
bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
|
@ -268,18 +268,8 @@ imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
|
||||
imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -312,15 +312,6 @@ vf_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
|
||||
vf_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
|
@ -318,20 +318,6 @@ rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->sc_gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & sc->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);
|
||||
|
||||
/* Can't mix pull-up/pull-down together. */
|
||||
if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
|
||||
(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
|
||||
return (EINVAL);
|
||||
|
||||
rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
|
@ -764,15 +764,6 @@ pad_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
|
||||
pad_pin_configure(sc, &sc->gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
|
@ -462,16 +462,6 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
uint32_t mask = (1UL << (pin % PINS_PER_BANK));
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Sanity check the flags supplied are valid, i.e. not input and output */
|
||||
if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 0x0000)
|
||||
return (EINVAL);
|
||||
if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
|
||||
(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
|
||||
return (EINVAL);
|
||||
if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
|
||||
(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
|
||||
return (EINVAL);
|
||||
|
||||
TI_GPIO_LOCK(sc);
|
||||
|
||||
/* Sanity check the pin number is valid */
|
||||
|
@ -220,16 +220,8 @@ avila_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask))
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & sc->sc_pins[pin].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);
|
||||
|
||||
avila_gpio_pin_configure(sc, &sc->sc_pins[pin], flags);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -317,15 +317,6 @@ cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (pin >= GPIO_PINS)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & sc->sc_pins[pin].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);
|
||||
|
||||
GPIO_LOCK(sc);
|
||||
sc->sc_pins[pin].gp_flags = flags;
|
||||
|
||||
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/gpio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
@ -70,6 +71,23 @@ static int gpiobus_pin_set(device_t, device_t, uint32_t, unsigned int);
|
||||
static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*);
|
||||
static int gpiobus_pin_toggle(device_t, device_t, uint32_t);
|
||||
|
||||
int
|
||||
gpio_check_flags(uint32_t caps, uint32_t flags)
|
||||
{
|
||||
|
||||
/* Check for unwanted flags. */
|
||||
if ((flags & caps) == 0 || (flags & caps) != flags)
|
||||
return (EINVAL);
|
||||
/* Cannot mix input/output together. */
|
||||
if (flags & GPIO_PIN_INPUT && flags & GPIO_PIN_OUTPUT)
|
||||
return (EINVAL);
|
||||
/* Cannot mix pull-up/pull-down together. */
|
||||
if (flags & GPIO_PIN_PULLUP && flags & GPIO_PIN_PULLDOWN)
|
||||
return (EINVAL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen)
|
||||
{
|
||||
@ -490,11 +508,16 @@ gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin,
|
||||
{
|
||||
struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
|
||||
struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
|
||||
uint32_t caps;
|
||||
|
||||
if (pin >= devi->npins)
|
||||
return (EINVAL);
|
||||
if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0)
|
||||
return (EINVAL);
|
||||
if (gpio_check_flags(caps, flags) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
return GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags);
|
||||
return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -94,6 +94,7 @@ gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
|
||||
|
||||
device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t);
|
||||
#endif
|
||||
int gpio_check_flags(uint32_t, uint32_t);
|
||||
int gpiobus_init_softc(device_t);
|
||||
|
||||
extern driver_t gpiobus_driver;
|
||||
|
@ -29,19 +29,16 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/gpio.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/queue.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <sys/gpio.h>
|
||||
#include <dev/gpio/gpiobusvar.h>
|
||||
|
||||
#include "gpio_if.h"
|
||||
|
||||
#undef GPIOC_DEBUG
|
||||
@ -119,6 +116,7 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
|
||||
struct gpioc_softc *sc = cdev->si_drv1;
|
||||
struct gpio_pin pin;
|
||||
struct gpio_req req;
|
||||
uint32_t caps;
|
||||
|
||||
switch (cmd) {
|
||||
case GPIOMAXPIN:
|
||||
@ -141,8 +139,12 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
|
||||
case GPIOSETCONFIG:
|
||||
bcopy(arg, &pin, sizeof(pin));
|
||||
dprintf("set config pin %d\n", pin.gp_pin);
|
||||
res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin,
|
||||
pin.gp_flags);
|
||||
res = GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &caps);
|
||||
if (res == 0)
|
||||
res = gpio_check_flags(caps, pin.gp_flags);
|
||||
if (res == 0)
|
||||
res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin,
|
||||
pin.gp_flags);
|
||||
break;
|
||||
case GPIOGET:
|
||||
bcopy(arg, &req, sizeof(req));
|
||||
|
@ -241,16 +241,8 @@ ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
|
||||
ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -219,16 +219,8 @@ octeon_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
}
|
||||
|
||||
|
@ -242,18 +242,8 @@ rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
if (i >= sc->gpio_npins)
|
||||
return (EINVAL);
|
||||
|
||||
/* Check for 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);
|
||||
|
||||
rt305x_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -295,11 +295,6 @@ wiigpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
if ((flags & ~(GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) != 0)
|
||||
return (EINVAL);
|
||||
if ((flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) ==
|
||||
(GPIO_PIN_OUTPUT|GPIO_PIN_INPUT))
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
pinbank = WIIGPIO_PINBANK(pin);
|
||||
pinmask = WIIGPIO_PINMASK(pin);
|
||||
|
Loading…
Reference in New Issue
Block a user