Re: [PATCH] gpio: allocate dynamic gpio numbers top down

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 29. 03. 22 10:52, Sascha Hauer wrote:
For GPIO controllers with dynamic GPIO number bases a free base
is searched for bottom up. This means that GPIO controllers with
fixed GPIO numbers must be registered before any controller with
dynamic GPIO number base is registered, because otherwise the
GPIO controllers with fixed GPIO numbers find their range occupied
and can't be registered anymore.

The probe order normally makes sure the SoC internal GPIO controllers
with fixed numbers are registered first. With deep probe enabled
we can't rely on the probe order anymore, so we need another solution.

With this patch a free GPIO number range is searched for top down
intead of bottom up, so as long as we have enough space in the
ARCH_NR_GPIOS range the SoC internal GPIO controllers find their
base unoccupied. GPIO controllers with dynamic GPIO numbers will
change their numbers with this patch, but code shouldn't rely on
these numbers anyway.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>

Tested on PHYTEC Mira and Nunki board. If you want you can add:
Tested-by: Andrej Picej <andrej.picej@xxxxxxxxx>

Thanks.
---
  drivers/gpio/gpiolib.c | 26 +++++++++++++-------------
  1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f709d11f75..c9b33bcd6c 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -414,22 +414,19 @@ free_array:
  }
  EXPORT_SYMBOL(gpio_array_to_id);
-static int gpiochip_find_base(int start, int ngpio)
+static int gpiochip_find_base(int ngpio)
  {
  	int i;
  	int spare = 0;
  	int base = -ENOSPC;
- if (start < 0)
-		start = 0;
-
-	for (i = start; i < ARCH_NR_GPIOS; i++) {
+	for (i = ARCH_NR_GPIOS - 1; i >= 0; i--) {
  		struct gpio_chip *chip = gpio_desc[i].chip;
if (!chip) {
  			spare++;
  			if (spare == ngpio) {
-				base = i + 1 - ngpio;
+				base = i;
  				break;
  			}
  		} else {
@@ -614,14 +611,17 @@ int gpiochip_add(struct gpio_chip *chip)
  {
  	int base, i;
- base = gpiochip_find_base(chip->base, chip->ngpio);
-	if (base < 0)
-		return base;
-
-	if (chip->base >= 0 && chip->base != base)
-		return -EBUSY;
+	if (chip->base >= 0) {
+		for (i = 0; i < chip->ngpio; i++) {
+			if (gpio_desc[chip->base + i].chip)
+				return -EBUSY;
+		}
+	} else {
+		chip->base = gpiochip_find_base(chip->ngpio);
+		if (chip->base < 0)
+			return -ENOSPC;
+	}
- chip->base = base; list_add_tail(&chip->list, &chip_list);

_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux