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
428 GPIOHANDLE_REQUEST_OPEN_DRAIN | \428 GPIOHANDLE_REQUEST_OPEN_DRAIN | \
429 GPIOHANDLE_REQUEST_OPEN_SOURCE)429 GPIOHANDLE_REQUEST_OPEN_SOURCE)
430 430
431static 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
431static long linehandle_ioctl(struct file *filep, unsigned int cmd,479static long linehandle_ioctl(struct file *filep, unsigned int cmd,
432 unsigned long arg)480 unsigned long arg)
433{481{
@@ -529,48 +577,9 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) · 95 unmodified lines
529 577
530 lflags = handlereq.flags;578 lflags = handlereq.flags;
531 579
532 /* Return an error if an unknown flag is set */580 ret = linehandle_validate_flags(lflags);
533 if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)581 if (ret)
534 return -EINVAL;582 return ret;
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;
574 583
575 lh = kzalloc(sizeof(*lh), GFP_KERNEL);584 lh = kzalloc(sizeof(*lh), GFP_KERNEL);
576 if (!lh)585 if (!lh)