History

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.

Kent Gibson committed 7 years ago

Commit b043ed71 parent 64e71121 file · +51 −42Browse files

Unified · Split

drivers/gpio/gpiolib.c+51−42
@@ -428,6 +428,54 @@ struct linehandle_state { · 427 unmodified lines
428428 GPIOHANDLE_REQUEST_OPEN_DRAIN | \
429429 GPIOHANDLE_REQUEST_OPEN_SOURCE)
430430
431+static int linehandle_validate_flags(u32 flags)
432+{
433+ /* Return an error if an unknown flag is set */
434+ if (flags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
435+ return -EINVAL;
436+
437+ /*
438+ * Do not allow both INPUT & OUTPUT flags to be set as they are
439+ * contradictory.
440+ */
441+ if ((flags & GPIOHANDLE_REQUEST_INPUT) &&
442+ (flags & GPIOHANDLE_REQUEST_OUTPUT))
443+ return -EINVAL;
444+
445+ /*
446+ * Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
447+ * the hardware actually supports enabling both at the same time the
448+ * electrical result would be disastrous.
449+ */
450+ if ((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) &&
451+ (flags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
452+ return -EINVAL;
453+
454+ /* OPEN_DRAIN and OPEN_SOURCE flags only make sense for output mode. */
455+ if (!(flags & GPIOHANDLE_REQUEST_OUTPUT) &&
456+ ((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
457+ (flags & GPIOHANDLE_REQUEST_OPEN_SOURCE)))
458+ return -EINVAL;
459+
460+ /* Bias flags only allowed for input or output mode. */
461+ if (!((flags & GPIOHANDLE_REQUEST_INPUT) ||
462+ (flags & GPIOHANDLE_REQUEST_OUTPUT)) &&
463+ ((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) ||
464+ (flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP) ||
465+ (flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN)))
466+ return -EINVAL;
467+
468+ /* Only one bias flag can be set. */
469+ if (((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
470+ (flags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
471+ GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
472+ ((flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
473+ (flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
474+ return -EINVAL;
475+
476+ return 0;
477+}
478+
431479 static long linehandle_ioctl(struct file *filep, unsigned int cmd,
432480 unsigned long arg)
433481 {
@@ -529,48 +577,9 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) · 95 unmodified lines
529577
530578 lflags = handlereq.flags;
531579
532− /* Return an error if an unknown flag is set */
533− if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
534− return -EINVAL;
535−
536− /*
537− * Do not allow both INPUT & OUTPUT flags to be set as they are
538− * contradictory.
539− */
540− if ((lflags & GPIOHANDLE_REQUEST_INPUT) &&
541− (lflags & GPIOHANDLE_REQUEST_OUTPUT))
542− return -EINVAL;
543−
544− /*
545− * Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
546− * the hardware actually supports enabling both at the same time the
547− * electrical result would be disastrous.
548− */
549− if ((lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) &&
550− (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
551− return -EINVAL;
552−
553− /* OPEN_DRAIN and OPEN_SOURCE flags only make sense for output mode. */
554− if (!(lflags & GPIOHANDLE_REQUEST_OUTPUT) &&
555− ((lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
556− (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)))
557− return -EINVAL;
558−
559− /* Bias flags only allowed for input or output mode. */
560− if (!((lflags & GPIOHANDLE_REQUEST_INPUT) ||
561− (lflags & GPIOHANDLE_REQUEST_OUTPUT)) &&
562− ((lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE) ||
563− (lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP) ||
564− (lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN)))
565− return -EINVAL;
566−
567− /* Only one bias flag can be set. */
568− if (((lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
569− (lflags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
570− GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
571− ((lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
572− (lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
573− return -EINVAL;
580+ ret = linehandle_validate_flags(lflags);
581+ if (ret)
582+ return ret;
574583
575584 lh = kzalloc(sizeof(*lh), GFP_KERNEL);
576585 if (!lh)