From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> We're slowly removing cases of abuse of the GPIOLIB public API. One of the biggest issues is looking up and accessing struct gpio_chip whose life-time is tied to the provider and which can disappear from under any user at any given moment. We have provided new interfaces that use the opaque struct gpio_device which is reference counted and will soon be thorougly protected with appropriate locking. Stop using old interfaces in this driver and switch to safer alternatives. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> --- .../platform/x86/x86-android-tablets/core.c | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 2fd6060a31bb..687f84cd193c 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -12,6 +12,7 @@ #include <linux/acpi.h> #include <linux/dmi.h> +#include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/irq.h> @@ -21,27 +22,28 @@ #include <linux/string.h> #include "x86-android-tablets.h" -/* For gpiochip_get_desc() which is EXPORT_SYMBOL_GPL() */ -#include "../../../gpio/gpiolib.h" -#include "../../../gpio/gpiolib-acpi.h" - -static int gpiochip_find_match_label(struct gpio_chip *gc, void *data) -{ - return gc->label && !strcmp(gc->label, data); -} int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc) { + struct gpio_device *gdev; struct gpio_desc *gpiod; - struct gpio_chip *chip; - chip = gpiochip_find((void *)label, gpiochip_find_match_label); - if (!chip) { - pr_err("error cannot find GPIO chip %s\n", label); + /* + * FIXME: handle GPIOs correctly! This driver should really use struct + * device and GPIO lookup tables. + * + * WONTDO: We do leak this reference, but the whole approach to getting + * GPIOs in this driver is such an abuse of the GPIOLIB API that it + * doesn't make it much worse and it's the only way to keep the + * interrupt requested later functional... + */ + gdev = gpio_device_find_by_label(label); + if (!gdev) { + pr_err("error cannot find GPIO device %s\n", label); return -ENODEV; } - gpiod = gpiochip_get_desc(chip, pin); + gpiod = gpio_device_get_desc(gdev, pin); if (IS_ERR(gpiod)) { pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin); return PTR_ERR(gpiod); @@ -257,9 +259,9 @@ static void x86_android_tablet_cleanup(void) static __init int x86_android_tablet_init(void) { + struct gpio_device *gdev __free(gpio_device_put) = NULL; const struct x86_dev_info *dev_info; const struct dmi_system_id *id; - struct gpio_chip *chip; int i, ret = 0; id = dmi_first_match(x86_android_tablet_ids); @@ -273,13 +275,13 @@ static __init int x86_android_tablet_init(void) * _AEI (ACPI Event Interrupt) handlers, disable these. */ if (dev_info->invalid_aei_gpiochip) { - chip = gpiochip_find(dev_info->invalid_aei_gpiochip, - gpiochip_find_match_label); - if (!chip) { + gdev = gpio_device_find_by_label( + dev_info->invalid_aei_gpiochip); + if (!gdev) { pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip); return -ENODEV; } - acpi_gpiochip_free_interrupts(chip); + acpi_gpio_device_free_interrupts(gdev); } /* -- 2.39.2