Documentation: core-api/cpuhotplug: Rewrite the API section
[linux-2.6-microblaze.git] / drivers / gpio / gpiolib.c
index 27c0710..d1b9b72 100644 (file)
@@ -382,10 +382,18 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip)
        if (count < 0)
                return 0;
 
-       if (count > gdev->ngpio) {
-               dev_warn(&gdev->dev, "gpio-line-names is length %d but should be at most length %d",
-                        count, gdev->ngpio);
-               count = gdev->ngpio;
+       /*
+        * When offset is set in the driver side we assume the driver internally
+        * is using more than one gpiochip per the same device. We have to stop
+        * setting friendly names if the specified ones with 'gpio-line-names'
+        * are less than the offset in the device itself. This means all the
+        * lines are not present for every single pin within all the internal
+        * gpiochips.
+        */
+       if (count <= chip->offset) {
+               dev_warn(&gdev->dev, "gpio-line-names too short (length %d), cannot map names for the gpiochip at offset %u\n",
+                        count, chip->offset);
+               return 0;
        }
 
        names = kcalloc(count, sizeof(*names), GFP_KERNEL);
@@ -400,8 +408,22 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip)
                return ret;
        }
 
+       /*
+        * When more that one gpiochip per device is used, 'count' can
+        * contain at most number gpiochips x chip->ngpio. We have to
+        * correctly distribute all defined lines taking into account
+        * chip->offset as starting point from where we will assign
+        * the names to pins from the 'names' array. Since property
+        * 'gpio-line-names' cannot contains gaps, we have to be sure
+        * we only assign those pins that really exists since chip->ngpio
+        * can be different of the chip->offset.
+        */
+       count = (count > chip->offset) ? count - chip->offset : count;
+       if (count > chip->ngpio)
+               count = chip->ngpio;
+
        for (i = 0; i < count; i++)
-               gdev->descs[i].name = names[i];
+               gdev->descs[i].name = names[chip->offset + i];
 
        kfree(names);