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: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
parent
64e7112ee3
commit
b043ed7ef0
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue