set pull-up/down flags in lineevent_create and add sanity checks Check the pull-up/down flags in lineevent_create() and set the corresponding bits. Add sanity checks to make pull-up and pull-down flags mutually exclusive and only valid when the line is an input. Signed-off-by: Drew Fustini <drew@xxxxxxxx> --- drivers/gpio/gpiolib.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 646ae4cffe26..babc26267561 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -554,6 +554,20 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))) return -EINVAL; + /* + * Do not allow PULL_UP & PULL_DOWN flags to be set as they are + * contradictory. + */ + if ((lflags & GPIOHANDLE_REQUEST_PULL_UP) && + (lflags & GPIOHANDLE_REQUEST_PULL_DOWN)) + return -EINVAL; + + /* PULL_UP and PULL_DOWN flags only make sense for input mode. */ + if (!(lflags & GPIOHANDLE_REQUEST_INPUT) && + ((lflags & GPIOHANDLE_REQUEST_PULL_UP) || + (lflags & GPIOHANDLE_REQUEST_PULL_DOWN))) + return -EINVAL; + lh = kzalloc(sizeof(*lh), GFP_KERNEL); if (!lh) return -ENOMEM; @@ -941,6 +955,24 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) goto out_free_label; } + /* + * Do not allow PULL_UP & PULL_DOWN flags to be set as they are + * contradictory. + */ + if ((lflags & GPIOHANDLE_REQUEST_PULL_UP) && + (lflags & GPIOHANDLE_REQUEST_PULL_DOWN)) { + ret = -EINVAL; + goto out_free_label; + } + + /* PULL_UP and PULL_DOWN flags only make sense for input mode. */ + if (!(lflags & GPIOHANDLE_REQUEST_INPUT) && + ((lflags & GPIOHANDLE_REQUEST_PULL_UP) || + (lflags & GPIOHANDLE_REQUEST_PULL_DOWN))) { + ret = -EINVAL; + goto out_free_label; + } + desc = &gdev->descs[offset]; ret = gpiod_request(desc, le->label); if (ret) @@ -950,6 +982,10 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) set_bit(FLAG_ACTIVE_LOW, &desc->flags); + if (lflags & GPIO_PULL_UP) + set_bit(FLAG_PULL_UP, &desc->flags); + else if (lflags & GPIO_PULL_DOWN) + set_bit(FLAG_PULL_DOWN, &desc->flags); ret = gpiod_direction_input(desc); if (ret) -- 2.20.1