blob: d56b367239ccbc3f115aca4716436964e1297be9 [file] [log] [blame]
Kent Gibson925ca362020-06-16 17:36:15 +08001// SPDX-License-Identifier: GPL-2.0
2
Kent Gibsond189f622020-07-08 12:15:45 +08003#include <linux/anon_inodes.h>
Kent Gibson925ca362020-06-16 17:36:15 +08004#include <linux/bitmap.h>
Kent Gibsond189f622020-07-08 12:15:45 +08005#include <linux/cdev.h>
6#include <linux/compat.h>
Kent Gibson925ca362020-06-16 17:36:15 +08007#include <linux/device.h>
8#include <linux/err.h>
Kent Gibsond189f622020-07-08 12:15:45 +08009#include <linux/file.h>
Kent Gibson925ca362020-06-16 17:36:15 +080010#include <linux/gpio.h>
11#include <linux/gpio/driver.h>
Kent Gibsond189f622020-07-08 12:15:45 +080012#include <linux/interrupt.h>
13#include <linux/irqreturn.h>
14#include <linux/kernel.h>
Kent Gibson925ca362020-06-16 17:36:15 +080015#include <linux/kfifo.h>
Kent Gibsond189f622020-07-08 12:15:45 +080016#include <linux/module.h>
17#include <linux/pinctrl/consumer.h>
Kent Gibson925ca362020-06-16 17:36:15 +080018#include <linux/poll.h>
Kent Gibsond189f622020-07-08 12:15:45 +080019#include <linux/spinlock.h>
Kent Gibson925ca362020-06-16 17:36:15 +080020#include <linux/timekeeping.h>
Kent Gibsond189f622020-07-08 12:15:45 +080021#include <linux/uaccess.h>
Kent Gibson925ca362020-06-16 17:36:15 +080022#include <uapi/linux/gpio.h>
23
24#include "gpiolib.h"
25#include "gpiolib-cdev.h"
26
27/* Character device interface to GPIO.
28 *
29 * The GPIO character device, /dev/gpiochipN, provides userspace an
30 * interface to gpiolib GPIOs via ioctl()s.
31 */
32
33/*
34 * GPIO line handle management
35 */
36
37/**
38 * struct linehandle_state - contains the state of a userspace handle
39 * @gdev: the GPIO device the handle pertains to
40 * @label: consumer label used to tag descriptors
41 * @descs: the GPIO descriptors held by this handle
Kent Gibson52b7b592020-07-08 12:15:49 +080042 * @num_descs: the number of descriptors held in the descs array
Kent Gibson925ca362020-06-16 17:36:15 +080043 */
44struct linehandle_state {
45 struct gpio_device *gdev;
46 const char *label;
47 struct gpio_desc *descs[GPIOHANDLES_MAX];
Kent Gibson52b7b592020-07-08 12:15:49 +080048 u32 num_descs;
Kent Gibson925ca362020-06-16 17:36:15 +080049};
50
51#define GPIOHANDLE_REQUEST_VALID_FLAGS \
52 (GPIOHANDLE_REQUEST_INPUT | \
53 GPIOHANDLE_REQUEST_OUTPUT | \
54 GPIOHANDLE_REQUEST_ACTIVE_LOW | \
55 GPIOHANDLE_REQUEST_BIAS_PULL_UP | \
56 GPIOHANDLE_REQUEST_BIAS_PULL_DOWN | \
57 GPIOHANDLE_REQUEST_BIAS_DISABLE | \
58 GPIOHANDLE_REQUEST_OPEN_DRAIN | \
59 GPIOHANDLE_REQUEST_OPEN_SOURCE)
60
61static int linehandle_validate_flags(u32 flags)
62{
63 /* Return an error if an unknown flag is set */
64 if (flags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
65 return -EINVAL;
66
67 /*
68 * Do not allow both INPUT & OUTPUT flags to be set as they are
69 * contradictory.
70 */
71 if ((flags & GPIOHANDLE_REQUEST_INPUT) &&
72 (flags & GPIOHANDLE_REQUEST_OUTPUT))
73 return -EINVAL;
74
75 /*
76 * Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
77 * the hardware actually supports enabling both at the same time the
78 * electrical result would be disastrous.
79 */
80 if ((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) &&
81 (flags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
82 return -EINVAL;
83
84 /* OPEN_DRAIN and OPEN_SOURCE flags only make sense for output mode. */
85 if (!(flags & GPIOHANDLE_REQUEST_OUTPUT) &&
86 ((flags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
87 (flags & GPIOHANDLE_REQUEST_OPEN_SOURCE)))
88 return -EINVAL;
89
90 /* Bias flags only allowed for input or output mode. */
91 if (!((flags & GPIOHANDLE_REQUEST_INPUT) ||
92 (flags & GPIOHANDLE_REQUEST_OUTPUT)) &&
93 ((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) ||
94 (flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP) ||
95 (flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN)))
96 return -EINVAL;
97
98 /* Only one bias flag can be set. */
99 if (((flags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
100 (flags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
Kent Gibsona18512e2020-07-08 12:15:46 +0800101 GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
Kent Gibson925ca362020-06-16 17:36:15 +0800102 ((flags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
103 (flags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
104 return -EINVAL;
105
106 return 0;
107}
108
Kent Gibsonc274b582020-07-08 12:15:47 +0800109static void linehandle_flags_to_desc_flags(u32 lflags, unsigned long *flagsp)
110{
111 assign_bit(FLAG_ACTIVE_LOW, flagsp,
112 lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW);
113 assign_bit(FLAG_OPEN_DRAIN, flagsp,
114 lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN);
115 assign_bit(FLAG_OPEN_SOURCE, flagsp,
116 lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE);
117 assign_bit(FLAG_PULL_UP, flagsp,
118 lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP);
119 assign_bit(FLAG_PULL_DOWN, flagsp,
120 lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN);
121 assign_bit(FLAG_BIAS_DISABLE, flagsp,
122 lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE);
123}
124
Kent Gibson925ca362020-06-16 17:36:15 +0800125static long linehandle_set_config(struct linehandle_state *lh,
126 void __user *ip)
127{
128 struct gpiohandle_config gcnf;
129 struct gpio_desc *desc;
130 int i, ret;
131 u32 lflags;
Kent Gibson925ca362020-06-16 17:36:15 +0800132
133 if (copy_from_user(&gcnf, ip, sizeof(gcnf)))
134 return -EFAULT;
135
136 lflags = gcnf.flags;
137 ret = linehandle_validate_flags(lflags);
138 if (ret)
139 return ret;
140
Kent Gibson52b7b592020-07-08 12:15:49 +0800141 for (i = 0; i < lh->num_descs; i++) {
Kent Gibson925ca362020-06-16 17:36:15 +0800142 desc = lh->descs[i];
Kent Gibsonc274b582020-07-08 12:15:47 +0800143 linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags);
Kent Gibson925ca362020-06-16 17:36:15 +0800144
145 /*
146 * Lines have to be requested explicitly for input
147 * or output, else the line will be treated "as is".
148 */
149 if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
150 int val = !!gcnf.default_values[i];
151
152 ret = gpiod_direction_output(desc, val);
153 if (ret)
154 return ret;
155 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
156 ret = gpiod_direction_input(desc);
157 if (ret)
158 return ret;
159 }
160
Kent Gibson6accc372020-07-08 12:15:51 +0800161 blocking_notifier_call_chain(&desc->gdev->notifier,
162 GPIOLINE_CHANGED_CONFIG, desc);
Kent Gibson925ca362020-06-16 17:36:15 +0800163 }
164 return 0;
165}
166
Kent Gibson49bc5272020-07-08 12:15:48 +0800167static long linehandle_ioctl(struct file *file, unsigned int cmd,
Kent Gibson925ca362020-06-16 17:36:15 +0800168 unsigned long arg)
169{
Kent Gibson49bc5272020-07-08 12:15:48 +0800170 struct linehandle_state *lh = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800171 void __user *ip = (void __user *)arg;
172 struct gpiohandle_data ghd;
173 DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
174 int i;
175
176 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
177 /* NOTE: It's ok to read values of output lines. */
178 int ret = gpiod_get_array_value_complex(false,
179 true,
Kent Gibson52b7b592020-07-08 12:15:49 +0800180 lh->num_descs,
Kent Gibson925ca362020-06-16 17:36:15 +0800181 lh->descs,
182 NULL,
183 vals);
184 if (ret)
185 return ret;
186
187 memset(&ghd, 0, sizeof(ghd));
Kent Gibson52b7b592020-07-08 12:15:49 +0800188 for (i = 0; i < lh->num_descs; i++)
Kent Gibson925ca362020-06-16 17:36:15 +0800189 ghd.values[i] = test_bit(i, vals);
190
191 if (copy_to_user(ip, &ghd, sizeof(ghd)))
192 return -EFAULT;
193
194 return 0;
195 } else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) {
196 /*
197 * All line descriptors were created at once with the same
198 * flags so just check if the first one is really output.
199 */
200 if (!test_bit(FLAG_IS_OUT, &lh->descs[0]->flags))
201 return -EPERM;
202
203 if (copy_from_user(&ghd, ip, sizeof(ghd)))
204 return -EFAULT;
205
206 /* Clamp all values to [0,1] */
Kent Gibson52b7b592020-07-08 12:15:49 +0800207 for (i = 0; i < lh->num_descs; i++)
Kent Gibson925ca362020-06-16 17:36:15 +0800208 __assign_bit(i, vals, ghd.values[i]);
209
210 /* Reuse the array setting function */
211 return gpiod_set_array_value_complex(false,
Kent Gibsona18512e2020-07-08 12:15:46 +0800212 true,
Kent Gibson52b7b592020-07-08 12:15:49 +0800213 lh->num_descs,
Kent Gibsona18512e2020-07-08 12:15:46 +0800214 lh->descs,
215 NULL,
216 vals);
Kent Gibson925ca362020-06-16 17:36:15 +0800217 } else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) {
218 return linehandle_set_config(lh, ip);
219 }
220 return -EINVAL;
221}
222
223#ifdef CONFIG_COMPAT
Kent Gibson49bc5272020-07-08 12:15:48 +0800224static long linehandle_ioctl_compat(struct file *file, unsigned int cmd,
Kent Gibsona18512e2020-07-08 12:15:46 +0800225 unsigned long arg)
Kent Gibson925ca362020-06-16 17:36:15 +0800226{
Kent Gibson49bc5272020-07-08 12:15:48 +0800227 return linehandle_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
Kent Gibson925ca362020-06-16 17:36:15 +0800228}
229#endif
230
Kent Gibson883f9192020-07-08 12:15:55 +0800231static void linehandle_free(struct linehandle_state *lh)
Kent Gibson925ca362020-06-16 17:36:15 +0800232{
Kent Gibson925ca362020-06-16 17:36:15 +0800233 int i;
234
Kent Gibson52b7b592020-07-08 12:15:49 +0800235 for (i = 0; i < lh->num_descs; i++)
Kent Gibson883f9192020-07-08 12:15:55 +0800236 if (lh->descs[i])
237 gpiod_free(lh->descs[i]);
Kent Gibson925ca362020-06-16 17:36:15 +0800238 kfree(lh->label);
Kent Gibson883f9192020-07-08 12:15:55 +0800239 put_device(&lh->gdev->dev);
Kent Gibson925ca362020-06-16 17:36:15 +0800240 kfree(lh);
Kent Gibson883f9192020-07-08 12:15:55 +0800241}
242
243static int linehandle_release(struct inode *inode, struct file *file)
244{
245 linehandle_free(file->private_data);
Kent Gibson925ca362020-06-16 17:36:15 +0800246 return 0;
247}
248
249static const struct file_operations linehandle_fileops = {
250 .release = linehandle_release,
251 .owner = THIS_MODULE,
252 .llseek = noop_llseek,
253 .unlocked_ioctl = linehandle_ioctl,
254#ifdef CONFIG_COMPAT
255 .compat_ioctl = linehandle_ioctl_compat,
256#endif
257};
258
259static int linehandle_create(struct gpio_device *gdev, void __user *ip)
260{
261 struct gpiohandle_request handlereq;
262 struct linehandle_state *lh;
263 struct file *file;
Kent Gibson883f9192020-07-08 12:15:55 +0800264 int fd, i, ret;
Kent Gibson925ca362020-06-16 17:36:15 +0800265 u32 lflags;
266
267 if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
268 return -EFAULT;
269 if ((handlereq.lines == 0) || (handlereq.lines > GPIOHANDLES_MAX))
270 return -EINVAL;
271
272 lflags = handlereq.flags;
273
274 ret = linehandle_validate_flags(lflags);
275 if (ret)
276 return ret;
277
278 lh = kzalloc(sizeof(*lh), GFP_KERNEL);
279 if (!lh)
280 return -ENOMEM;
281 lh->gdev = gdev;
282 get_device(&gdev->dev);
283
284 /* Make sure this is terminated */
285 handlereq.consumer_label[sizeof(handlereq.consumer_label)-1] = '\0';
286 if (strlen(handlereq.consumer_label)) {
287 lh->label = kstrdup(handlereq.consumer_label,
288 GFP_KERNEL);
289 if (!lh->label) {
290 ret = -ENOMEM;
291 goto out_free_lh;
292 }
293 }
294
Kent Gibson883f9192020-07-08 12:15:55 +0800295 lh->num_descs = handlereq.lines;
296
Kent Gibson925ca362020-06-16 17:36:15 +0800297 /* Request each GPIO */
298 for (i = 0; i < handlereq.lines; i++) {
299 u32 offset = handlereq.lineoffsets[i];
300 struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset);
301
302 if (IS_ERR(desc)) {
303 ret = PTR_ERR(desc);
Kent Gibson883f9192020-07-08 12:15:55 +0800304 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800305 }
306
307 ret = gpiod_request(desc, lh->label);
308 if (ret)
Kent Gibson883f9192020-07-08 12:15:55 +0800309 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800310 lh->descs[i] = desc;
Kent Gibsonc274b582020-07-08 12:15:47 +0800311 linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags);
Kent Gibson925ca362020-06-16 17:36:15 +0800312
313 ret = gpiod_set_transitory(desc, false);
314 if (ret < 0)
Kent Gibson883f9192020-07-08 12:15:55 +0800315 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800316
317 /*
318 * Lines have to be requested explicitly for input
319 * or output, else the line will be treated "as is".
320 */
321 if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
322 int val = !!handlereq.default_values[i];
323
324 ret = gpiod_direction_output(desc, val);
325 if (ret)
Kent Gibson883f9192020-07-08 12:15:55 +0800326 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800327 } else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
328 ret = gpiod_direction_input(desc);
329 if (ret)
Kent Gibson883f9192020-07-08 12:15:55 +0800330 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800331 }
332
Kent Gibson6accc372020-07-08 12:15:51 +0800333 blocking_notifier_call_chain(&desc->gdev->notifier,
334 GPIOLINE_CHANGED_REQUESTED, desc);
Kent Gibson925ca362020-06-16 17:36:15 +0800335
336 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n",
337 offset);
338 }
Kent Gibson925ca362020-06-16 17:36:15 +0800339
340 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
341 if (fd < 0) {
342 ret = fd;
Kent Gibson883f9192020-07-08 12:15:55 +0800343 goto out_free_lh;
Kent Gibson925ca362020-06-16 17:36:15 +0800344 }
345
346 file = anon_inode_getfile("gpio-linehandle",
347 &linehandle_fileops,
348 lh,
349 O_RDONLY | O_CLOEXEC);
350 if (IS_ERR(file)) {
351 ret = PTR_ERR(file);
352 goto out_put_unused_fd;
353 }
354
355 handlereq.fd = fd;
356 if (copy_to_user(ip, &handlereq, sizeof(handlereq))) {
357 /*
358 * fput() will trigger the release() callback, so do not go onto
359 * the regular error cleanup path here.
360 */
361 fput(file);
362 put_unused_fd(fd);
363 return -EFAULT;
364 }
365
366 fd_install(fd, file);
367
368 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
Kent Gibson52b7b592020-07-08 12:15:49 +0800369 lh->num_descs);
Kent Gibson925ca362020-06-16 17:36:15 +0800370
371 return 0;
372
373out_put_unused_fd:
374 put_unused_fd(fd);
Kent Gibson925ca362020-06-16 17:36:15 +0800375out_free_lh:
Kent Gibson883f9192020-07-08 12:15:55 +0800376 linehandle_free(lh);
Kent Gibson925ca362020-06-16 17:36:15 +0800377 return ret;
378}
379
380/*
381 * GPIO line event management
382 */
383
384/**
385 * struct lineevent_state - contains the state of a userspace event
386 * @gdev: the GPIO device the event pertains to
387 * @label: consumer label used to tag descriptors
388 * @desc: the GPIO descriptor held by this event
389 * @eflags: the event flags this line was requested with
390 * @irq: the interrupt that trigger in response to events on this GPIO
391 * @wait: wait queue that handles blocking reads of events
392 * @events: KFIFO for the GPIO events
393 * @timestamp: cache for the timestamp storing it between hardirq
394 * and IRQ thread, used to bring the timestamp close to the actual
395 * event
396 */
397struct lineevent_state {
398 struct gpio_device *gdev;
399 const char *label;
400 struct gpio_desc *desc;
401 u32 eflags;
402 int irq;
403 wait_queue_head_t wait;
404 DECLARE_KFIFO(events, struct gpioevent_data, 16);
405 u64 timestamp;
406};
407
408#define GPIOEVENT_REQUEST_VALID_FLAGS \
409 (GPIOEVENT_REQUEST_RISING_EDGE | \
410 GPIOEVENT_REQUEST_FALLING_EDGE)
411
Kent Gibson49bc5272020-07-08 12:15:48 +0800412static __poll_t lineevent_poll(struct file *file,
Kent Gibsona18512e2020-07-08 12:15:46 +0800413 struct poll_table_struct *wait)
Kent Gibson925ca362020-06-16 17:36:15 +0800414{
Kent Gibson49bc5272020-07-08 12:15:48 +0800415 struct lineevent_state *le = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800416 __poll_t events = 0;
417
Kent Gibson49bc5272020-07-08 12:15:48 +0800418 poll_wait(file, &le->wait, wait);
Kent Gibson925ca362020-06-16 17:36:15 +0800419
420 if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock))
421 events = EPOLLIN | EPOLLRDNORM;
422
423 return events;
424}
425
426
Kent Gibson49bc5272020-07-08 12:15:48 +0800427static ssize_t lineevent_read(struct file *file,
Kent Gibson925ca362020-06-16 17:36:15 +0800428 char __user *buf,
429 size_t count,
430 loff_t *f_ps)
431{
Kent Gibson49bc5272020-07-08 12:15:48 +0800432 struct lineevent_state *le = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800433 struct gpioevent_data ge;
434 ssize_t bytes_read = 0;
435 int ret;
436
437 if (count < sizeof(ge))
438 return -EINVAL;
439
440 do {
441 spin_lock(&le->wait.lock);
442 if (kfifo_is_empty(&le->events)) {
443 if (bytes_read) {
444 spin_unlock(&le->wait.lock);
445 return bytes_read;
446 }
447
Kent Gibson49bc5272020-07-08 12:15:48 +0800448 if (file->f_flags & O_NONBLOCK) {
Kent Gibson925ca362020-06-16 17:36:15 +0800449 spin_unlock(&le->wait.lock);
450 return -EAGAIN;
451 }
452
453 ret = wait_event_interruptible_locked(le->wait,
454 !kfifo_is_empty(&le->events));
455 if (ret) {
456 spin_unlock(&le->wait.lock);
457 return ret;
458 }
459 }
460
461 ret = kfifo_out(&le->events, &ge, 1);
462 spin_unlock(&le->wait.lock);
463 if (ret != 1) {
464 /*
465 * This should never happen - we were holding the lock
466 * from the moment we learned the fifo is no longer
467 * empty until now.
468 */
469 ret = -EIO;
470 break;
471 }
472
473 if (copy_to_user(buf + bytes_read, &ge, sizeof(ge)))
474 return -EFAULT;
475 bytes_read += sizeof(ge);
476 } while (count >= bytes_read + sizeof(ge));
477
478 return bytes_read;
479}
480
Kent Gibson49bc5272020-07-08 12:15:48 +0800481static int lineevent_release(struct inode *inode, struct file *file)
Kent Gibson925ca362020-06-16 17:36:15 +0800482{
Kent Gibson49bc5272020-07-08 12:15:48 +0800483 struct lineevent_state *le = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800484 struct gpio_device *gdev = le->gdev;
485
486 free_irq(le->irq, le);
487 gpiod_free(le->desc);
488 kfree(le->label);
489 kfree(le);
490 put_device(&gdev->dev);
491 return 0;
492}
493
Kent Gibson49bc5272020-07-08 12:15:48 +0800494static long lineevent_ioctl(struct file *file, unsigned int cmd,
Kent Gibson925ca362020-06-16 17:36:15 +0800495 unsigned long arg)
496{
Kent Gibson49bc5272020-07-08 12:15:48 +0800497 struct lineevent_state *le = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800498 void __user *ip = (void __user *)arg;
499 struct gpiohandle_data ghd;
500
501 /*
502 * We can get the value for an event line but not set it,
503 * because it is input by definition.
504 */
505 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
506 int val;
507
508 memset(&ghd, 0, sizeof(ghd));
509
510 val = gpiod_get_value_cansleep(le->desc);
511 if (val < 0)
512 return val;
513 ghd.values[0] = val;
514
515 if (copy_to_user(ip, &ghd, sizeof(ghd)))
516 return -EFAULT;
517
518 return 0;
519 }
520 return -EINVAL;
521}
522
523#ifdef CONFIG_COMPAT
Kent Gibson49bc5272020-07-08 12:15:48 +0800524static long lineevent_ioctl_compat(struct file *file, unsigned int cmd,
Kent Gibson925ca362020-06-16 17:36:15 +0800525 unsigned long arg)
526{
Kent Gibson49bc5272020-07-08 12:15:48 +0800527 return lineevent_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
Kent Gibson925ca362020-06-16 17:36:15 +0800528}
529#endif
530
531static const struct file_operations lineevent_fileops = {
532 .release = lineevent_release,
533 .read = lineevent_read,
534 .poll = lineevent_poll,
535 .owner = THIS_MODULE,
536 .llseek = noop_llseek,
537 .unlocked_ioctl = lineevent_ioctl,
538#ifdef CONFIG_COMPAT
539 .compat_ioctl = lineevent_ioctl_compat,
540#endif
541};
542
543static irqreturn_t lineevent_irq_thread(int irq, void *p)
544{
545 struct lineevent_state *le = p;
546 struct gpioevent_data ge;
547 int ret;
548
549 /* Do not leak kernel stack to userspace */
550 memset(&ge, 0, sizeof(ge));
551
552 /*
553 * We may be running from a nested threaded interrupt in which case
554 * we didn't get the timestamp from lineevent_irq_handler().
555 */
556 if (!le->timestamp)
557 ge.timestamp = ktime_get_ns();
558 else
559 ge.timestamp = le->timestamp;
560
561 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
562 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
563 int level = gpiod_get_value_cansleep(le->desc);
564
565 if (level)
566 /* Emit low-to-high event */
567 ge.id = GPIOEVENT_EVENT_RISING_EDGE;
568 else
569 /* Emit high-to-low event */
570 ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
571 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) {
572 /* Emit low-to-high event */
573 ge.id = GPIOEVENT_EVENT_RISING_EDGE;
574 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
575 /* Emit high-to-low event */
576 ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
577 } else {
578 return IRQ_NONE;
579 }
580
581 ret = kfifo_in_spinlocked_noirqsave(&le->events, &ge,
582 1, &le->wait.lock);
583 if (ret)
584 wake_up_poll(&le->wait, EPOLLIN);
585 else
586 pr_debug_ratelimited("event FIFO is full - event dropped\n");
587
588 return IRQ_HANDLED;
589}
590
591static irqreturn_t lineevent_irq_handler(int irq, void *p)
592{
593 struct lineevent_state *le = p;
594
595 /*
596 * Just store the timestamp in hardirq context so we get it as
597 * close in time as possible to the actual event.
598 */
599 le->timestamp = ktime_get_ns();
600
601 return IRQ_WAKE_THREAD;
602}
603
604static int lineevent_create(struct gpio_device *gdev, void __user *ip)
605{
606 struct gpioevent_request eventreq;
607 struct lineevent_state *le;
608 struct gpio_desc *desc;
609 struct file *file;
610 u32 offset;
611 u32 lflags;
612 u32 eflags;
613 int fd;
614 int ret;
615 int irqflags = 0;
616
617 if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
618 return -EFAULT;
619
620 offset = eventreq.lineoffset;
621 lflags = eventreq.handleflags;
622 eflags = eventreq.eventflags;
623
624 desc = gpiochip_get_desc(gdev->chip, offset);
625 if (IS_ERR(desc))
626 return PTR_ERR(desc);
627
628 /* Return an error if a unknown flag is set */
629 if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
630 (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS))
631 return -EINVAL;
632
633 /* This is just wrong: we don't look for events on output lines */
634 if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
635 (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
636 (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
637 return -EINVAL;
638
639 /* Only one bias flag can be set. */
640 if (((lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE) &&
641 (lflags & (GPIOHANDLE_REQUEST_BIAS_PULL_DOWN |
642 GPIOHANDLE_REQUEST_BIAS_PULL_UP))) ||
643 ((lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN) &&
644 (lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP)))
645 return -EINVAL;
646
647 le = kzalloc(sizeof(*le), GFP_KERNEL);
648 if (!le)
649 return -ENOMEM;
650 le->gdev = gdev;
651 get_device(&gdev->dev);
652
653 /* Make sure this is terminated */
654 eventreq.consumer_label[sizeof(eventreq.consumer_label)-1] = '\0';
655 if (strlen(eventreq.consumer_label)) {
656 le->label = kstrdup(eventreq.consumer_label,
657 GFP_KERNEL);
658 if (!le->label) {
659 ret = -ENOMEM;
660 goto out_free_le;
661 }
662 }
663
664 ret = gpiod_request(desc, le->label);
665 if (ret)
666 goto out_free_label;
667 le->desc = desc;
668 le->eflags = eflags;
669
Kent Gibsonc274b582020-07-08 12:15:47 +0800670 linehandle_flags_to_desc_flags(lflags, &desc->flags);
Kent Gibson925ca362020-06-16 17:36:15 +0800671
672 ret = gpiod_direction_input(desc);
673 if (ret)
674 goto out_free_desc;
675
Kent Gibson6accc372020-07-08 12:15:51 +0800676 blocking_notifier_call_chain(&desc->gdev->notifier,
677 GPIOLINE_CHANGED_REQUESTED, desc);
Kent Gibson925ca362020-06-16 17:36:15 +0800678
679 le->irq = gpiod_to_irq(desc);
680 if (le->irq <= 0) {
681 ret = -ENODEV;
682 goto out_free_desc;
683 }
684
685 if (eflags & GPIOEVENT_REQUEST_RISING_EDGE)
686 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
687 IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
688 if (eflags & GPIOEVENT_REQUEST_FALLING_EDGE)
689 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
690 IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
691 irqflags |= IRQF_ONESHOT;
692
693 INIT_KFIFO(le->events);
694 init_waitqueue_head(&le->wait);
695
696 /* Request a thread to read the events */
697 ret = request_threaded_irq(le->irq,
Kent Gibsona18512e2020-07-08 12:15:46 +0800698 lineevent_irq_handler,
699 lineevent_irq_thread,
700 irqflags,
701 le->label,
702 le);
Kent Gibson925ca362020-06-16 17:36:15 +0800703 if (ret)
704 goto out_free_desc;
705
706 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
707 if (fd < 0) {
708 ret = fd;
709 goto out_free_irq;
710 }
711
712 file = anon_inode_getfile("gpio-event",
713 &lineevent_fileops,
714 le,
715 O_RDONLY | O_CLOEXEC);
716 if (IS_ERR(file)) {
717 ret = PTR_ERR(file);
718 goto out_put_unused_fd;
719 }
720
721 eventreq.fd = fd;
722 if (copy_to_user(ip, &eventreq, sizeof(eventreq))) {
723 /*
724 * fput() will trigger the release() callback, so do not go onto
725 * the regular error cleanup path here.
726 */
727 fput(file);
728 put_unused_fd(fd);
729 return -EFAULT;
730 }
731
732 fd_install(fd, file);
733
734 return 0;
735
736out_put_unused_fd:
737 put_unused_fd(fd);
738out_free_irq:
739 free_irq(le->irq, le);
740out_free_desc:
741 gpiod_free(le->desc);
742out_free_label:
743 kfree(le->label);
744out_free_le:
745 kfree(le);
746 put_device(&gdev->dev);
747 return ret;
748}
749
750static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
751 struct gpioline_info *info)
752{
753 struct gpio_chip *gc = desc->gdev->chip;
754 bool ok_for_pinctrl;
755 unsigned long flags;
756
757 /*
758 * This function takes a mutex so we must check this before taking
759 * the spinlock.
760 *
761 * FIXME: find a non-racy way to retrieve this information. Maybe a
762 * lock common to both frameworks?
763 */
764 ok_for_pinctrl =
765 pinctrl_gpio_can_use_line(gc->base + info->line_offset);
766
767 spin_lock_irqsave(&gpio_lock, flags);
768
769 if (desc->name) {
770 strncpy(info->name, desc->name, sizeof(info->name));
771 info->name[sizeof(info->name) - 1] = '\0';
772 } else {
773 info->name[0] = '\0';
774 }
775
776 if (desc->label) {
777 strncpy(info->consumer, desc->label, sizeof(info->consumer));
778 info->consumer[sizeof(info->consumer) - 1] = '\0';
779 } else {
780 info->consumer[0] = '\0';
781 }
782
783 /*
784 * Userspace only need to know that the kernel is using this GPIO so
785 * it can't use it.
786 */
787 info->flags = 0;
788 if (test_bit(FLAG_REQUESTED, &desc->flags) ||
789 test_bit(FLAG_IS_HOGGED, &desc->flags) ||
790 test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
791 test_bit(FLAG_EXPORT, &desc->flags) ||
792 test_bit(FLAG_SYSFS, &desc->flags) ||
793 !ok_for_pinctrl)
794 info->flags |= GPIOLINE_FLAG_KERNEL;
795 if (test_bit(FLAG_IS_OUT, &desc->flags))
796 info->flags |= GPIOLINE_FLAG_IS_OUT;
797 if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
798 info->flags |= GPIOLINE_FLAG_ACTIVE_LOW;
799 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
800 info->flags |= (GPIOLINE_FLAG_OPEN_DRAIN |
801 GPIOLINE_FLAG_IS_OUT);
802 if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
803 info->flags |= (GPIOLINE_FLAG_OPEN_SOURCE |
804 GPIOLINE_FLAG_IS_OUT);
805 if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
806 info->flags |= GPIOLINE_FLAG_BIAS_DISABLE;
807 if (test_bit(FLAG_PULL_DOWN, &desc->flags))
808 info->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
809 if (test_bit(FLAG_PULL_UP, &desc->flags))
810 info->flags |= GPIOLINE_FLAG_BIAS_PULL_UP;
811
812 spin_unlock_irqrestore(&gpio_lock, flags);
813}
814
815struct gpio_chardev_data {
816 struct gpio_device *gdev;
817 wait_queue_head_t wait;
818 DECLARE_KFIFO(events, struct gpioline_info_changed, 32);
819 struct notifier_block lineinfo_changed_nb;
820 unsigned long *watched_lines;
821};
822
823/*
824 * gpio_ioctl() - ioctl handler for the GPIO chardev
825 */
Kent Gibson49bc5272020-07-08 12:15:48 +0800826static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Kent Gibson925ca362020-06-16 17:36:15 +0800827{
Kent Gibsone2b781c52020-07-08 12:15:52 +0800828 struct gpio_chardev_data *cdev = file->private_data;
829 struct gpio_device *gdev = cdev->gdev;
Kent Gibson925ca362020-06-16 17:36:15 +0800830 struct gpio_chip *gc = gdev->chip;
831 void __user *ip = (void __user *)arg;
832 struct gpio_desc *desc;
833 __u32 offset;
Kent Gibson925ca362020-06-16 17:36:15 +0800834
835 /* We fail any subsequent ioctl():s when the chip is gone */
836 if (!gc)
837 return -ENODEV;
838
839 /* Fill in the struct and pass to userspace */
840 if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
841 struct gpiochip_info chipinfo;
842
843 memset(&chipinfo, 0, sizeof(chipinfo));
844
845 strncpy(chipinfo.name, dev_name(&gdev->dev),
846 sizeof(chipinfo.name));
847 chipinfo.name[sizeof(chipinfo.name)-1] = '\0';
848 strncpy(chipinfo.label, gdev->label,
849 sizeof(chipinfo.label));
850 chipinfo.label[sizeof(chipinfo.label)-1] = '\0';
851 chipinfo.lines = gdev->ngpio;
852 if (copy_to_user(ip, &chipinfo, sizeof(chipinfo)))
853 return -EFAULT;
854 return 0;
855 } else if (cmd == GPIO_GET_LINEINFO_IOCTL) {
856 struct gpioline_info lineinfo;
857
858 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
859 return -EFAULT;
860
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800861 /* this doubles as a range check on line_offset */
Kent Gibson925ca362020-06-16 17:36:15 +0800862 desc = gpiochip_get_desc(gc, lineinfo.line_offset);
863 if (IS_ERR(desc))
864 return PTR_ERR(desc);
865
Kent Gibson925ca362020-06-16 17:36:15 +0800866 gpio_desc_to_lineinfo(desc, &lineinfo);
867
868 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo)))
869 return -EFAULT;
870 return 0;
871 } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
872 return linehandle_create(gdev, ip);
873 } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
874 return lineevent_create(gdev, ip);
875 } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
876 struct gpioline_info lineinfo;
877
878 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
879 return -EFAULT;
880
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800881 /* this doubles as a range check on line_offset */
Kent Gibson925ca362020-06-16 17:36:15 +0800882 desc = gpiochip_get_desc(gc, lineinfo.line_offset);
883 if (IS_ERR(desc))
884 return PTR_ERR(desc);
885
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800886 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines))
Kent Gibson925ca362020-06-16 17:36:15 +0800887 return -EBUSY;
888
889 gpio_desc_to_lineinfo(desc, &lineinfo);
890
Kent Gibsonf30ef3e2020-07-08 12:15:53 +0800891 if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800892 clear_bit(lineinfo.line_offset, cdev->watched_lines);
Kent Gibson925ca362020-06-16 17:36:15 +0800893 return -EFAULT;
Kent Gibsonf30ef3e2020-07-08 12:15:53 +0800894 }
Kent Gibson925ca362020-06-16 17:36:15 +0800895
Kent Gibson925ca362020-06-16 17:36:15 +0800896 return 0;
897 } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
898 if (copy_from_user(&offset, ip, sizeof(offset)))
899 return -EFAULT;
900
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800901 if (offset >= cdev->gdev->ngpio)
902 return -EINVAL;
Kent Gibson925ca362020-06-16 17:36:15 +0800903
Kent Gibson1bf7ba42020-07-08 12:15:54 +0800904 if (!test_and_clear_bit(offset, cdev->watched_lines))
Kent Gibson925ca362020-06-16 17:36:15 +0800905 return -EBUSY;
906
Kent Gibson925ca362020-06-16 17:36:15 +0800907 return 0;
908 }
909 return -EINVAL;
910}
911
912#ifdef CONFIG_COMPAT
Kent Gibson49bc5272020-07-08 12:15:48 +0800913static long gpio_ioctl_compat(struct file *file, unsigned int cmd,
Kent Gibson925ca362020-06-16 17:36:15 +0800914 unsigned long arg)
915{
Kent Gibson49bc5272020-07-08 12:15:48 +0800916 return gpio_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
Kent Gibson925ca362020-06-16 17:36:15 +0800917}
918#endif
919
920static struct gpio_chardev_data *
921to_gpio_chardev_data(struct notifier_block *nb)
922{
923 return container_of(nb, struct gpio_chardev_data, lineinfo_changed_nb);
924}
925
926static int lineinfo_changed_notify(struct notifier_block *nb,
927 unsigned long action, void *data)
928{
Kent Gibsone2b781c52020-07-08 12:15:52 +0800929 struct gpio_chardev_data *cdev = to_gpio_chardev_data(nb);
Kent Gibson925ca362020-06-16 17:36:15 +0800930 struct gpioline_info_changed chg;
931 struct gpio_desc *desc = data;
932 int ret;
933
Kent Gibsone2b781c52020-07-08 12:15:52 +0800934 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines))
Kent Gibson925ca362020-06-16 17:36:15 +0800935 return NOTIFY_DONE;
936
937 memset(&chg, 0, sizeof(chg));
938 chg.info.line_offset = gpio_chip_hwgpio(desc);
939 chg.event_type = action;
940 chg.timestamp = ktime_get_ns();
941 gpio_desc_to_lineinfo(desc, &chg.info);
942
Kent Gibsone2b781c52020-07-08 12:15:52 +0800943 ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock);
Kent Gibson925ca362020-06-16 17:36:15 +0800944 if (ret)
Kent Gibsone2b781c52020-07-08 12:15:52 +0800945 wake_up_poll(&cdev->wait, EPOLLIN);
Kent Gibson925ca362020-06-16 17:36:15 +0800946 else
947 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n");
948
949 return NOTIFY_OK;
950}
951
Kent Gibson49bc5272020-07-08 12:15:48 +0800952static __poll_t lineinfo_watch_poll(struct file *file,
Kent Gibson925ca362020-06-16 17:36:15 +0800953 struct poll_table_struct *pollt)
954{
Kent Gibsone2b781c52020-07-08 12:15:52 +0800955 struct gpio_chardev_data *cdev = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800956 __poll_t events = 0;
957
Kent Gibsone2b781c52020-07-08 12:15:52 +0800958 poll_wait(file, &cdev->wait, pollt);
Kent Gibson925ca362020-06-16 17:36:15 +0800959
Kent Gibsone2b781c52020-07-08 12:15:52 +0800960 if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events,
961 &cdev->wait.lock))
Kent Gibson925ca362020-06-16 17:36:15 +0800962 events = EPOLLIN | EPOLLRDNORM;
963
964 return events;
965}
966
Kent Gibson49bc5272020-07-08 12:15:48 +0800967static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
Kent Gibson925ca362020-06-16 17:36:15 +0800968 size_t count, loff_t *off)
969{
Kent Gibsone2b781c52020-07-08 12:15:52 +0800970 struct gpio_chardev_data *cdev = file->private_data;
Kent Gibson925ca362020-06-16 17:36:15 +0800971 struct gpioline_info_changed event;
972 ssize_t bytes_read = 0;
973 int ret;
974
975 if (count < sizeof(event))
976 return -EINVAL;
977
978 do {
Kent Gibsone2b781c52020-07-08 12:15:52 +0800979 spin_lock(&cdev->wait.lock);
980 if (kfifo_is_empty(&cdev->events)) {
Kent Gibson925ca362020-06-16 17:36:15 +0800981 if (bytes_read) {
Kent Gibsone2b781c52020-07-08 12:15:52 +0800982 spin_unlock(&cdev->wait.lock);
Kent Gibson925ca362020-06-16 17:36:15 +0800983 return bytes_read;
984 }
985
Kent Gibson49bc5272020-07-08 12:15:48 +0800986 if (file->f_flags & O_NONBLOCK) {
Kent Gibsone2b781c52020-07-08 12:15:52 +0800987 spin_unlock(&cdev->wait.lock);
Kent Gibson925ca362020-06-16 17:36:15 +0800988 return -EAGAIN;
989 }
990
Kent Gibsone2b781c52020-07-08 12:15:52 +0800991 ret = wait_event_interruptible_locked(cdev->wait,
992 !kfifo_is_empty(&cdev->events));
Kent Gibson925ca362020-06-16 17:36:15 +0800993 if (ret) {
Kent Gibsone2b781c52020-07-08 12:15:52 +0800994 spin_unlock(&cdev->wait.lock);
Kent Gibson925ca362020-06-16 17:36:15 +0800995 return ret;
996 }
997 }
998
Kent Gibsone2b781c52020-07-08 12:15:52 +0800999 ret = kfifo_out(&cdev->events, &event, 1);
1000 spin_unlock(&cdev->wait.lock);
Kent Gibson925ca362020-06-16 17:36:15 +08001001 if (ret != 1) {
1002 ret = -EIO;
1003 break;
1004 /* We should never get here. See lineevent_read(). */
1005 }
1006
1007 if (copy_to_user(buf + bytes_read, &event, sizeof(event)))
1008 return -EFAULT;
1009 bytes_read += sizeof(event);
1010 } while (count >= bytes_read + sizeof(event));
1011
1012 return bytes_read;
1013}
1014
1015/**
1016 * gpio_chrdev_open() - open the chardev for ioctl operations
1017 * @inode: inode for this chardev
Kent Gibson49bc5272020-07-08 12:15:48 +08001018 * @file: file struct for storing private data
Kent Gibson925ca362020-06-16 17:36:15 +08001019 * Returns 0 on success
1020 */
Kent Gibson49bc5272020-07-08 12:15:48 +08001021static int gpio_chrdev_open(struct inode *inode, struct file *file)
Kent Gibson925ca362020-06-16 17:36:15 +08001022{
1023 struct gpio_device *gdev = container_of(inode->i_cdev,
Kent Gibsona18512e2020-07-08 12:15:46 +08001024 struct gpio_device, chrdev);
Kent Gibsone2b781c52020-07-08 12:15:52 +08001025 struct gpio_chardev_data *cdev;
Kent Gibson925ca362020-06-16 17:36:15 +08001026 int ret = -ENOMEM;
1027
1028 /* Fail on open if the backing gpiochip is gone */
1029 if (!gdev->chip)
1030 return -ENODEV;
1031
Kent Gibsone2b781c52020-07-08 12:15:52 +08001032 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
1033 if (!cdev)
Kent Gibson925ca362020-06-16 17:36:15 +08001034 return -ENOMEM;
1035
Kent Gibsone2b781c52020-07-08 12:15:52 +08001036 cdev->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL);
1037 if (!cdev->watched_lines)
1038 goto out_free_cdev;
Kent Gibson925ca362020-06-16 17:36:15 +08001039
Kent Gibsone2b781c52020-07-08 12:15:52 +08001040 init_waitqueue_head(&cdev->wait);
1041 INIT_KFIFO(cdev->events);
1042 cdev->gdev = gdev;
Kent Gibson925ca362020-06-16 17:36:15 +08001043
Kent Gibsone2b781c52020-07-08 12:15:52 +08001044 cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify;
Kent Gibson6accc372020-07-08 12:15:51 +08001045 ret = blocking_notifier_chain_register(&gdev->notifier,
Kent Gibsone2b781c52020-07-08 12:15:52 +08001046 &cdev->lineinfo_changed_nb);
Kent Gibson925ca362020-06-16 17:36:15 +08001047 if (ret)
1048 goto out_free_bitmap;
1049
1050 get_device(&gdev->dev);
Kent Gibsone2b781c52020-07-08 12:15:52 +08001051 file->private_data = cdev;
Kent Gibson925ca362020-06-16 17:36:15 +08001052
Kent Gibson49bc5272020-07-08 12:15:48 +08001053 ret = nonseekable_open(inode, file);
Kent Gibson925ca362020-06-16 17:36:15 +08001054 if (ret)
1055 goto out_unregister_notifier;
1056
1057 return ret;
1058
1059out_unregister_notifier:
Kent Gibson6accc372020-07-08 12:15:51 +08001060 blocking_notifier_chain_unregister(&gdev->notifier,
Kent Gibsone2b781c52020-07-08 12:15:52 +08001061 &cdev->lineinfo_changed_nb);
Kent Gibson925ca362020-06-16 17:36:15 +08001062out_free_bitmap:
Kent Gibsone2b781c52020-07-08 12:15:52 +08001063 bitmap_free(cdev->watched_lines);
1064out_free_cdev:
1065 kfree(cdev);
Kent Gibson925ca362020-06-16 17:36:15 +08001066 return ret;
1067}
1068
1069/**
1070 * gpio_chrdev_release() - close chardev after ioctl operations
1071 * @inode: inode for this chardev
Kent Gibson49bc5272020-07-08 12:15:48 +08001072 * @file: file struct for storing private data
Kent Gibson925ca362020-06-16 17:36:15 +08001073 * Returns 0 on success
1074 */
Kent Gibson49bc5272020-07-08 12:15:48 +08001075static int gpio_chrdev_release(struct inode *inode, struct file *file)
Kent Gibson925ca362020-06-16 17:36:15 +08001076{
Kent Gibsone2b781c52020-07-08 12:15:52 +08001077 struct gpio_chardev_data *cdev = file->private_data;
1078 struct gpio_device *gdev = cdev->gdev;
Kent Gibson925ca362020-06-16 17:36:15 +08001079
Kent Gibsone2b781c52020-07-08 12:15:52 +08001080 bitmap_free(cdev->watched_lines);
Kent Gibson6accc372020-07-08 12:15:51 +08001081 blocking_notifier_chain_unregister(&gdev->notifier,
Kent Gibsone2b781c52020-07-08 12:15:52 +08001082 &cdev->lineinfo_changed_nb);
Kent Gibson925ca362020-06-16 17:36:15 +08001083 put_device(&gdev->dev);
Kent Gibsone2b781c52020-07-08 12:15:52 +08001084 kfree(cdev);
Kent Gibson925ca362020-06-16 17:36:15 +08001085
1086 return 0;
1087}
1088
1089static const struct file_operations gpio_fileops = {
1090 .release = gpio_chrdev_release,
1091 .open = gpio_chrdev_open,
1092 .poll = lineinfo_watch_poll,
1093 .read = lineinfo_watch_read,
1094 .owner = THIS_MODULE,
1095 .llseek = no_llseek,
1096 .unlocked_ioctl = gpio_ioctl,
1097#ifdef CONFIG_COMPAT
1098 .compat_ioctl = gpio_ioctl_compat,
1099#endif
1100};
1101
1102int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
1103{
1104 int ret;
1105
1106 cdev_init(&gdev->chrdev, &gpio_fileops);
1107 gdev->chrdev.owner = THIS_MODULE;
1108 gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id);
1109
1110 ret = cdev_device_add(&gdev->chrdev, &gdev->dev);
1111 if (ret)
1112 return ret;
1113
1114 chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n",
1115 MAJOR(devt), gdev->id);
1116
1117 return 0;
1118}
1119
1120void gpiolib_cdev_unregister(struct gpio_device *gdev)
1121{
1122 cdev_device_del(&gdev->chrdev, &gdev->dev);
1123}