Loading drivers/gpio/gpiolib-cdev.c +21 −45 Original line number Diff line number Diff line Loading @@ -298,12 +298,13 @@ static const struct file_operations linehandle_fileops = { #endif }; DEFINE_FREE(linehandle_free, struct linehandle_state *, if (!IS_ERR_OR_NULL(_T)) linehandle_free(_T)) static int linehandle_create(struct gpio_device *gdev, void __user *ip) { struct gpiohandle_request handlereq; struct linehandle_state *lh; struct file *file; int fd, i, ret; struct linehandle_state *lh __free(linehandle_free) = NULL; int i, ret; u32 lflags; if (copy_from_user(&handlereq, ip, sizeof(handlereq))) Loading @@ -327,10 +328,8 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) lh->label = kstrndup(handlereq.consumer_label, sizeof(handlereq.consumer_label) - 1, GFP_KERNEL); if (!lh->label) { ret = -ENOMEM; goto out_free_lh; } if (!lh->label) return -ENOMEM; } lh->num_descs = handlereq.lines; Loading @@ -340,20 +339,18 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) u32 offset = handlereq.lineoffsets[i]; struct gpio_desc *desc = gpio_device_get_desc(gdev, offset); if (IS_ERR(desc)) { ret = PTR_ERR(desc); goto out_free_lh; } if (IS_ERR(desc)) return PTR_ERR(desc); ret = gpiod_request_user(desc, lh->label); if (ret) goto out_free_lh; return ret; lh->descs[i] = desc; linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags); ret = gpiod_set_transitory(desc, false); if (ret < 0) goto out_free_lh; return ret; /* * Lines have to be requested explicitly for input Loading @@ -364,11 +361,11 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ret = gpiod_direction_output_nonotify(desc, val); if (ret) goto out_free_lh; return ret; } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { ret = gpiod_direction_input_nonotify(desc); if (ret) goto out_free_lh; return ret; } gpiod_line_state_notify(desc, GPIO_V2_LINE_CHANGED_REQUESTED); Loading @@ -377,44 +374,23 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) offset); } fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); if (fd < 0) { ret = fd; goto out_free_lh; } FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC, anon_inode_getfile("gpio-linehandle", &linehandle_fileops, lh, O_RDONLY | O_CLOEXEC)); if (fdf.err) return fdf.err; retain_and_null_ptr(lh); file = anon_inode_getfile("gpio-linehandle", &linehandle_fileops, lh, O_RDONLY | O_CLOEXEC); if (IS_ERR(file)) { ret = PTR_ERR(file); goto out_put_unused_fd; } handlereq.fd = fd; if (copy_to_user(ip, &handlereq, sizeof(handlereq))) { /* * fput() will trigger the release() callback, so do not go onto * the regular error cleanup path here. */ fput(file); put_unused_fd(fd); handlereq.fd = fd_prepare_fd(fdf); if (copy_to_user(ip, &handlereq, sizeof(handlereq))) return -EFAULT; } fd_install(fd, file); fd_publish(fdf); dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", lh->num_descs); return 0; out_put_unused_fd: put_unused_fd(fd); out_free_lh: linehandle_free(lh); return ret; } #endif /* CONFIG_GPIO_CDEV_V1 */ Loading Loading
drivers/gpio/gpiolib-cdev.c +21 −45 Original line number Diff line number Diff line Loading @@ -298,12 +298,13 @@ static const struct file_operations linehandle_fileops = { #endif }; DEFINE_FREE(linehandle_free, struct linehandle_state *, if (!IS_ERR_OR_NULL(_T)) linehandle_free(_T)) static int linehandle_create(struct gpio_device *gdev, void __user *ip) { struct gpiohandle_request handlereq; struct linehandle_state *lh; struct file *file; int fd, i, ret; struct linehandle_state *lh __free(linehandle_free) = NULL; int i, ret; u32 lflags; if (copy_from_user(&handlereq, ip, sizeof(handlereq))) Loading @@ -327,10 +328,8 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) lh->label = kstrndup(handlereq.consumer_label, sizeof(handlereq.consumer_label) - 1, GFP_KERNEL); if (!lh->label) { ret = -ENOMEM; goto out_free_lh; } if (!lh->label) return -ENOMEM; } lh->num_descs = handlereq.lines; Loading @@ -340,20 +339,18 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) u32 offset = handlereq.lineoffsets[i]; struct gpio_desc *desc = gpio_device_get_desc(gdev, offset); if (IS_ERR(desc)) { ret = PTR_ERR(desc); goto out_free_lh; } if (IS_ERR(desc)) return PTR_ERR(desc); ret = gpiod_request_user(desc, lh->label); if (ret) goto out_free_lh; return ret; lh->descs[i] = desc; linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags); ret = gpiod_set_transitory(desc, false); if (ret < 0) goto out_free_lh; return ret; /* * Lines have to be requested explicitly for input Loading @@ -364,11 +361,11 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ret = gpiod_direction_output_nonotify(desc, val); if (ret) goto out_free_lh; return ret; } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { ret = gpiod_direction_input_nonotify(desc); if (ret) goto out_free_lh; return ret; } gpiod_line_state_notify(desc, GPIO_V2_LINE_CHANGED_REQUESTED); Loading @@ -377,44 +374,23 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) offset); } fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); if (fd < 0) { ret = fd; goto out_free_lh; } FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC, anon_inode_getfile("gpio-linehandle", &linehandle_fileops, lh, O_RDONLY | O_CLOEXEC)); if (fdf.err) return fdf.err; retain_and_null_ptr(lh); file = anon_inode_getfile("gpio-linehandle", &linehandle_fileops, lh, O_RDONLY | O_CLOEXEC); if (IS_ERR(file)) { ret = PTR_ERR(file); goto out_put_unused_fd; } handlereq.fd = fd; if (copy_to_user(ip, &handlereq, sizeof(handlereq))) { /* * fput() will trigger the release() callback, so do not go onto * the regular error cleanup path here. */ fput(file); put_unused_fd(fd); handlereq.fd = fd_prepare_fd(fdf); if (copy_to_user(ip, &handlereq, sizeof(handlereq))) return -EFAULT; } fd_install(fd, file); fd_publish(fdf); dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", lh->num_descs); return 0; out_put_unused_fd: put_unused_fd(fd); out_free_lh: linehandle_free(lh); return ret; } #endif /* CONFIG_GPIO_CDEV_V1 */ Loading