Skip to content

Commit fdeb8e1

Browse files
committed
gpio: reflect base and ngpio into gpio_device
Some information about the GPIO chip need to stay around also after the gpio_chip has been removed and only the gpio_device persist. The base and ngpio are such things, for example we don't want a new chip arriving to overlap the number space of a dangling gpio_device, and the chardev may still query the device for the number of lines etc. Note that the code that assigns base and insert gpio_device into the global list no longer check for a missing gpio_chip: we respect the number space allocated by any other gpio_device. As a consequence of the gdev being referenced directly from the gpio_desc, we need to verify it differently from all in-kernel API calls that fall through to direct queries to the gpio_chip vtable: we first check that desc is !NULL, then that desc->gdev is !NULL, then, if desc->gdev->chip is NULL, we *BAIL OUT* without any error, so as to manage the case where operations are requested on a device that is gone. These checks were non-uniform and partly missing in the past: so to simplify: create the macros VALIDATE_DESC() that will return -EINVAL if the desc or desc->gdev is missing and just 0 if the chip is gone, and conversely VALIDATE_DESC_VOID() for the case where the function does not return an error. By using these macros, we get warning messages about missing gdev with reference to the right function in the kernel log. Despite the macro business this simplifies the code and make it more readable than if we copy/paste the same descriptor checking code into all code ABI call sites (IMHO). Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 6cee382 commit fdeb8e1

File tree

3 files changed

+149
-130
lines changed

3 files changed

+149
-130
lines changed

drivers/gpio/gpiolib-sysfs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags)
180180
* Remove this redundant call (along with the corresponding
181181
* unlock) when those drivers have been fixed.
182182
*/
183-
ret = gpiochip_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc));
183+
ret = gpiochip_lock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
184184
if (ret < 0)
185185
goto err_put_kn;
186186

@@ -194,7 +194,7 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags)
194194
return 0;
195195

196196
err_unlock:
197-
gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc));
197+
gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
198198
err_put_kn:
199199
sysfs_put(data->value_kn);
200200

@@ -212,7 +212,7 @@ static void gpio_sysfs_free_irq(struct device *dev)
212212

213213
data->irq_flags = 0;
214214
free_irq(data->irq, data);
215-
gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc));
215+
gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
216216
sysfs_put(data->value_kn);
217217
}
218218

@@ -566,8 +566,8 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
566566
return -EINVAL;
567567
}
568568

569-
chip = desc->chip;
570-
gdev = chip->gpiodev;
569+
gdev = desc->gdev;
570+
chip = gdev->chip;
571571

572572
mutex_lock(&sysfs_lock);
573573

@@ -765,7 +765,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
765765

766766
/* unregister gpiod class devices owned by sysfs */
767767
for (i = 0; i < chip->ngpio; i++) {
768-
desc = &chip->gpiodev->descs[i];
768+
desc = &gdev->descs[i];
769769
if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
770770
gpiod_free(desc);
771771
}

0 commit comments

Comments
 (0)