Module: xenomai-3 Branch: next Commit: 15da7eeb46c9ff1a1bced18f4839cedafe05e907 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=15da7eeb46c9ff1a1bced18f4839cedafe05e907
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Feb 10 16:13:59 2017 +0100 drivers/gpio: do not require IRQEN for reading a pin Reading a pin should only require to have set its direction to input mode using the DIR_IN request, nothing beyond that. IRQEN still implicitly allows for reading a pin though. --- kernel/drivers/gpio/gpio-core.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/gpio/gpio-core.c b/kernel/drivers/gpio/gpio-core.c index c310a96..3acc555 100644 --- a/kernel/drivers/gpio/gpio-core.c +++ b/kernel/drivers/gpio/gpio-core.c @@ -34,7 +34,9 @@ struct rtdm_gpio_pin { }; struct rtdm_gpio_chan { - bool requested; + int requested : 1, + has_direction : 1, + is_output : 1 ; }; static int gpio_pin_interrupt(rtdm_irq_t *irqh) @@ -77,6 +79,7 @@ static int request_gpio_irq(unsigned int gpio, struct rtdm_gpio_pin *pin, goto fail; } + chan->has_direction = true; gpio_export(gpio, true); rtdm_event_clear(&pin->event); @@ -133,9 +136,15 @@ static int gpio_pin_ioctl_nrt(struct rtdm_fd *fd, if (ret) return ret; ret = gpio_direction_output(gpio, val); + if (ret == 0) { + chan->has_direction = true; + chan->is_output = true; + } break; case GPIO_RTIOC_DIR_IN: ret = gpio_direction_input(gpio); + if (ret == 0) + chan->has_direction = true; break; case GPIO_RTIOC_IRQEN: if (chan->requested) @@ -148,6 +157,7 @@ static int gpio_pin_ioctl_nrt(struct rtdm_fd *fd, break; case GPIO_RTIOC_IRQDIS: release_gpio_irq(gpio, pin, chan); + chan->requested = false; break; default: return -EINVAL; @@ -167,9 +177,12 @@ static ssize_t gpio_pin_read_rt(struct rtdm_fd *fd, if (len < sizeof(value)) return -EINVAL; - if (!chan->requested) + if (!chan->has_direction) return -EAGAIN; + if (chan->is_output) + return -EINVAL; + pin = container_of(dev, struct rtdm_gpio_pin, dev); if (!(fd->oflags & O_NONBLOCK)) { @@ -187,6 +200,7 @@ static ssize_t gpio_pin_read_rt(struct rtdm_fd *fd, static ssize_t gpio_pin_write_rt(struct rtdm_fd *fd, const void __user *buf, size_t len) { + struct rtdm_gpio_chan *chan = rtdm_fd_to_private(fd); struct rtdm_device *dev = rtdm_fd_device(fd); struct rtdm_gpio_pin *pin; int value, ret; @@ -194,6 +208,12 @@ static ssize_t gpio_pin_write_rt(struct rtdm_fd *fd, if (len < sizeof(value)) return -EINVAL; + if (!chan->has_direction) + return -EAGAIN; + + if (!chan->is_output) + return -EINVAL; + ret = rtdm_safe_copy_from_user(fd, &value, buf, sizeof(value)); if (ret) return ret; @@ -211,9 +231,12 @@ static int gpio_pin_select(struct rtdm_fd *fd, struct xnselector *selector, struct rtdm_device *dev = rtdm_fd_device(fd); struct rtdm_gpio_pin *pin; - if (!chan->requested) + if (!chan->has_direction) return -EAGAIN; + if (chan->is_output) + return -EINVAL; + pin = container_of(dev, struct rtdm_gpio_pin, dev); return rtdm_event_select(&pin->event, selector, type, index); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git