Commit b043ed7e authored by Kent Gibson's avatar Kent Gibson Committed by Bartosz Golaszewski

gpiolib: move validation of line handle flags into helper function

Move validation of line handle flags into helper function.
This reduces the size and complexity of linehandle_create and allows the
validation to be reused elsewhere.
Signed-off-by: default avatarKent Gibson <warthog618@gmail.com>
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
parent 64e7112e
...@@ -428,6 +428,54 @@ struct linehandle_state { ...@@ -428,6 +428,54 @@ struct linehandle_state {
GPIOHANDLE_REQUEST_OPEN_DRAIN | \ GPIOHANDLE_REQUEST_OPEN_DRAIN | \
GPIOHANDLE_REQUEST_OPEN_SOURCE) GPIOHANDLE_REQUEST_OPEN_SOURCE)
static int linehandle_validate_flags(u32 flags)
{
/* Return an error if an unknown flag is set */
if (flags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
return -EINVAL;
/*
* Do not allow both INPUT & OUTPUT flags to be set as they are
* contradictory.
*/
if ((flags & GPIOHANDLE_REQUEST_INPUT) &&
(flags & GPIOHANDLE_REQUEST_OUTPUT))
return -EINVAL;
/*
* Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
* the hardware actually supports enabling both at the same time the
* electrical result would be disastrous.
*/
if ((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) &&
(flags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
return -EINVAL;
/* OPEN_DRAIN and OPEN_SOURCE flags only make sense for output mode. */
if (!(flags & GPIOHANDLE_REQUEST_OUTPUT) &&
((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
(flags & GPIOHANDLE_REQUEST_OPEN_SOURCE)))
return -EINVAL;
/* Bias flags only allowed for input or output mode. */
if (!((flags & GPIOHANDLE_REQUEST_INPUT) ||
(flags & GPIOHANDLE_REQUEST_OUTPUT)) &&
((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) ||
(flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP) ||
(flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN)))
return -EINVAL;
/* Only one bias flag can be set. */
if (((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
(flags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
((flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
(flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
return -EINVAL;
return 0;
}
static long linehandle_ioctl(struct file *filep, unsigned int cmd, static long linehandle_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -529,48 +577,9 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -529,48 +577,9 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
lflags = handlereq.flags; lflags = handlereq.flags;
/* Return an error if an unknown flag is set */ ret = linehandle_validate_flags(lflags);
if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) if (ret)
return -EINVAL; return ret;
/*
* Do not allow both INPUT & OUTPUT flags to be set as they are
* contradictory.
*/
if ((lflags & GPIOHANDLE_REQUEST_INPUT) &&
(lflags & GPIOHANDLE_REQUEST_OUTPUT))
return -EINVAL;
/*
* Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
* the hardware actually supports enabling both at the same time the
* electrical result would be disastrous.
*/
if ((lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) &&
(lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
return -EINVAL;
/* OPEN_DRAIN and OPEN_SOURCE flags only make sense for output mode. */
if (!(lflags & GPIOHANDLE_REQUEST_OUTPUT) &&
((lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
(lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)))
return -EINVAL;
/* Bias flags only allowed for input or output mode. */
if (!((lflags & GPIOHANDLE_REQUEST_INPUT) ||
(lflags & GPIOHANDLE_REQUEST_OUTPUT)) &&
((lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE) ||
(lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP) ||
(lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN)))
return -EINVAL;
/* Only one bias flag can be set. */
if (((lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
(lflags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
((lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
(lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
return -EINVAL;
lh = kzalloc(sizeof(*lh), GFP_KERNEL); lh = kzalloc(sizeof(*lh), GFP_KERNEL);
if (!lh) if (!lh)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment