mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 20:14:06 +02:00
gpio fixes for v6.19-rc7
- 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
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAmlzQPgACgkQBZ0uy/82
hMOVLBAAoRiX+SyZ2zXnsjqmgoUB4DdpeRLu7E4vgrB3mvSqdKfFLG76aPUO0S9H
QwYG5S8P/NoXNt7wJKoIc0jBiv+/P7leGIe7rEumg+uzfQ7dznIdXloPNttE9mB2
eaLQF3B1i/HtHKOSwJYtq5E8Pqxy0TU56SYMTbfJV7+ZpqhSv7z43lxSCIjXFPJ4
rhmn07rs1t6q/QGusdHyEk35kzYOGYhFkLdWuUnqVAw5/y2PDXU00YQ/r/av5CO4
K38WqDOpxl1/HCifQUYof89nUq5aysAHu80pUd3u7GsPZPaL9KZY8xuRdYIIlC8e
3Mr2KhgeKWrx8IrFizOoE4TnsXkLzD61JOQmHMnx9kXIRU1GcUdO9NS1CAxZABJ9
lO4mTa+QnYI4PDlsx0e0ixgShzu/HhhJhdLBmbRhUEsJNp1qlhisyNIBhkHxByJ7
bGXWxUOARccceSX8EkhcC0B1W24sTwH+1pjotzZRoCt0e1vD4cNU67nnIP23ApdC
j+ExPdj89pe9Hc7NlxkGNx7Z2eG9l8J3Tx2EkK4TIGnUplEqrZl3sXG9KEYxesFd
1dNPcv9C1qrVhquEGQHOYNfCH5nljvFq7cjE0H+TWXVvLVAgRhLpgVnxXSiFkjry
mC2VwVUcmvYti0T6vhvYb213XI/zMm0+7sOyRmjXrpG8nvQl7kk=
=/U+a
-----END PGP SIGNATURE-----
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
This commit is contained in:
commit
1f664bbd5f
|
|
@ -2549,6 +2549,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb,
|
|||
ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
|
||||
if (!ctx) {
|
||||
pr_err("Failed to allocate memory for line info notification\n");
|
||||
fput(fp);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
|
@ -2696,7 +2697,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
|
|||
|
||||
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
|
||||
if (!cdev)
|
||||
return -ENODEV;
|
||||
return -ENOMEM;
|
||||
|
||||
cdev->watched_lines = bitmap_zalloc(gdev->ngpio, GFP_KERNEL);
|
||||
if (!cdev->watched_lines)
|
||||
|
|
@ -2796,13 +2797,18 @@ int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
|
|||
return -ENOMEM;
|
||||
|
||||
ret = cdev_device_add(&gdev->chrdev, &gdev->dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
destroy_workqueue(gdev->line_state_wq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
guard(srcu)(&gdev->srcu);
|
||||
gc = srcu_dereference(gdev->chip, &gdev->srcu);
|
||||
if (!gc)
|
||||
if (!gc) {
|
||||
cdev_device_del(&gdev->chrdev, &gdev->dev);
|
||||
destroy_workqueue(gdev->line_state_wq);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id);
|
||||
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
|
|||
{
|
||||
struct gpio_shared_entry *entry;
|
||||
struct gpio_shared_ref *ref;
|
||||
unsigned long *flags;
|
||||
struct gpio_desc *desc;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(entry, &gpio_shared_list, list) {
|
||||
|
|
@ -543,15 +543,17 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
|
|||
if (list_count_nodes(&entry->refs) <= 1)
|
||||
continue;
|
||||
|
||||
flags = &gdev->descs[entry->offset].flags;
|
||||
desc = &gdev->descs[entry->offset];
|
||||
|
||||
__set_bit(GPIOD_FLAG_SHARED, flags);
|
||||
__set_bit(GPIOD_FLAG_SHARED, &desc->flags);
|
||||
/*
|
||||
* Shared GPIOs are not requested via the normal path. Make
|
||||
* them inaccessible to anyone even before we register the
|
||||
* chip.
|
||||
*/
|
||||
__set_bit(GPIOD_FLAG_REQUESTED, flags);
|
||||
ret = gpiod_request_commit(desc, "shared");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_debug("GPIO %u owned by %s is shared by multiple consumers\n",
|
||||
entry->offset, gpio_device_get_label(gdev));
|
||||
|
|
@ -562,8 +564,10 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
|
|||
ref->con_id ?: "(none)");
|
||||
|
||||
ret = gpio_shared_make_adev(gdev, entry, ref);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
gpiod_free_commit(desc);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -579,6 +583,8 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
|
|||
if (!device_match_fwnode(&gdev->dev, entry->fwnode))
|
||||
continue;
|
||||
|
||||
gpiod_free_commit(&gdev->descs[entry->offset]);
|
||||
|
||||
list_for_each_entry(ref, &entry->refs, list) {
|
||||
guard(mutex)(&ref->lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -2453,7 +2453,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
|
|||
* on each other, and help provide better diagnostics in debugfs.
|
||||
* They're called even less than the "set direction" calls.
|
||||
*/
|
||||
static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
|
||||
int gpiod_request_commit(struct gpio_desc *desc, const char *label)
|
||||
{
|
||||
unsigned int offset;
|
||||
int ret;
|
||||
|
|
@ -2515,7 +2515,7 @@ int gpiod_request(struct gpio_desc *desc, const char *label)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void gpiod_free_commit(struct gpio_desc *desc)
|
||||
void gpiod_free_commit(struct gpio_desc *desc)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -244,7 +244,9 @@ DEFINE_CLASS(gpio_chip_guard,
|
|||
struct gpio_desc *desc)
|
||||
|
||||
int gpiod_request(struct gpio_desc *desc, const char *label);
|
||||
int gpiod_request_commit(struct gpio_desc *desc, const char *label);
|
||||
void gpiod_free(struct gpio_desc *desc);
|
||||
void gpiod_free_commit(struct gpio_desc *desc);
|
||||
|
||||
static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user