summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorloos <loos@FreeBSD.org>2015-02-14 21:16:19 +0000
committerloos <loos@FreeBSD.org>2015-02-14 21:16:19 +0000
commita7a8c39e00df26eda21597ddbe0f587ced4375a8 (patch)
treea2bdaaa92bec82c663e0a841ddfdce165ac2ebf1
parentfd8cd0a9634bc701a7e4e2431a43432b23767400 (diff)
downloadFreeBSD-src-a7a8c39e00df26eda21597ddbe0f587ced4375a8.zip
FreeBSD-src-a7a8c39e00df26eda21597ddbe0f587ced4375a8.tar.gz
MFC r274670, r274671, r276168:
Moves all the duplicate code to a single function. Verify for invalid modes and unwanted flags before pass the new flags to driver. Make gpio_default_map_gpios() static. No functional changes. Improves the GPIO API description a little bit. gpio_pin_max must return the maximum supported pin number and not the total number of pins on the system.
-rw-r--r--sys/arm/allwinner/a10_gpio.c14
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_gpio.c14
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c10
-rw-r--r--sys/arm/freescale/vybrid/vf_gpio.c9
-rw-r--r--sys/arm/rockchip/rk30xx_gpio.c14
-rw-r--r--sys/arm/samsung/exynos/exynos5_pad.c9
-rw-r--r--sys/arm/ti/ti_gpio.c10
-rw-r--r--sys/arm/xscale/ixp425/avila_gpio.c10
-rw-r--r--sys/arm/xscale/ixp425/cambria_gpio.c9
-rw-r--r--sys/dev/gpio/gpio_if.m8
-rw-r--r--sys/dev/gpio/gpiobus.c25
-rw-r--r--sys/dev/gpio/gpiobusvar.h1
-rw-r--r--sys/dev/gpio/gpioc.c18
-rw-r--r--sys/mips/atheros/ar71xx_gpio.c10
-rw-r--r--sys/mips/cavium/octeon_gpio.c10
-rw-r--r--sys/mips/rt305x/rt305x_gpio.c10
-rw-r--r--sys/powerpc/wii/wii_gpio.c5
17 files changed, 41 insertions, 145 deletions
diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c
index a532106..23bf399 100644
--- a/sys/arm/allwinner/a10_gpio.c
+++ b/sys/arm/allwinner/a10_gpio.c
@@ -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);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
index a8903ee..48f45de 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
@@ -399,20 +399,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);
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index b365489..c23f75b 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -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);
}
diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c
index ab6274e..ab4a18b 100644
--- a/sys/arm/freescale/vybrid/vf_gpio.c
+++ b/sys/arm/freescale/vybrid/vf_gpio.c
@@ -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);
diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c
index fc24947c..5c7dc99 100644
--- a/sys/arm/rockchip/rk30xx_gpio.c
+++ b/sys/arm/rockchip/rk30xx_gpio.c
@@ -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);
diff --git a/sys/arm/samsung/exynos/exynos5_pad.c b/sys/arm/samsung/exynos/exynos5_pad.c
index 73435fa..a00e458 100644
--- a/sys/arm/samsung/exynos/exynos5_pad.c
+++ b/sys/arm/samsung/exynos/exynos5_pad.c
@@ -643,15 +643,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);
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index 707634e..ee38247 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -456,16 +456,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 */
diff --git a/sys/arm/xscale/ixp425/avila_gpio.c b/sys/arm/xscale/ixp425/avila_gpio.c
index 48f970d..4a2d1e9 100644
--- a/sys/arm/xscale/ixp425/avila_gpio.c
+++ b/sys/arm/xscale/ixp425/avila_gpio.c
@@ -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);
}
diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c
index baa3483..7a773db 100644
--- a/sys/arm/xscale/ixp425/cambria_gpio.c
+++ b/sys/arm/xscale/ixp425/cambria_gpio.c
@@ -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;
diff --git a/sys/dev/gpio/gpio_if.m b/sys/dev/gpio/gpio_if.m
index 4d6dfd1..adc119e 100644
--- a/sys/dev/gpio/gpio_if.m
+++ b/sys/dev/gpio/gpio_if.m
@@ -32,9 +32,7 @@
INTERFACE gpio;
CODE {
- static gpio_map_gpios_t gpio_default_map_gpios;
-
- int
+ static int
gpio_default_map_gpios(device_t bus, phandle_t dev,
phandle_t gparent, int gcells, pcell_t *gpios, uint32_t *pin,
uint32_t *flags)
@@ -58,11 +56,11 @@ HEADER {
};
#
-# Get total number of pins
+# Get maximum pin number
#
METHOD int pin_max {
device_t dev;
- int *npins;
+ int *maxpin;
};
#
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index dcf6049..efff2c0 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -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
diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h
index 3ec8a17..a1c2be0 100644
--- a/sys/dev/gpio/gpiobusvar.h
+++ b/sys/dev/gpio/gpiobusvar.h
@@ -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;
diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c
index 156f05c..2fad4df 100644
--- a/sys/dev/gpio/gpioc.c
+++ b/sys/dev/gpio/gpioc.c
@@ -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));
diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c
index 2ffcfb5..f799e85 100644
--- a/sys/mips/atheros/ar71xx_gpio.c
+++ b/sys/mips/atheros/ar71xx_gpio.c
@@ -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);
}
diff --git a/sys/mips/cavium/octeon_gpio.c b/sys/mips/cavium/octeon_gpio.c
index 26b42ea..3686848 100644
--- a/sys/mips/cavium/octeon_gpio.c
+++ b/sys/mips/cavium/octeon_gpio.c
@@ -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);
}
diff --git a/sys/mips/rt305x/rt305x_gpio.c b/sys/mips/rt305x/rt305x_gpio.c
index 5f7defb..a5d7254 100644
--- a/sys/mips/rt305x/rt305x_gpio.c
+++ b/sys/mips/rt305x/rt305x_gpio.c
@@ -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);
}
diff --git a/sys/powerpc/wii/wii_gpio.c b/sys/powerpc/wii/wii_gpio.c
index b9ecccb..e6d76b8 100644
--- a/sys/powerpc/wii/wii_gpio.c
+++ b/sys/powerpc/wii/wii_gpio.c
@@ -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);
OpenPOWER on IntegriCloud