Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'gpio-aggregator-refactoring-for-v6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel

Immutable branch for the pinctrl tree to pull from

Refactor the gpio-aggregator module as a prerequisite for merging the
pin controller driver for AAEON UP boards.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+466 -67
+351 -55
drivers/gpio/gpio-aggregator.c
··· 12 12 #include <linux/configfs.h> 13 13 #include <linux/ctype.h> 14 14 #include <linux/delay.h> 15 + #include <linux/export.h> 15 16 #include <linux/idr.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/list.h> ··· 29 28 30 29 #include <linux/gpio/consumer.h> 31 30 #include <linux/gpio/driver.h> 31 + #include <linux/gpio/forwarder.h> 32 32 #include <linux/gpio/machine.h> 33 33 34 34 #include "dev-sync-probe.h" ··· 246 244 spinlock_t slock; /* protects tmp[] if !can_sleep */ 247 245 }; 248 246 struct gpiochip_fwd_timing *delay_timings; 247 + void *data; 248 + unsigned long *valid_mask; 249 249 unsigned long tmp[]; /* values and descs for multiple ops */ 250 250 }; 251 251 ··· 256 252 257 253 #define fwd_tmp_size(ngpios) (BITS_TO_LONGS((ngpios)) + (ngpios)) 258 254 255 + static int gpio_fwd_request(struct gpio_chip *chip, unsigned int offset) 256 + { 257 + struct gpiochip_fwd *fwd = gpiochip_get_data(chip); 258 + 259 + return test_bit(offset, fwd->valid_mask) ? 0 : -ENODEV; 260 + } 261 + 259 262 static int gpio_fwd_get_direction(struct gpio_chip *chip, unsigned int offset) 260 263 { 261 264 struct gpiochip_fwd *fwd = gpiochip_get_data(chip); 265 + 266 + /* 267 + * get_direction() is called during gpiochip registration, return 268 + * -ENODEV if there is no GPIO desc for the line. 269 + */ 270 + if (!test_bit(offset, fwd->valid_mask)) 271 + return -ENODEV; 262 272 263 273 return gpiod_get_direction(fwd->descs[offset]); 264 274 } ··· 471 453 return line; 472 454 } 473 455 474 - static int gpiochip_fwd_setup_delay_line(struct device *dev, struct gpio_chip *chip, 475 - struct gpiochip_fwd *fwd) 456 + static int gpiochip_fwd_setup_delay_line(struct gpiochip_fwd *fwd) 476 457 { 477 - fwd->delay_timings = devm_kcalloc(dev, chip->ngpio, 458 + struct gpio_chip *chip = &fwd->chip; 459 + 460 + fwd->delay_timings = devm_kcalloc(chip->parent, chip->ngpio, 478 461 sizeof(*fwd->delay_timings), 479 462 GFP_KERNEL); 480 463 if (!fwd->delay_timings) ··· 487 468 return 0; 488 469 } 489 470 #else 490 - static int gpiochip_fwd_setup_delay_line(struct device *dev, struct gpio_chip *chip, 491 - struct gpiochip_fwd *fwd) 471 + static int gpiochip_fwd_setup_delay_line(struct gpiochip_fwd *fwd) 492 472 { 493 473 return 0; 494 474 } 495 475 #endif /* !CONFIG_OF_GPIO */ 496 476 497 477 /** 478 + * gpiochip_fwd_get_gpiochip - Get the GPIO chip for the GPIO forwarder 479 + * @fwd: GPIO forwarder 480 + * 481 + * Returns: The GPIO chip for the GPIO forwarder 482 + */ 483 + struct gpio_chip *gpiochip_fwd_get_gpiochip(struct gpiochip_fwd *fwd) 484 + { 485 + return &fwd->chip; 486 + } 487 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_get_gpiochip, "GPIO_FORWARDER"); 488 + 489 + /** 490 + * gpiochip_fwd_get_data - Get driver-private data for the GPIO forwarder 491 + * @fwd: GPIO forwarder 492 + * 493 + * Returns: The driver-private data for the GPIO forwarder 494 + */ 495 + void *gpiochip_fwd_get_data(struct gpiochip_fwd *fwd) 496 + { 497 + return fwd->data; 498 + } 499 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_get_data, "GPIO_FORWARDER"); 500 + 501 + /** 502 + * gpiochip_fwd_gpio_request - Request a line of the GPIO forwarder 503 + * @fwd: GPIO forwarder 504 + * @offset: the offset of the line to request 505 + * 506 + * Returns: 0 on success, or negative errno on failure. 507 + */ 508 + int gpiochip_fwd_gpio_request(struct gpiochip_fwd *fwd, unsigned int offset) 509 + { 510 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 511 + 512 + return gpio_fwd_request(gc, offset); 513 + } 514 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_request, "GPIO_FORWARDER"); 515 + 516 + /** 517 + * gpiochip_fwd_gpio_get_direction - Return the current direction of a GPIO forwarder line 518 + * @fwd: GPIO forwarder 519 + * @offset: the offset of the line 520 + * 521 + * Returns: 0 for output, 1 for input, or an error code in case of error. 522 + */ 523 + int gpiochip_fwd_gpio_get_direction(struct gpiochip_fwd *fwd, unsigned int offset) 524 + { 525 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 526 + 527 + return gpio_fwd_get_direction(gc, offset); 528 + } 529 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_get_direction, "GPIO_FORWARDER"); 530 + 531 + /** 532 + * gpiochip_fwd_gpio_direction_output - Set a GPIO forwarder line direction to 533 + * output 534 + * @fwd: GPIO forwarder 535 + * @offset: the offset of the line 536 + * @value: value to set 537 + * 538 + * Returns: 0 on success, or negative errno on failure. 539 + */ 540 + int gpiochip_fwd_gpio_direction_output(struct gpiochip_fwd *fwd, unsigned int offset, 541 + int value) 542 + { 543 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 544 + 545 + return gpio_fwd_direction_output(gc, offset, value); 546 + } 547 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_direction_output, "GPIO_FORWARDER"); 548 + 549 + /** 550 + * gpiochip_fwd_gpio_direction_input - Set a GPIO forwarder line direction to input 551 + * @fwd: GPIO forwarder 552 + * @offset: the offset of the line 553 + * 554 + * Returns: 0 on success, or negative errno on failure. 555 + */ 556 + int gpiochip_fwd_gpio_direction_input(struct gpiochip_fwd *fwd, unsigned int offset) 557 + { 558 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 559 + 560 + return gpio_fwd_direction_input(gc, offset); 561 + } 562 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_direction_input, "GPIO_FORWARDER"); 563 + 564 + /** 565 + * gpiochip_fwd_gpio_get - Return a GPIO forwarder line's value 566 + * @fwd: GPIO forwarder 567 + * @offset: the offset of the line 568 + * 569 + * Returns: The GPIO's logical value, i.e. taking the ACTIVE_LOW status into 570 + * account, or negative errno on failure. 571 + */ 572 + int gpiochip_fwd_gpio_get(struct gpiochip_fwd *fwd, unsigned int offset) 573 + { 574 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 575 + 576 + return gpio_fwd_get(gc, offset); 577 + } 578 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_get, "GPIO_FORWARDER"); 579 + 580 + /** 581 + * gpiochip_fwd_gpio_get_multiple - Get values for multiple GPIO forwarder lines 582 + * @fwd: GPIO forwarder 583 + * @mask: bit mask array; one bit per line; BITS_PER_LONG bits per word defines 584 + * which lines are to be read 585 + * @bits: bit value array; one bit per line; BITS_PER_LONG bits per word will 586 + * contains the read values for the lines specified by mask 587 + * 588 + * Returns: 0 on success, or negative errno on failure. 589 + */ 590 + int gpiochip_fwd_gpio_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, 591 + unsigned long *bits) 592 + { 593 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 594 + 595 + return gpio_fwd_get_multiple_locked(gc, mask, bits); 596 + } 597 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_get_multiple, "GPIO_FORWARDER"); 598 + 599 + /** 600 + * gpiochip_fwd_gpio_set - Assign value to a GPIO forwarder line. 601 + * @fwd: GPIO forwarder 602 + * @offset: the offset of the line 603 + * @value: value to set 604 + * 605 + * Returns: 0 on success, or negative errno on failure. 606 + */ 607 + int gpiochip_fwd_gpio_set(struct gpiochip_fwd *fwd, unsigned int offset, int value) 608 + { 609 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 610 + 611 + return gpio_fwd_set(gc, offset, value); 612 + } 613 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_set, "GPIO_FORWARDER"); 614 + 615 + /** 616 + * gpiochip_fwd_gpio_set_multiple - Assign values to multiple GPIO forwarder lines 617 + * @fwd: GPIO forwarder 618 + * @mask: bit mask array; one bit per output; BITS_PER_LONG bits per word 619 + * defines which outputs are to be changed 620 + * @bits: bit value array; one bit per output; BITS_PER_LONG bits per word 621 + * defines the values the outputs specified by mask are to be set to 622 + * 623 + * Returns: 0 on success, or negative errno on failure. 624 + */ 625 + int gpiochip_fwd_gpio_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, 626 + unsigned long *bits) 627 + { 628 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 629 + 630 + return gpio_fwd_set_multiple_locked(gc, mask, bits); 631 + } 632 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_set_multiple, "GPIO_FORWARDER"); 633 + 634 + /** 635 + * gpiochip_fwd_gpio_set_config - Set @config for a GPIO forwarder line 636 + * @fwd: GPIO forwarder 637 + * @offset: the offset of the line 638 + * @config: Same packed config format as generic pinconf 639 + * 640 + * Returns: 0 on success, %-ENOTSUPP if the controller doesn't support setting 641 + * the configuration. 642 + */ 643 + int gpiochip_fwd_gpio_set_config(struct gpiochip_fwd *fwd, unsigned int offset, 644 + unsigned long config) 645 + { 646 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 647 + 648 + return gpio_fwd_set_config(gc, offset, config); 649 + } 650 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_set_config, "GPIO_FORWARDER"); 651 + 652 + /** 653 + * gpiochip_fwd_gpio_to_irq - Return the IRQ corresponding to a GPIO forwarder line 654 + * @fwd: GPIO forwarder 655 + * @offset: the offset of the line 656 + * 657 + * Returns: The Linux IRQ corresponding to the passed line, or an error code in 658 + * case of error. 659 + */ 660 + int gpiochip_fwd_gpio_to_irq(struct gpiochip_fwd *fwd, unsigned int offset) 661 + { 662 + struct gpio_chip *gc = gpiochip_fwd_get_gpiochip(fwd); 663 + 664 + return gpio_fwd_to_irq(gc, offset); 665 + } 666 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_gpio_to_irq, "GPIO_FORWARDER"); 667 + 668 + /** 669 + * devm_gpiochip_fwd_alloc - Allocate and initialize a new GPIO forwarder 670 + * @dev: Parent device pointer 671 + * @ngpios: Number of GPIOs in the forwarder 672 + * 673 + * Returns: An opaque object pointer, or an ERR_PTR()-encoded negative error 674 + * code on failure. 675 + */ 676 + struct gpiochip_fwd *devm_gpiochip_fwd_alloc(struct device *dev, 677 + unsigned int ngpios) 678 + { 679 + struct gpiochip_fwd *fwd; 680 + struct gpio_chip *chip; 681 + 682 + fwd = devm_kzalloc(dev, struct_size(fwd, tmp, fwd_tmp_size(ngpios)), GFP_KERNEL); 683 + if (!fwd) 684 + return ERR_PTR(-ENOMEM); 685 + 686 + fwd->descs = devm_kcalloc(dev, ngpios, sizeof(*fwd->descs), GFP_KERNEL); 687 + if (!fwd->descs) 688 + return ERR_PTR(-ENOMEM); 689 + 690 + fwd->valid_mask = devm_bitmap_zalloc(dev, ngpios, GFP_KERNEL); 691 + if (!fwd->valid_mask) 692 + return ERR_PTR(-ENOMEM); 693 + 694 + chip = &fwd->chip; 695 + 696 + chip->label = dev_name(dev); 697 + chip->parent = dev; 698 + chip->owner = THIS_MODULE; 699 + chip->request = gpio_fwd_request; 700 + chip->get_direction = gpio_fwd_get_direction; 701 + chip->direction_input = gpio_fwd_direction_input; 702 + chip->direction_output = gpio_fwd_direction_output; 703 + chip->get = gpio_fwd_get; 704 + chip->get_multiple = gpio_fwd_get_multiple_locked; 705 + chip->set = gpio_fwd_set; 706 + chip->set_multiple = gpio_fwd_set_multiple_locked; 707 + chip->to_irq = gpio_fwd_to_irq; 708 + chip->base = -1; 709 + chip->ngpio = ngpios; 710 + 711 + return fwd; 712 + } 713 + EXPORT_SYMBOL_NS_GPL(devm_gpiochip_fwd_alloc, "GPIO_FORWARDER"); 714 + 715 + /** 716 + * gpiochip_fwd_desc_add - Add a GPIO desc in the forwarder 717 + * @fwd: GPIO forwarder 718 + * @desc: GPIO descriptor to register 719 + * @offset: offset for the GPIO in the forwarder 720 + * 721 + * Returns: 0 on success, or negative errno on failure. 722 + */ 723 + int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd, struct gpio_desc *desc, 724 + unsigned int offset) 725 + { 726 + struct gpio_chip *chip = &fwd->chip; 727 + 728 + if (offset > chip->ngpio) 729 + return -EINVAL; 730 + 731 + if (test_and_set_bit(offset, fwd->valid_mask)) 732 + return -EEXIST; 733 + 734 + /* 735 + * If any of the GPIO lines are sleeping, then the entire forwarder 736 + * will be sleeping. 737 + */ 738 + if (gpiod_cansleep(desc)) 739 + chip->can_sleep = true; 740 + 741 + fwd->descs[offset] = desc; 742 + 743 + dev_dbg(chip->parent, "%u => gpio %d irq %d\n", offset, 744 + desc_to_gpio(desc), gpiod_to_irq(desc)); 745 + 746 + return 0; 747 + } 748 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_desc_add, "GPIO_FORWARDER"); 749 + 750 + /** 751 + * gpiochip_fwd_desc_free - Remove a GPIO desc from the forwarder 752 + * @fwd: GPIO forwarder 753 + * @offset: offset of GPIO desc to remove 754 + */ 755 + void gpiochip_fwd_desc_free(struct gpiochip_fwd *fwd, unsigned int offset) 756 + { 757 + if (test_and_clear_bit(offset, fwd->valid_mask)) 758 + gpiod_put(fwd->descs[offset]); 759 + } 760 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_desc_free, "GPIO_FORWARDER"); 761 + 762 + /** 763 + * gpiochip_fwd_register - Register a GPIO forwarder 764 + * @fwd: GPIO forwarder 765 + * @data: driver-private data associated with this forwarder 766 + * 767 + * Returns: 0 on success, or negative errno on failure. 768 + */ 769 + int gpiochip_fwd_register(struct gpiochip_fwd *fwd, void *data) 770 + { 771 + struct gpio_chip *chip = &fwd->chip; 772 + 773 + /* 774 + * Some gpio_desc were not registered. They will be registered at runtime 775 + * but we have to suppose they can sleep. 776 + */ 777 + if (!bitmap_full(fwd->valid_mask, chip->ngpio)) 778 + chip->can_sleep = true; 779 + 780 + if (chip->can_sleep) 781 + mutex_init(&fwd->mlock); 782 + else 783 + spin_lock_init(&fwd->slock); 784 + 785 + fwd->data = data; 786 + 787 + return devm_gpiochip_add_data(chip->parent, chip, fwd); 788 + } 789 + EXPORT_SYMBOL_NS_GPL(gpiochip_fwd_register, "GPIO_FORWARDER"); 790 + 791 + /** 498 792 * gpiochip_fwd_create() - Create a new GPIO forwarder 499 793 * @dev: Parent device pointer 500 794 * @ngpios: Number of GPIOs in the forwarder. 501 795 * @descs: Array containing the GPIO descriptors to forward to. 502 - * This array must contain @ngpios entries, and must not be deallocated 503 - * before the forwarder has been destroyed again. 796 + * This array must contain @ngpios entries, and can be deallocated 797 + * as the forwarder has its own array. 504 798 * @features: Bitwise ORed features as defined with FWD_FEATURE_*. 505 799 * 506 800 * This function creates a new gpiochip, which forwards all GPIO operations to ··· 827 495 struct gpio_desc *descs[], 828 496 unsigned long features) 829 497 { 830 - const char *label = dev_name(dev); 831 498 struct gpiochip_fwd *fwd; 832 - struct gpio_chip *chip; 833 499 unsigned int i; 834 500 int error; 835 501 836 - fwd = devm_kzalloc(dev, struct_size(fwd, tmp, fwd_tmp_size(ngpios)), 837 - GFP_KERNEL); 838 - if (!fwd) 839 - return ERR_PTR(-ENOMEM); 502 + fwd = devm_gpiochip_fwd_alloc(dev, ngpios); 503 + if (IS_ERR(fwd)) 504 + return fwd; 840 505 841 - chip = &fwd->chip; 842 - 843 - /* 844 - * If any of the GPIO lines are sleeping, then the entire forwarder 845 - * will be sleeping. 846 - * If any of the chips support .set_config(), then the forwarder will 847 - * support setting configs. 848 - */ 849 506 for (i = 0; i < ngpios; i++) { 850 - struct gpio_chip *parent = gpiod_to_chip(descs[i]); 851 - 852 - dev_dbg(dev, "%u => gpio %d irq %d\n", i, 853 - desc_to_gpio(descs[i]), gpiod_to_irq(descs[i])); 854 - 855 - if (gpiod_cansleep(descs[i])) 856 - chip->can_sleep = true; 857 - if (parent && parent->set_config) 858 - chip->set_config = gpio_fwd_set_config; 859 - } 860 - 861 - chip->label = label; 862 - chip->parent = dev; 863 - chip->owner = THIS_MODULE; 864 - chip->get_direction = gpio_fwd_get_direction; 865 - chip->direction_input = gpio_fwd_direction_input; 866 - chip->direction_output = gpio_fwd_direction_output; 867 - chip->get = gpio_fwd_get; 868 - chip->get_multiple = gpio_fwd_get_multiple_locked; 869 - chip->set = gpio_fwd_set; 870 - chip->set_multiple = gpio_fwd_set_multiple_locked; 871 - chip->to_irq = gpio_fwd_to_irq; 872 - chip->base = -1; 873 - chip->ngpio = ngpios; 874 - fwd->descs = descs; 875 - 876 - if (chip->can_sleep) 877 - mutex_init(&fwd->mlock); 878 - else 879 - spin_lock_init(&fwd->slock); 880 - 881 - if (features & FWD_FEATURE_DELAY) { 882 - error = gpiochip_fwd_setup_delay_line(dev, chip, fwd); 507 + error = gpiochip_fwd_desc_add(fwd, descs[i], i); 883 508 if (error) 884 509 return ERR_PTR(error); 885 510 } 886 511 887 - error = devm_gpiochip_add_data(dev, chip, fwd); 512 + if (features & FWD_FEATURE_DELAY) { 513 + error = gpiochip_fwd_setup_delay_line(fwd); 514 + if (error) 515 + return ERR_PTR(error); 516 + } 517 + 518 + error = gpiochip_fwd_register(fwd, NULL); 888 519 if (error) 889 520 return ERR_PTR(error); 890 521 ··· 1629 1334 return PTR_ERR(fwd); 1630 1335 1631 1336 platform_set_drvdata(pdev, fwd); 1337 + devm_kfree(dev, descs); 1632 1338 return 0; 1633 1339 } 1634 1340
+20 -9
drivers/gpio/gpiolib.c
··· 2349 2349 EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); 2350 2350 2351 2351 /** 2352 - * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping 2352 + * gpiochip_add_pin_range_with_pins() - add a range for GPIO <-> pin mapping 2353 2353 * @gc: the gpiochip to add the range for 2354 2354 * @pinctl_name: the dev_name() of the pin controller to map to 2355 2355 * @gpio_offset: the start offset in the current gpio_chip number space 2356 2356 * @pin_offset: the start offset in the pin controller number space 2357 + * @pins: the list of non consecutive pins to accumulate in this range (if not 2358 + * NULL, pin_offset is ignored by pinctrl core) 2357 2359 * @npins: the number of pins from the offset of each pin space (GPIO and 2358 2360 * pin controller) to accumulate in this range 2359 2361 * ··· 2367 2365 * Returns: 2368 2366 * 0 on success, or a negative errno on failure. 2369 2367 */ 2370 - int gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, 2371 - unsigned int gpio_offset, unsigned int pin_offset, 2372 - unsigned int npins) 2368 + int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc, 2369 + const char *pinctl_name, 2370 + unsigned int gpio_offset, 2371 + unsigned int pin_offset, 2372 + unsigned int const *pins, 2373 + unsigned int npins) 2373 2374 { 2374 2375 struct gpio_pin_range *pin_range; 2375 2376 struct gpio_device *gdev = gc->gpiodev; ··· 2390 2385 pin_range->range.name = gc->label; 2391 2386 pin_range->range.base = gdev->base + gpio_offset; 2392 2387 pin_range->range.pin_base = pin_offset; 2388 + pin_range->range.pins = pins; 2393 2389 pin_range->range.npins = npins; 2394 2390 pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, 2395 2391 &pin_range->range); ··· 2400 2394 kfree(pin_range); 2401 2395 return ret; 2402 2396 } 2403 - chip_dbg(gc, "created GPIO range %d->%d ==> %s PIN %d->%d\n", 2404 - gpio_offset, gpio_offset + npins - 1, 2405 - pinctl_name, 2406 - pin_offset, pin_offset + npins - 1); 2397 + if (pin_range->range.pins) 2398 + chip_dbg(gc, "created GPIO range %d->%d ==> %s %d sparse PIN range { %d, ... }", 2399 + gpio_offset, gpio_offset + npins - 1, 2400 + pinctl_name, npins, pins[0]); 2401 + else 2402 + chip_dbg(gc, "created GPIO range %d->%d ==> %s PIN %d->%d\n", 2403 + gpio_offset, gpio_offset + npins - 1, 2404 + pinctl_name, 2405 + pin_offset, pin_offset + npins - 1); 2407 2406 2408 2407 list_add_tail(&pin_range->node, &gdev->pin_ranges); 2409 2408 2410 2409 return 0; 2411 2410 } 2412 - EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); 2411 + EXPORT_SYMBOL_GPL(gpiochip_add_pin_range_with_pins); 2413 2412 2414 2413 /** 2415 2414 * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings
+48 -3
include/linux/gpio/driver.h
··· 772 772 773 773 #ifdef CONFIG_PINCTRL 774 774 775 - int gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, 776 - unsigned int gpio_offset, unsigned int pin_offset, 777 - unsigned int npins); 775 + int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc, 776 + const char *pinctl_name, 777 + unsigned int gpio_offset, 778 + unsigned int pin_offset, 779 + unsigned int const *pins, 780 + unsigned int npins); 778 781 int gpiochip_add_pingroup_range(struct gpio_chip *gc, 779 782 struct pinctrl_dev *pctldev, 780 783 unsigned int gpio_offset, const char *pin_group); 781 784 void gpiochip_remove_pin_ranges(struct gpio_chip *gc); 782 785 786 + static inline int 787 + gpiochip_add_pin_range(struct gpio_chip *gc, 788 + const char *pinctl_name, 789 + unsigned int gpio_offset, 790 + unsigned int pin_offset, 791 + unsigned int npins) 792 + { 793 + return gpiochip_add_pin_range_with_pins(gc, pinctl_name, gpio_offset, 794 + pin_offset, NULL, npins); 795 + } 796 + 797 + static inline int 798 + gpiochip_add_sparse_pin_range(struct gpio_chip *gc, 799 + const char *pinctl_name, 800 + unsigned int gpio_offset, 801 + unsigned int const *pins, 802 + unsigned int npins) 803 + { 804 + return gpiochip_add_pin_range_with_pins(gc, pinctl_name, gpio_offset, 0, 805 + pins, npins); 806 + } 783 807 #else /* ! CONFIG_PINCTRL */ 808 + 809 + static inline int 810 + gpiochip_add_pin_range_with_pins(struct gpio_chip *gc, 811 + const char *pinctl_name, 812 + unsigned int gpio_offset, 813 + unsigned int pin_offset, 814 + unsigned int npins) 815 + { 816 + return 0; 817 + } 784 818 785 819 static inline int 786 820 gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, ··· 823 789 { 824 790 return 0; 825 791 } 792 + 793 + static inline int 794 + gpiochip_add_sparse_pin_range(struct gpio_chip *gc, 795 + const char *pinctl_name, 796 + unsigned int gpio_offset, 797 + unsigned int const *pins, 798 + unsigned int npins) 799 + { 800 + return 0; 801 + } 802 + 826 803 static inline int 827 804 gpiochip_add_pingroup_range(struct gpio_chip *gc, 828 805 struct pinctrl_dev *pctldev,
+41
include/linux/gpio/forwarder.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __LINUX_GPIO_FORWARDER_H 3 + #define __LINUX_GPIO_FORWARDER_H 4 + 5 + struct gpio_desc; 6 + struct gpio_chip; 7 + struct gpiochip_fwd; 8 + 9 + struct gpiochip_fwd *devm_gpiochip_fwd_alloc(struct device *dev, 10 + unsigned int ngpios); 11 + int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd, 12 + struct gpio_desc *desc, unsigned int offset); 13 + void gpiochip_fwd_desc_free(struct gpiochip_fwd *fwd, unsigned int offset); 14 + int gpiochip_fwd_register(struct gpiochip_fwd *fwd, void *data); 15 + 16 + struct gpio_chip *gpiochip_fwd_get_gpiochip(struct gpiochip_fwd *fwd); 17 + 18 + void *gpiochip_fwd_get_data(struct gpiochip_fwd *fwd); 19 + 20 + int gpiochip_fwd_gpio_request(struct gpiochip_fwd *fwd, unsigned int offset); 21 + int gpiochip_fwd_gpio_get_direction(struct gpiochip_fwd *fwd, 22 + unsigned int offset); 23 + int gpiochip_fwd_gpio_direction_input(struct gpiochip_fwd *fwd, 24 + unsigned int offset); 25 + int gpiochip_fwd_gpio_direction_output(struct gpiochip_fwd *fwd, 26 + unsigned int offset, 27 + int value); 28 + int gpiochip_fwd_gpio_get(struct gpiochip_fwd *fwd, unsigned int offset); 29 + int gpiochip_fwd_gpio_get_multiple(struct gpiochip_fwd *fwd, 30 + unsigned long *mask, 31 + unsigned long *bits); 32 + int gpiochip_fwd_gpio_set(struct gpiochip_fwd *fwd, unsigned int offset, 33 + int value); 34 + int gpiochip_fwd_gpio_set_multiple(struct gpiochip_fwd *fwd, 35 + unsigned long *mask, 36 + unsigned long *bits); 37 + int gpiochip_fwd_gpio_set_config(struct gpiochip_fwd *fwd, unsigned int offset, 38 + unsigned long config); 39 + int gpiochip_fwd_gpio_to_irq(struct gpiochip_fwd *fwd, unsigned int offset); 40 + 41 + #endif
+6
include/linux/string_choices.h
··· 41 41 } 42 42 #define str_low_high(v) str_high_low(!(v)) 43 43 44 + static inline const char *str_input_output(bool v) 45 + { 46 + return v ? "input" : "output"; 47 + } 48 + #define str_output_input(v) str_input_output(!(v)) 49 + 44 50 static inline const char *str_on_off(bool v) 45 51 { 46 52 return v ? "on" : "off";