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

gpio: mmio: handle "ngpios" properly in bgpio_init()

bgpio_init() uses "sz" argument to populate ngpio, which is not
accurate. Instead, read the "ngpios" property from the DT and if it
doesn't exist, use the "sz" argument. With this change, drivers no
longer need to overwrite the ngpio variable after calling bgpio_init().

If the "ngpios" property is specified, bgpio_bits is calculated
as the round up value of ngpio. At the moment, the only requirement
specified is that the round up value must be a multiple of 8 but
it should also be a power of 2 because we provide accessors based
on the bank size in bgpio_setup_accessors().

Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

authored by

Asmaa Mnebhi and committed by
Bartosz Golaszewski
55b2395e 0f93a345

+46 -32
+8 -1
drivers/gpio/gpio-mmio.c
··· 60 60 #include <linux/of.h> 61 61 #include <linux/of_device.h> 62 62 63 + #include "gpiolib.h" 64 + 63 65 static void bgpio_write8(void __iomem *reg, unsigned long data) 64 66 { 65 67 writeb(data, reg); ··· 616 614 gc->parent = dev; 617 615 gc->label = dev_name(dev); 618 616 gc->base = -1; 619 - gc->ngpio = gc->bgpio_bits; 620 617 gc->request = bgpio_request; 621 618 gc->be_bits = !!(flags & BGPIOF_BIG_ENDIAN); 619 + 620 + ret = gpiochip_get_ngpios(gc, dev); 621 + if (ret) 622 + gc->ngpio = gc->bgpio_bits; 623 + else 624 + gc->bgpio_bits = roundup_pow_of_two(round_up(gc->ngpio, 8)); 622 625 623 626 ret = bgpio_setup_io(gc, dat, set, clr, flags); 624 627 if (ret)
+37 -31
drivers/gpio/gpiolib.c
··· 700 700 } 701 701 EXPORT_SYMBOL_GPL(gpiochip_get_data); 702 702 703 + int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev) 704 + { 705 + u32 ngpios = gc->ngpio; 706 + int ret; 707 + 708 + if (ngpios == 0) { 709 + ret = device_property_read_u32(dev, "ngpios", &ngpios); 710 + if (ret == -ENODATA) 711 + /* 712 + * -ENODATA means that there is no property found and 713 + * we want to issue the error message to the user. 714 + * Besides that, we want to return different error code 715 + * to state that supplied value is not valid. 716 + */ 717 + ngpios = 0; 718 + else if (ret) 719 + return ret; 720 + 721 + gc->ngpio = ngpios; 722 + } 723 + 724 + if (gc->ngpio == 0) { 725 + chip_err(gc, "tried to insert a GPIO chip with zero lines\n"); 726 + return -EINVAL; 727 + } 728 + 729 + if (gc->ngpio > FASTPATH_NGPIO) 730 + chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n", 731 + gc->ngpio, FASTPATH_NGPIO); 732 + 733 + return 0; 734 + } 735 + EXPORT_SYMBOL_GPL(gpiochip_get_ngpios); 736 + 703 737 int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, 704 738 struct lock_class_key *lock_key, 705 739 struct lock_class_key *request_key) ··· 741 707 struct gpio_device *gdev; 742 708 unsigned long flags; 743 709 unsigned int i; 744 - u32 ngpios = 0; 745 710 int base = 0; 746 711 int ret = 0; 747 712 ··· 786 753 else 787 754 gdev->owner = THIS_MODULE; 788 755 789 - /* 790 - * Try the device properties if the driver didn't supply the number 791 - * of GPIO lines. 792 - */ 793 - ngpios = gc->ngpio; 794 - if (ngpios == 0) { 795 - ret = device_property_read_u32(&gdev->dev, "ngpios", &ngpios); 796 - if (ret == -ENODATA) 797 - /* 798 - * -ENODATA means that there is no property found and 799 - * we want to issue the error message to the user. 800 - * Besides that, we want to return different error code 801 - * to state that supplied value is not valid. 802 - */ 803 - ngpios = 0; 804 - else if (ret) 805 - goto err_free_dev_name; 806 - 807 - gc->ngpio = ngpios; 808 - } 809 - 810 - if (gc->ngpio == 0) { 811 - chip_err(gc, "tried to insert a GPIO chip with zero lines\n"); 812 - ret = -EINVAL; 756 + ret = gpiochip_get_ngpios(gc, &gdev->dev); 757 + if (ret) 813 758 goto err_free_dev_name; 814 - } 815 - 816 - if (gc->ngpio > FASTPATH_NGPIO) 817 - chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n", 818 - gc->ngpio, FASTPATH_NGPIO); 819 759 820 760 gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL); 821 761 if (!gdev->descs) { ··· 953 947 /* failures here can mean systems won't boot... */ 954 948 if (ret != -EPROBE_DEFER) { 955 949 pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__, 956 - base, base + (int)ngpios - 1, 950 + base, base + (int)gc->ngpio - 1, 957 951 gc->label ? : "generic", ret); 958 952 } 959 953 return ret;
+1
drivers/gpio/gpiolib.h
··· 218 218 int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce); 219 219 int gpiod_hog(struct gpio_desc *desc, const char *name, 220 220 unsigned long lflags, enum gpiod_flags dflags); 221 + int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev); 221 222 222 223 /* 223 224 * Return the GPIO number of the passed descriptor relative to its chip