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.
Unified · Split
| @@ -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 | ||
| 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 | |||
| 431 | static long linehandle_ioctl(struct file *filep, unsigned int cmd, | 479 | static 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) |