Merge tag 'gpio-fixes-for-v6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:
"Some fixes to resource leaks in the character device handling and
another small fix for shared GPIO management:

- fix resource leaks in error paths in GPIO character device code

- return -ENOMEM and not -ENODEV on memory allocation failure

- fix an audio issue on Qualcomm platforms due to configuration not
being propagated to pinctrl from shared GPIO proxy"

* tag 'gpio-fixes-for-v6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpio: shared: propagate configuration to pinctrl
gpio: cdev: Fix resource leaks on errors in gpiolib_cdev_register()
gpio: cdev: Fix resource leaks on errors in lineinfo_changed_notify()
gpio: cdev: Correct return code on memory allocation failure

+24 -10
+9 -3
drivers/gpio/gpiolib-cdev.c
··· 2549 ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); 2550 if (!ctx) { 2551 pr_err("Failed to allocate memory for line info notification\n"); 2552 return NOTIFY_DONE; 2553 } 2554 ··· 2697 2698 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 2699 if (!cdev) 2700 - return -ENODEV; 2701 2702 cdev->watched_lines = bitmap_zalloc(gdev->ngpio, GFP_KERNEL); 2703 if (!cdev->watched_lines) ··· 2797 return -ENOMEM; 2798 2799 ret = cdev_device_add(&gdev->chrdev, &gdev->dev); 2800 - if (ret) 2801 return ret; 2802 2803 guard(srcu)(&gdev->srcu); 2804 gc = srcu_dereference(gdev->chip, &gdev->srcu); 2805 - if (!gc) 2806 return -ENODEV; 2807 2808 gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); 2809
··· 2549 ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); 2550 if (!ctx) { 2551 pr_err("Failed to allocate memory for line info notification\n"); 2552 + fput(fp); 2553 return NOTIFY_DONE; 2554 } 2555 ··· 2696 2697 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 2698 if (!cdev) 2699 + return -ENOMEM; 2700 2701 cdev->watched_lines = bitmap_zalloc(gdev->ngpio, GFP_KERNEL); 2702 if (!cdev->watched_lines) ··· 2796 return -ENOMEM; 2797 2798 ret = cdev_device_add(&gdev->chrdev, &gdev->dev); 2799 + if (ret) { 2800 + destroy_workqueue(gdev->line_state_wq); 2801 return ret; 2802 + } 2803 2804 guard(srcu)(&gdev->srcu); 2805 gc = srcu_dereference(gdev->chip, &gdev->srcu); 2806 + if (!gc) { 2807 + cdev_device_del(&gdev->chrdev, &gdev->dev); 2808 + destroy_workqueue(gdev->line_state_wq); 2809 return -ENODEV; 2810 + } 2811 2812 gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); 2813
+11 -5
drivers/gpio/gpiolib-shared.c
··· 515 { 516 struct gpio_shared_entry *entry; 517 struct gpio_shared_ref *ref; 518 - unsigned long *flags; 519 int ret; 520 521 list_for_each_entry(entry, &gpio_shared_list, list) { ··· 543 if (list_count_nodes(&entry->refs) <= 1) 544 continue; 545 546 - flags = &gdev->descs[entry->offset].flags; 547 548 - __set_bit(GPIOD_FLAG_SHARED, flags); 549 /* 550 * Shared GPIOs are not requested via the normal path. Make 551 * them inaccessible to anyone even before we register the 552 * chip. 553 */ 554 - __set_bit(GPIOD_FLAG_REQUESTED, flags); 555 556 pr_debug("GPIO %u owned by %s is shared by multiple consumers\n", 557 entry->offset, gpio_device_get_label(gdev)); ··· 564 ref->con_id ?: "(none)"); 565 566 ret = gpio_shared_make_adev(gdev, entry, ref); 567 - if (ret) 568 return ret; 569 } 570 } 571 ··· 582 list_for_each_entry(entry, &gpio_shared_list, list) { 583 if (!device_match_fwnode(&gdev->dev, entry->fwnode)) 584 continue; 585 586 list_for_each_entry(ref, &entry->refs, list) { 587 guard(mutex)(&ref->lock);
··· 515 { 516 struct gpio_shared_entry *entry; 517 struct gpio_shared_ref *ref; 518 + struct gpio_desc *desc; 519 int ret; 520 521 list_for_each_entry(entry, &gpio_shared_list, list) { ··· 543 if (list_count_nodes(&entry->refs) <= 1) 544 continue; 545 546 + desc = &gdev->descs[entry->offset]; 547 548 + __set_bit(GPIOD_FLAG_SHARED, &desc->flags); 549 /* 550 * Shared GPIOs are not requested via the normal path. Make 551 * them inaccessible to anyone even before we register the 552 * chip. 553 */ 554 + ret = gpiod_request_commit(desc, "shared"); 555 + if (ret) 556 + return ret; 557 558 pr_debug("GPIO %u owned by %s is shared by multiple consumers\n", 559 entry->offset, gpio_device_get_label(gdev)); ··· 562 ref->con_id ?: "(none)"); 563 564 ret = gpio_shared_make_adev(gdev, entry, ref); 565 + if (ret) { 566 + gpiod_free_commit(desc); 567 return ret; 568 + } 569 } 570 } 571 ··· 578 list_for_each_entry(entry, &gpio_shared_list, list) { 579 if (!device_match_fwnode(&gdev->dev, entry->fwnode)) 580 continue; 581 + 582 + gpiod_free_commit(&gdev->descs[entry->offset]); 583 584 list_for_each_entry(ref, &entry->refs, list) { 585 guard(mutex)(&ref->lock);
+2 -2
drivers/gpio/gpiolib.c
··· 2453 * on each other, and help provide better diagnostics in debugfs. 2454 * They're called even less than the "set direction" calls. 2455 */ 2456 - static int gpiod_request_commit(struct gpio_desc *desc, const char *label) 2457 { 2458 unsigned int offset; 2459 int ret; ··· 2515 return ret; 2516 } 2517 2518 - static void gpiod_free_commit(struct gpio_desc *desc) 2519 { 2520 unsigned long flags; 2521
··· 2453 * on each other, and help provide better diagnostics in debugfs. 2454 * They're called even less than the "set direction" calls. 2455 */ 2456 + int gpiod_request_commit(struct gpio_desc *desc, const char *label) 2457 { 2458 unsigned int offset; 2459 int ret; ··· 2515 return ret; 2516 } 2517 2518 + void gpiod_free_commit(struct gpio_desc *desc) 2519 { 2520 unsigned long flags; 2521
+2
drivers/gpio/gpiolib.h
··· 244 struct gpio_desc *desc) 245 246 int gpiod_request(struct gpio_desc *desc, const char *label); 247 void gpiod_free(struct gpio_desc *desc); 248 249 static inline int gpiod_request_user(struct gpio_desc *desc, const char *label) 250 {
··· 244 struct gpio_desc *desc) 245 246 int gpiod_request(struct gpio_desc *desc, const char *label); 247 + int gpiod_request_commit(struct gpio_desc *desc, const char *label); 248 void gpiod_free(struct gpio_desc *desc); 249 + void gpiod_free_commit(struct gpio_desc *desc); 250 251 static inline int gpiod_request_user(struct gpio_desc *desc, const char *label) 252 {