diff options
Diffstat (limited to 'sys/dev/gpio')
-rw-r--r-- | sys/dev/gpio/gpioc.c | 31 | ||||
-rw-r--r-- | sys/dev/gpio/gpioled.c | 2 | ||||
-rw-r--r-- | sys/dev/gpio/pl061.c | 3 |
3 files changed, 21 insertions, 15 deletions
diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c index 5a60f939dc78..6c6f79227166 100644 --- a/sys/dev/gpio/gpioc.c +++ b/sys/dev/gpio/gpioc.c @@ -704,7 +704,7 @@ gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) * npins isn't a horrible fifo size for that either. */ priv->numevents = priv->sc->sc_npins * 2; - priv->events = malloc(priv->numevents * sizeof(struct gpio_event_detail), + priv->events = malloc(priv->numevents * sizeof(struct gpioc_pin_event), M_GPIOC, M_WAITOK | M_ZERO); priv->evidx_head = priv->evidx_tail = 0; @@ -793,6 +793,7 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, struct gpio_access_32 *a32; struct gpio_config_32 *c32; struct gpio_event_config *evcfg; + struct gpioc_pin_event *tmp; uint32_t caps, intrflags; switch (cmd) { @@ -908,27 +909,35 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, res = devfs_get_cdevpriv((void **)&priv); if (res != 0) break; - /* If any pins have been configured, changes aren't allowed. */ - if (!SLIST_EMPTY(&priv->pins)) { - res = EINVAL; - break; - } if (evcfg->gp_report_type != GPIO_EVENT_REPORT_DETAIL && evcfg->gp_report_type != GPIO_EVENT_REPORT_SUMMARY) { res = EINVAL; break; } - priv->report_option = evcfg->gp_report_type; /* Reallocate the events buffer if the user wants it bigger. */ - if (priv->report_option == GPIO_EVENT_REPORT_DETAIL && + tmp = NULL; + if (evcfg->gp_report_type == GPIO_EVENT_REPORT_DETAIL && priv->numevents < evcfg->gp_fifo_size) { + tmp = malloc(evcfg->gp_fifo_size * + sizeof(struct gpioc_pin_event), M_GPIOC, + M_WAITOK | M_ZERO); + } + mtx_lock(&priv->mtx); + /* If any pins have been configured, changes aren't allowed. */ + if (!SLIST_EMPTY(&priv->pins)) { + mtx_unlock(&priv->mtx); + free(tmp, M_GPIOC); + res = EINVAL; + break; + } + if (tmp != NULL) { free(priv->events, M_GPIOC); + priv->events = tmp; priv->numevents = evcfg->gp_fifo_size; - priv->events = malloc(priv->numevents * - sizeof(struct gpio_event_detail), M_GPIOC, - M_WAITOK | M_ZERO); priv->evidx_head = priv->evidx_tail = 0; } + priv->report_option = evcfg->gp_report_type; + mtx_unlock(&priv->mtx); break; case FIONBIO: /* diff --git a/sys/dev/gpio/gpioled.c b/sys/dev/gpio/gpioled.c index 71af5741b2fe..a36c2faef379 100644 --- a/sys/dev/gpio/gpioled.c +++ b/sys/dev/gpio/gpioled.c @@ -75,8 +75,6 @@ gpioled_control(void *priv, int onoff) struct gpioled_softc *sc; sc = (struct gpioled_softc *)priv; - if (onoff == -1) /* Keep the current state. */ - return; if (sc->sc_softinvert) onoff = !onoff; GPIOLED_LOCK(sc); diff --git a/sys/dev/gpio/pl061.c b/sys/dev/gpio/pl061.c index 32109e5982bc..9996b0253c7d 100644 --- a/sys/dev/gpio/pl061.c +++ b/sys/dev/gpio/pl061.c @@ -558,8 +558,7 @@ static device_method_t pl061_methods[] = { /* Bus interface */ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), /* GPIO protocol */ DEVMETHOD(gpio_get_bus, pl061_get_bus), |