Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Configurable virtual GPIO consumer module.
4 *
5 * Copyright (C) 2023-2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
6 */
7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10#include <linux/array_size.h>
11#include <linux/atomic.h>
12#include <linux/bitmap.h>
13#include <linux/cleanup.h>
14#include <linux/configfs.h>
15#include <linux/debugfs.h>
16#include <linux/device.h>
17#include <linux/err.h>
18#include <linux/gpio/consumer.h>
19#include <linux/gpio/machine.h>
20#include <linux/idr.h>
21#include <linux/interrupt.h>
22#include <linux/irq_work.h>
23#include <linux/limits.h>
24#include <linux/list.h>
25#include <linux/lockdep.h>
26#include <linux/mod_devicetable.h>
27#include <linux/module.h>
28#include <linux/mutex.h>
29#include <linux/notifier.h>
30#include <linux/of.h>
31#include <linux/overflow.h>
32#include <linux/platform_device.h>
33#include <linux/printk.h>
34#include <linux/property.h>
35#include <linux/slab.h>
36#include <linux/string_helpers.h>
37#include <linux/types.h>
38
39#include "dev-sync-probe.h"
40
41#define GPIO_VIRTUSER_NAME_BUF_LEN 32
42
43static DEFINE_IDA(gpio_virtuser_ida);
44static struct dentry *gpio_virtuser_dbg_root;
45
46struct gpio_virtuser_attr_data {
47 union {
48 struct gpio_desc *desc;
49 struct gpio_descs *descs;
50 };
51 struct dentry *dbgfs_dir;
52};
53
54struct gpio_virtuser_line_array_data {
55 struct gpio_virtuser_attr_data ad;
56};
57
58struct gpio_virtuser_line_data {
59 struct gpio_virtuser_attr_data ad;
60 char consumer[GPIO_VIRTUSER_NAME_BUF_LEN];
61 struct mutex consumer_lock;
62 unsigned int debounce;
63 atomic_t irq;
64 atomic_t irq_count;
65};
66
67struct gpio_virtuser_dbgfs_attr_descr {
68 const char *name;
69 const struct file_operations *fops;
70};
71
72struct gpio_virtuser_irq_work_context {
73 struct irq_work work;
74 struct completion work_completion;
75 union {
76 struct {
77 struct gpio_desc *desc;
78 int dir;
79 int val;
80 int ret;
81 };
82 struct {
83 struct gpio_descs *descs;
84 unsigned long *values;
85 };
86 };
87};
88
89static struct gpio_virtuser_irq_work_context *
90to_gpio_virtuser_irq_work_context(struct irq_work *work)
91{
92 return container_of(work, struct gpio_virtuser_irq_work_context, work);
93}
94
95static void
96gpio_virtuser_init_irq_work_context(struct gpio_virtuser_irq_work_context *ctx)
97{
98 memset(ctx, 0, sizeof(*ctx));
99 init_completion(&ctx->work_completion);
100}
101
102static void
103gpio_virtuser_irq_work_queue_sync(struct gpio_virtuser_irq_work_context *ctx)
104{
105 irq_work_queue(&ctx->work);
106 wait_for_completion(&ctx->work_completion);
107}
108
109static void gpio_virtuser_dbgfs_emit_value_array(char *buf,
110 unsigned long *values,
111 size_t num_values)
112{
113 size_t i;
114
115 for (i = 0; i < num_values; i++)
116 buf[i] = test_bit(i, values) ? '1' : '0';
117
118 buf[i++] = '\n';
119}
120
121static void gpio_virtuser_get_value_array_atomic(struct irq_work *work)
122{
123 struct gpio_virtuser_irq_work_context *ctx =
124 to_gpio_virtuser_irq_work_context(work);
125 struct gpio_descs *descs = ctx->descs;
126
127 ctx->ret = gpiod_get_array_value(descs->ndescs, descs->desc,
128 descs->info, ctx->values);
129 complete(&ctx->work_completion);
130}
131
132static int gpio_virtuser_get_array_value(struct gpio_descs *descs,
133 unsigned long *values, bool atomic)
134{
135 struct gpio_virtuser_irq_work_context ctx;
136
137 if (!atomic)
138 return gpiod_get_array_value_cansleep(descs->ndescs,
139 descs->desc,
140 descs->info, values);
141
142 gpio_virtuser_init_irq_work_context(&ctx);
143 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_get_value_array_atomic);
144 ctx.descs = descs;
145 ctx.values = values;
146
147 gpio_virtuser_irq_work_queue_sync(&ctx);
148
149 return ctx.ret;
150}
151
152static ssize_t gpio_virtuser_value_array_do_read(struct file *file,
153 char __user *user_buf,
154 size_t size, loff_t *ppos,
155 bool atomic)
156{
157 struct gpio_virtuser_line_data *data = file->private_data;
158 struct gpio_descs *descs = data->ad.descs;
159 size_t bufsize;
160 int ret;
161
162 unsigned long *values __free(bitmap) = bitmap_zalloc(descs->ndescs,
163 GFP_KERNEL);
164 if (!values)
165 return -ENOMEM;
166
167 ret = gpio_virtuser_get_array_value(descs, values, atomic);
168 if (ret)
169 return ret;
170
171 bufsize = descs->ndescs + 2;
172
173 char *buf __free(kfree) = kzalloc(bufsize, GFP_KERNEL);
174 if (!buf)
175 return -ENOMEM;
176
177 gpio_virtuser_dbgfs_emit_value_array(buf, values, descs->ndescs);
178
179 return simple_read_from_buffer(user_buf, size, ppos, buf,
180 descs->ndescs + 1);
181}
182
183static int gpio_virtuser_dbgfs_parse_value_array(const char *buf,
184 size_t len,
185 unsigned long *values)
186{
187 size_t i;
188
189 for (i = 0; i < len; i++) {
190 if (buf[i] == '0')
191 clear_bit(i, values);
192 else if (buf[i] == '1')
193 set_bit(i, values);
194 else
195 return -EINVAL;
196 }
197
198 return 0;
199}
200
201static void gpio_virtuser_set_value_array_atomic(struct irq_work *work)
202{
203 struct gpio_virtuser_irq_work_context *ctx =
204 to_gpio_virtuser_irq_work_context(work);
205 struct gpio_descs *descs = ctx->descs;
206
207 ctx->ret = gpiod_set_array_value(descs->ndescs, descs->desc,
208 descs->info, ctx->values);
209 complete(&ctx->work_completion);
210}
211
212static int gpio_virtuser_set_array_value(struct gpio_descs *descs,
213 unsigned long *values, bool atomic)
214{
215 struct gpio_virtuser_irq_work_context ctx;
216
217 if (!atomic)
218 return gpiod_set_array_value_cansleep(descs->ndescs,
219 descs->desc,
220 descs->info, values);
221
222 gpio_virtuser_init_irq_work_context(&ctx);
223 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_set_value_array_atomic);
224 ctx.descs = descs;
225 ctx.values = values;
226
227 gpio_virtuser_irq_work_queue_sync(&ctx);
228
229 return ctx.ret;
230}
231
232static ssize_t gpio_virtuser_value_array_do_write(struct file *file,
233 const char __user *user_buf,
234 size_t count, loff_t *ppos,
235 bool atomic)
236{
237 struct gpio_virtuser_line_data *data = file->private_data;
238 struct gpio_descs *descs = data->ad.descs;
239 int ret;
240
241 if (count - 1 != descs->ndescs)
242 return -EINVAL;
243
244 char *buf __free(kfree) = kzalloc(count, GFP_KERNEL);
245 if (!buf)
246 return -ENOMEM;
247
248 ret = simple_write_to_buffer(buf, count, ppos, user_buf, count);
249 if (ret < 0)
250 return ret;
251
252 unsigned long *values __free(bitmap) = bitmap_zalloc(descs->ndescs,
253 GFP_KERNEL);
254 if (!values)
255 return -ENOMEM;
256
257 ret = gpio_virtuser_dbgfs_parse_value_array(buf, count - 1, values);
258 if (ret)
259 return ret;
260
261 ret = gpio_virtuser_set_array_value(descs, values, atomic);
262 if (ret)
263 return ret;
264
265 return count;
266}
267
268static ssize_t gpio_virtuser_value_array_read(struct file *file,
269 char __user *user_buf,
270 size_t count, loff_t *ppos)
271{
272 return gpio_virtuser_value_array_do_read(file, user_buf, count, ppos,
273 false);
274}
275
276static ssize_t gpio_virtuser_value_array_write(struct file *file,
277 const char __user *user_buf,
278 size_t count, loff_t *ppos)
279{
280 return gpio_virtuser_value_array_do_write(file, user_buf, count, ppos,
281 false);
282}
283
284static const struct file_operations gpio_virtuser_value_array_fops = {
285 .read = gpio_virtuser_value_array_read,
286 .write = gpio_virtuser_value_array_write,
287 .open = simple_open,
288 .owner = THIS_MODULE,
289 .llseek = default_llseek,
290};
291
292static ssize_t
293gpio_virtuser_value_array_atomic_read(struct file *file, char __user *user_buf,
294 size_t count, loff_t *ppos)
295{
296 return gpio_virtuser_value_array_do_read(file, user_buf, count, ppos,
297 true);
298}
299
300static ssize_t
301gpio_virtuser_value_array_atomic_write(struct file *file,
302 const char __user *user_buf,
303 size_t count, loff_t *ppos)
304{
305 return gpio_virtuser_value_array_do_write(file, user_buf, count, ppos,
306 true);
307}
308
309static const struct file_operations gpio_virtuser_value_array_atomic_fops = {
310 .read = gpio_virtuser_value_array_atomic_read,
311 .write = gpio_virtuser_value_array_atomic_write,
312 .open = simple_open,
313 .owner = THIS_MODULE,
314 .llseek = default_llseek,
315};
316
317static void gpio_virtuser_do_get_direction_atomic(struct irq_work *work)
318{
319 struct gpio_virtuser_irq_work_context *ctx =
320 to_gpio_virtuser_irq_work_context(work);
321
322 ctx->ret = gpiod_get_direction(ctx->desc);
323 complete(&ctx->work_completion);
324}
325
326static int gpio_virtuser_get_direction_atomic(struct gpio_desc *desc)
327{
328 struct gpio_virtuser_irq_work_context ctx;
329
330 gpio_virtuser_init_irq_work_context(&ctx);
331 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_do_get_direction_atomic);
332 ctx.desc = desc;
333
334 gpio_virtuser_irq_work_queue_sync(&ctx);
335
336 return ctx.ret;
337}
338
339static ssize_t gpio_virtuser_direction_do_read(struct file *file,
340 char __user *user_buf,
341 size_t size, loff_t *ppos,
342 bool atomic)
343{
344 struct gpio_virtuser_line_data *data = file->private_data;
345 struct gpio_desc *desc = data->ad.desc;
346 char buf[32];
347 int dir;
348
349 if (!atomic)
350 dir = gpiod_get_direction(desc);
351 else
352 dir = gpio_virtuser_get_direction_atomic(desc);
353 if (dir < 0)
354 return dir;
355
356 snprintf(buf, sizeof(buf), "%s\n", dir ? "input" : "output");
357
358 return simple_read_from_buffer(user_buf, size, ppos, buf, strlen(buf));
359}
360
361static int gpio_virtuser_set_direction(struct gpio_desc *desc, int dir, int val)
362{
363 if (dir)
364 return gpiod_direction_input(desc);
365
366 return gpiod_direction_output(desc, val);
367}
368
369static void gpio_virtuser_do_set_direction_atomic(struct irq_work *work)
370{
371 struct gpio_virtuser_irq_work_context *ctx =
372 to_gpio_virtuser_irq_work_context(work);
373
374 ctx->ret = gpio_virtuser_set_direction(ctx->desc, ctx->dir, ctx->val);
375 complete(&ctx->work_completion);
376}
377
378static int gpio_virtuser_set_direction_atomic(struct gpio_desc *desc,
379 int dir, int val)
380{
381 struct gpio_virtuser_irq_work_context ctx;
382
383 gpio_virtuser_init_irq_work_context(&ctx);
384 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_do_set_direction_atomic);
385 ctx.desc = desc;
386 ctx.dir = dir;
387 ctx.val = val;
388
389 gpio_virtuser_irq_work_queue_sync(&ctx);
390
391 return ctx.ret;
392}
393
394static ssize_t gpio_virtuser_direction_do_write(struct file *file,
395 const char __user *user_buf,
396 size_t count, loff_t *ppos,
397 bool atomic)
398{
399 struct gpio_virtuser_line_data *data = file->private_data;
400 struct gpio_desc *desc = data->ad.desc;
401 char buf[32], *trimmed;
402 int ret, dir, val = 0;
403
404 ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count);
405 if (ret < 0)
406 return ret;
407
408 trimmed = strim(buf);
409
410 if (strcmp(trimmed, "input") == 0) {
411 dir = 1;
412 } else if (strcmp(trimmed, "output-high") == 0) {
413 dir = 0;
414 val = 1;
415 } else if (strcmp(trimmed, "output-low") == 0) {
416 dir = val = 0;
417 } else {
418 return -EINVAL;
419 }
420
421 if (!atomic)
422 ret = gpio_virtuser_set_direction(desc, dir, val);
423 else
424 ret = gpio_virtuser_set_direction_atomic(desc, dir, val);
425 if (ret)
426 return ret;
427
428 return count;
429}
430
431static ssize_t gpio_virtuser_direction_read(struct file *file,
432 char __user *user_buf,
433 size_t size, loff_t *ppos)
434{
435 return gpio_virtuser_direction_do_read(file, user_buf, size, ppos,
436 false);
437}
438
439static ssize_t gpio_virtuser_direction_write(struct file *file,
440 const char __user *user_buf,
441 size_t count, loff_t *ppos)
442{
443 return gpio_virtuser_direction_do_write(file, user_buf, count, ppos,
444 false);
445}
446
447static const struct file_operations gpio_virtuser_direction_fops = {
448 .read = gpio_virtuser_direction_read,
449 .write = gpio_virtuser_direction_write,
450 .open = simple_open,
451 .owner = THIS_MODULE,
452 .llseek = default_llseek,
453};
454
455static ssize_t gpio_virtuser_direction_atomic_read(struct file *file,
456 char __user *user_buf,
457 size_t size, loff_t *ppos)
458{
459 return gpio_virtuser_direction_do_read(file, user_buf, size, ppos,
460 true);
461}
462
463static ssize_t gpio_virtuser_direction_atomic_write(struct file *file,
464 const char __user *user_buf,
465 size_t count, loff_t *ppos)
466{
467 return gpio_virtuser_direction_do_write(file, user_buf, count, ppos,
468 true);
469}
470
471static const struct file_operations gpio_virtuser_direction_atomic_fops = {
472 .read = gpio_virtuser_direction_atomic_read,
473 .write = gpio_virtuser_direction_atomic_write,
474 .open = simple_open,
475 .owner = THIS_MODULE,
476 .llseek = default_llseek,
477};
478
479static int gpio_virtuser_value_get(void *data, u64 *val)
480{
481 struct gpio_virtuser_line_data *ld = data;
482 int ret;
483
484 ret = gpiod_get_value_cansleep(ld->ad.desc);
485 if (ret < 0)
486 return ret;
487
488 *val = ret;
489
490 return 0;
491}
492
493static int gpio_virtuser_value_set(void *data, u64 val)
494{
495 struct gpio_virtuser_line_data *ld = data;
496
497 if (val > 1)
498 return -EINVAL;
499
500 gpiod_set_value_cansleep(ld->ad.desc, (int)val);
501
502 return 0;
503}
504
505DEFINE_DEBUGFS_ATTRIBUTE(gpio_virtuser_value_fops,
506 gpio_virtuser_value_get,
507 gpio_virtuser_value_set,
508 "%llu\n");
509
510static void gpio_virtuser_get_value_atomic(struct irq_work *work)
511{
512 struct gpio_virtuser_irq_work_context *ctx =
513 to_gpio_virtuser_irq_work_context(work);
514
515 ctx->val = gpiod_get_value(ctx->desc);
516 complete(&ctx->work_completion);
517}
518
519static int gpio_virtuser_value_atomic_get(void *data, u64 *val)
520{
521 struct gpio_virtuser_line_data *ld = data;
522 struct gpio_virtuser_irq_work_context ctx;
523
524 gpio_virtuser_init_irq_work_context(&ctx);
525 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_get_value_atomic);
526 ctx.desc = ld->ad.desc;
527
528 gpio_virtuser_irq_work_queue_sync(&ctx);
529
530 if (ctx.val < 0)
531 return ctx.val;
532
533 *val = ctx.val;
534
535 return 0;
536}
537
538static void gpio_virtuser_set_value_atomic(struct irq_work *work)
539{
540 struct gpio_virtuser_irq_work_context *ctx =
541 to_gpio_virtuser_irq_work_context(work);
542
543 gpiod_set_value(ctx->desc, ctx->val);
544 complete(&ctx->work_completion);
545}
546
547static int gpio_virtuser_value_atomic_set(void *data, u64 val)
548{
549 struct gpio_virtuser_line_data *ld = data;
550 struct gpio_virtuser_irq_work_context ctx;
551
552 if (val > 1)
553 return -EINVAL;
554
555 gpio_virtuser_init_irq_work_context(&ctx);
556 ctx.work = IRQ_WORK_INIT_HARD(gpio_virtuser_set_value_atomic);
557 ctx.desc = ld->ad.desc;
558 ctx.val = (int)val;
559
560 gpio_virtuser_irq_work_queue_sync(&ctx);
561
562 return 0;
563}
564
565DEFINE_DEBUGFS_ATTRIBUTE(gpio_virtuser_value_atomic_fops,
566 gpio_virtuser_value_atomic_get,
567 gpio_virtuser_value_atomic_set,
568 "%llu\n");
569
570static int gpio_virtuser_debounce_get(void *data, u64 *val)
571{
572 struct gpio_virtuser_line_data *ld = data;
573
574 *val = READ_ONCE(ld->debounce);
575
576 return 0;
577}
578
579static int gpio_virtuser_debounce_set(void *data, u64 val)
580{
581 struct gpio_virtuser_line_data *ld = data;
582 int ret;
583
584 if (val > UINT_MAX)
585 return -E2BIG;
586
587 ret = gpiod_set_debounce(ld->ad.desc, (unsigned int)val);
588 if (ret)
589 /* Don't propagate errno unknown to user-space. */
590 return ret == -ENOTSUPP ? -EOPNOTSUPP : ret;
591
592 WRITE_ONCE(ld->debounce, (unsigned int)val);
593
594 return 0;
595}
596
597DEFINE_DEBUGFS_ATTRIBUTE(gpio_virtuser_debounce_fops,
598 gpio_virtuser_debounce_get,
599 gpio_virtuser_debounce_set,
600 "%llu\n");
601
602static ssize_t gpio_virtuser_consumer_read(struct file *file,
603 char __user *user_buf,
604 size_t size, loff_t *ppos)
605{
606 struct gpio_virtuser_line_data *data = file->private_data;
607 char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 1];
608 ssize_t ret;
609
610 memset(buf, 0x0, sizeof(buf));
611
612 scoped_guard(mutex, &data->consumer_lock)
613 ret = snprintf(buf, sizeof(buf), "%s\n", data->consumer);
614
615 return simple_read_from_buffer(user_buf, size, ppos, buf, ret);
616}
617
618static ssize_t gpio_virtuser_consumer_write(struct file *file,
619 const char __user *user_buf,
620 size_t count, loff_t *ppos)
621{
622 struct gpio_virtuser_line_data *data = file->private_data;
623 char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
624 int ret;
625
626 ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
627 user_buf, count);
628 if (ret < 0)
629 return ret;
630
631 buf[strlen(buf) - 1] = '\0';
632
633 ret = gpiod_set_consumer_name(data->ad.desc, buf);
634 if (ret)
635 return ret;
636
637 scoped_guard(mutex, &data->consumer_lock)
638 strscpy(data->consumer, buf, sizeof(data->consumer));
639
640 return count;
641}
642
643static const struct file_operations gpio_virtuser_consumer_fops = {
644 .read = gpio_virtuser_consumer_read,
645 .write = gpio_virtuser_consumer_write,
646 .open = simple_open,
647 .owner = THIS_MODULE,
648 .llseek = default_llseek,
649};
650
651static int gpio_virtuser_interrupts_get(void *data, u64 *val)
652{
653 struct gpio_virtuser_line_data *ld = data;
654
655 *val = atomic_read(&ld->irq_count);
656
657 return 0;
658}
659
660static irqreturn_t gpio_virtuser_irq_handler(int irq, void *data)
661{
662 struct gpio_virtuser_line_data *ld = data;
663
664 atomic_inc(&ld->irq_count);
665
666 return IRQ_HANDLED;
667}
668
669static int gpio_virtuser_interrupts_set(void *data, u64 val)
670{
671 struct gpio_virtuser_line_data *ld = data;
672 int irq, ret;
673
674 if (val > 1)
675 return -EINVAL;
676
677 if (val) {
678 irq = gpiod_to_irq(ld->ad.desc);
679 if (irq < 0)
680 return irq;
681
682 ret = request_threaded_irq(irq, NULL,
683 gpio_virtuser_irq_handler,
684 IRQF_TRIGGER_RISING |
685 IRQF_TRIGGER_FALLING |
686 IRQF_ONESHOT,
687 ld->consumer, data);
688 if (ret)
689 return ret;
690
691 atomic_set(&ld->irq, irq);
692 } else {
693 irq = atomic_xchg(&ld->irq, 0);
694 free_irq(irq, ld);
695 }
696
697 return 0;
698}
699
700DEFINE_DEBUGFS_ATTRIBUTE(gpio_virtuser_interrupts_fops,
701 gpio_virtuser_interrupts_get,
702 gpio_virtuser_interrupts_set,
703 "%llu\n");
704
705static const struct gpio_virtuser_dbgfs_attr_descr
706gpio_virtuser_line_array_dbgfs_attrs[] = {
707 {
708 .name = "values",
709 .fops = &gpio_virtuser_value_array_fops,
710 },
711 {
712 .name = "values_atomic",
713 .fops = &gpio_virtuser_value_array_atomic_fops,
714 },
715};
716
717static const struct gpio_virtuser_dbgfs_attr_descr
718gpio_virtuser_line_dbgfs_attrs[] = {
719 {
720 .name = "direction",
721 .fops = &gpio_virtuser_direction_fops,
722 },
723 {
724 .name = "direction_atomic",
725 .fops = &gpio_virtuser_direction_atomic_fops,
726 },
727 {
728 .name = "value",
729 .fops = &gpio_virtuser_value_fops,
730 },
731 {
732 .name = "value_atomic",
733 .fops = &gpio_virtuser_value_atomic_fops,
734 },
735 {
736 .name = "debounce",
737 .fops = &gpio_virtuser_debounce_fops,
738 },
739 {
740 .name = "consumer",
741 .fops = &gpio_virtuser_consumer_fops,
742 },
743 {
744 .name = "interrupts",
745 .fops = &gpio_virtuser_interrupts_fops,
746 },
747};
748
749static int gpio_virtuser_create_debugfs_attrs(
750 const struct gpio_virtuser_dbgfs_attr_descr *attr,
751 size_t num_attrs, struct dentry *parent, void *data)
752{
753 struct dentry *ret;
754 size_t i;
755
756 for (i = 0; i < num_attrs; i++, attr++) {
757 ret = debugfs_create_file(attr->name, 0644, parent, data,
758 attr->fops);
759 if (IS_ERR(ret))
760 return PTR_ERR(ret);
761 }
762
763 return 0;
764}
765
766static int gpio_virtuser_dbgfs_init_line_array_attrs(struct device *dev,
767 struct gpio_descs *descs,
768 const char *id,
769 struct dentry *dbgfs_entry)
770{
771 struct gpio_virtuser_line_array_data *data;
772 char *name;
773
774 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
775 if (!data)
776 return -ENOMEM;
777
778 data->ad.descs = descs;
779
780 name = devm_kasprintf(dev, GFP_KERNEL, "gpiod:%s", id);
781 if (!name)
782 return -ENOMEM;
783
784 data->ad.dbgfs_dir = debugfs_create_dir(name, dbgfs_entry);
785 if (IS_ERR(data->ad.dbgfs_dir))
786 return PTR_ERR(data->ad.dbgfs_dir);
787
788 return gpio_virtuser_create_debugfs_attrs(
789 gpio_virtuser_line_array_dbgfs_attrs,
790 ARRAY_SIZE(gpio_virtuser_line_array_dbgfs_attrs),
791 data->ad.dbgfs_dir, data);
792}
793
794static int gpio_virtuser_dbgfs_init_line_attrs(struct device *dev,
795 struct gpio_desc *desc,
796 const char *id,
797 unsigned int index,
798 struct dentry *dbgfs_entry)
799{
800 struct gpio_virtuser_line_data *data;
801 char *name;
802 int ret;
803
804 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
805 if (!data)
806 return -ENOMEM;
807
808 data->ad.desc = desc;
809 strscpy(data->consumer, id);
810 atomic_set(&data->irq, 0);
811 atomic_set(&data->irq_count, 0);
812
813 name = devm_kasprintf(dev, GFP_KERNEL, "gpiod:%s:%u", id, index);
814 if (!name)
815 return -ENOMEM;
816
817 ret = devm_mutex_init(dev, &data->consumer_lock);
818 if (ret)
819 return ret;
820
821 data->ad.dbgfs_dir = debugfs_create_dir(name, dbgfs_entry);
822 if (IS_ERR(data->ad.dbgfs_dir))
823 return PTR_ERR(data->ad.dbgfs_dir);
824
825 return gpio_virtuser_create_debugfs_attrs(
826 gpio_virtuser_line_dbgfs_attrs,
827 ARRAY_SIZE(gpio_virtuser_line_dbgfs_attrs),
828 data->ad.dbgfs_dir, data);
829}
830
831static void gpio_virtuser_debugfs_remove(void *data)
832{
833 struct dentry *dbgfs_entry = data;
834
835 debugfs_remove_recursive(dbgfs_entry);
836}
837
838static int gpio_virtuser_prop_is_gpio(struct property *prop)
839{
840 char *dash = strrchr(prop->name, '-');
841
842 return dash && strcmp(dash, "-gpios") == 0;
843}
844
845/*
846 * If this is an OF-based system, then we iterate over properties and consider
847 * all whose names end in "-gpios". For configfs we expect an additional string
848 * array property - "gpio-virtuser,ids" - containing the list of all GPIO IDs
849 * to request.
850 */
851static int gpio_virtuser_count_ids(struct device *dev)
852{
853 struct device_node *of_node = dev_of_node(dev);
854 struct property *prop;
855 int ret = 0;
856
857 if (!of_node)
858 return device_property_string_array_count(dev,
859 "gpio-virtuser,ids");
860
861 for_each_property_of_node(of_node, prop) {
862 if (gpio_virtuser_prop_is_gpio(prop))
863 ++ret;
864 }
865
866 return ret;
867}
868
869static int gpio_virtuser_get_ids(struct device *dev, const char **ids,
870 int num_ids)
871{
872 struct device_node *of_node = dev_of_node(dev);
873 struct property *prop;
874 size_t pos = 0, diff;
875 char *dash, *tmp;
876
877 if (!of_node)
878 return device_property_read_string_array(dev,
879 "gpio-virtuser,ids",
880 ids, num_ids);
881
882 for_each_property_of_node(of_node, prop) {
883 if (!gpio_virtuser_prop_is_gpio(prop))
884 continue;
885
886 dash = strrchr(prop->name, '-');
887 diff = dash - prop->name;
888
889 tmp = devm_kmemdup(dev, prop->name, diff + 1,
890 GFP_KERNEL);
891 if (!tmp)
892 return -ENOMEM;
893
894 tmp[diff] = '\0';
895 ids[pos++] = tmp;
896 }
897
898 return 0;
899}
900
901static int gpio_virtuser_probe(struct platform_device *pdev)
902{
903 struct device *dev = &pdev->dev;
904 struct dentry *dbgfs_entry;
905 struct gpio_descs *descs;
906 int ret, num_ids = 0, i;
907 const char **ids;
908 unsigned int j;
909
910 num_ids = gpio_virtuser_count_ids(dev);
911 if (num_ids < 0)
912 return dev_err_probe(dev, num_ids,
913 "Failed to get the number of GPIOs to request\n");
914
915 if (num_ids == 0)
916 return dev_err_probe(dev, -EINVAL, "No GPIO IDs specified\n");
917
918 ids = devm_kcalloc(dev, num_ids, sizeof(*ids), GFP_KERNEL);
919 if (!ids)
920 return -ENOMEM;
921
922 ret = gpio_virtuser_get_ids(dev, ids, num_ids);
923 if (ret < 0)
924 return dev_err_probe(dev, ret,
925 "Failed to get the IDs of GPIOs to request\n");
926
927 dbgfs_entry = debugfs_create_dir(dev_name(dev), gpio_virtuser_dbg_root);
928 ret = devm_add_action_or_reset(dev, gpio_virtuser_debugfs_remove,
929 dbgfs_entry);
930 if (ret)
931 return ret;
932
933 for (i = 0; i < num_ids; i++) {
934 descs = devm_gpiod_get_array(dev, ids[i], GPIOD_ASIS);
935 if (IS_ERR(descs))
936 return dev_err_probe(dev, PTR_ERR(descs),
937 "Failed to request the '%s' GPIOs\n",
938 ids[i]);
939
940 ret = gpio_virtuser_dbgfs_init_line_array_attrs(dev, descs,
941 ids[i],
942 dbgfs_entry);
943 if (ret)
944 return dev_err_probe(dev, ret,
945 "Failed to setup the debugfs array interface for the '%s' GPIOs\n",
946 ids[i]);
947
948 for (j = 0; j < descs->ndescs; j++) {
949 ret = gpio_virtuser_dbgfs_init_line_attrs(dev,
950 descs->desc[j], ids[i],
951 j, dbgfs_entry);
952 if (ret)
953 return dev_err_probe(dev, ret,
954 "Failed to setup the debugfs line interface for the '%s' GPIOs\n",
955 ids[i]);
956 }
957 }
958
959 return 0;
960}
961
962static const struct of_device_id gpio_virtuser_of_match[] = {
963 { .compatible = "gpio-virtuser" },
964 { }
965};
966MODULE_DEVICE_TABLE(of, gpio_virtuser_of_match);
967
968static struct platform_driver gpio_virtuser_driver = {
969 .driver = {
970 .name = "gpio-virtuser",
971 .of_match_table = gpio_virtuser_of_match,
972 },
973 .probe = gpio_virtuser_probe,
974};
975
976struct gpio_virtuser_device {
977 struct dev_sync_probe_data probe_data;
978 struct config_group group;
979
980 int id;
981 struct mutex lock;
982
983 struct gpiod_lookup_table *lookup_table;
984
985 struct list_head lookup_list;
986};
987
988static struct gpio_virtuser_device *
989to_gpio_virtuser_device(struct config_item *item)
990{
991 struct config_group *group = to_config_group(item);
992
993 return container_of(group, struct gpio_virtuser_device, group);
994}
995
996static bool
997gpio_virtuser_device_is_live(struct gpio_virtuser_device *dev)
998{
999 lockdep_assert_held(&dev->lock);
1000
1001 return !!dev->probe_data.pdev;
1002}
1003
1004struct gpio_virtuser_lookup {
1005 struct config_group group;
1006
1007 struct gpio_virtuser_device *parent;
1008 struct list_head siblings;
1009
1010 char *con_id;
1011
1012 struct list_head entry_list;
1013};
1014
1015static struct gpio_virtuser_lookup *
1016to_gpio_virtuser_lookup(struct config_item *item)
1017{
1018 struct config_group *group = to_config_group(item);
1019
1020 return container_of(group, struct gpio_virtuser_lookup, group);
1021}
1022
1023struct gpio_virtuser_lookup_entry {
1024 struct config_group group;
1025
1026 struct gpio_virtuser_lookup *parent;
1027 struct list_head siblings;
1028
1029 char *key;
1030 /* Can be negative to indicate lookup by name. */
1031 int offset;
1032 enum gpio_lookup_flags flags;
1033};
1034
1035static struct gpio_virtuser_lookup_entry *
1036to_gpio_virtuser_lookup_entry(struct config_item *item)
1037{
1038 struct config_group *group = to_config_group(item);
1039
1040 return container_of(group, struct gpio_virtuser_lookup_entry, group);
1041}
1042
1043static ssize_t
1044gpio_virtuser_lookup_entry_config_key_show(struct config_item *item, char *page)
1045{
1046 struct gpio_virtuser_lookup_entry *entry =
1047 to_gpio_virtuser_lookup_entry(item);
1048 struct gpio_virtuser_device *dev = entry->parent->parent;
1049
1050 guard(mutex)(&dev->lock);
1051
1052 return sprintf(page, "%s\n", entry->key ?: "");
1053}
1054
1055static ssize_t
1056gpio_virtuser_lookup_entry_config_key_store(struct config_item *item,
1057 const char *page, size_t count)
1058{
1059 struct gpio_virtuser_lookup_entry *entry =
1060 to_gpio_virtuser_lookup_entry(item);
1061 struct gpio_virtuser_device *dev = entry->parent->parent;
1062
1063 char *key __free(kfree) = kstrndup(skip_spaces(page), count,
1064 GFP_KERNEL);
1065 if (!key)
1066 return -ENOMEM;
1067
1068 strim(key);
1069
1070 guard(mutex)(&dev->lock);
1071
1072 if (gpio_virtuser_device_is_live(dev))
1073 return -EBUSY;
1074
1075 kfree(entry->key);
1076 entry->key = no_free_ptr(key);
1077
1078 return count;
1079}
1080
1081CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, key);
1082
1083static ssize_t
1084gpio_virtuser_lookup_entry_config_offset_show(struct config_item *item,
1085 char *page)
1086{
1087 struct gpio_virtuser_lookup_entry *entry =
1088 to_gpio_virtuser_lookup_entry(item);
1089 struct gpio_virtuser_device *dev = entry->parent->parent;
1090 unsigned int offset;
1091
1092 scoped_guard(mutex, &dev->lock)
1093 offset = entry->offset;
1094
1095 return sprintf(page, "%d\n", offset);
1096}
1097
1098static ssize_t
1099gpio_virtuser_lookup_entry_config_offset_store(struct config_item *item,
1100 const char *page, size_t count)
1101{
1102 struct gpio_virtuser_lookup_entry *entry =
1103 to_gpio_virtuser_lookup_entry(item);
1104 struct gpio_virtuser_device *dev = entry->parent->parent;
1105 int offset, ret;
1106
1107 ret = kstrtoint(page, 0, &offset);
1108 if (ret)
1109 return ret;
1110
1111 /*
1112 * Negative number here means: 'key' represents a line name to lookup.
1113 * Non-negative means: 'key' represents the label of the chip with
1114 * the 'offset' value representing the line within that chip.
1115 *
1116 * GPIOLIB uses the U16_MAX value to indicate lookup by line name so
1117 * the greatest offset we can accept is (U16_MAX - 1).
1118 */
1119 if (offset > (U16_MAX - 1))
1120 return -EINVAL;
1121
1122 guard(mutex)(&dev->lock);
1123
1124 if (gpio_virtuser_device_is_live(dev))
1125 return -EBUSY;
1126
1127 entry->offset = offset;
1128
1129 return count;
1130}
1131
1132CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, offset);
1133
1134static enum gpio_lookup_flags
1135gpio_virtuser_lookup_get_flags(struct config_item *item)
1136{
1137 struct gpio_virtuser_lookup_entry *entry =
1138 to_gpio_virtuser_lookup_entry(item);
1139 struct gpio_virtuser_device *dev = entry->parent->parent;
1140
1141 guard(mutex)(&dev->lock);
1142
1143 return entry->flags;
1144}
1145
1146static ssize_t
1147gpio_virtuser_lookup_entry_config_drive_show(struct config_item *item, char *page)
1148{
1149 enum gpio_lookup_flags flags = gpio_virtuser_lookup_get_flags(item);
1150 const char *repr;
1151
1152 if (flags & GPIO_OPEN_DRAIN)
1153 repr = "open-drain";
1154 else if (flags & GPIO_OPEN_SOURCE)
1155 repr = "open-source";
1156 else
1157 repr = "push-pull";
1158
1159 return sprintf(page, "%s\n", repr);
1160}
1161
1162static ssize_t
1163gpio_virtuser_lookup_entry_config_drive_store(struct config_item *item,
1164 const char *page, size_t count)
1165{
1166 struct gpio_virtuser_lookup_entry *entry =
1167 to_gpio_virtuser_lookup_entry(item);
1168 struct gpio_virtuser_device *dev = entry->parent->parent;
1169
1170 guard(mutex)(&dev->lock);
1171
1172 if (gpio_virtuser_device_is_live(dev))
1173 return -EBUSY;
1174
1175 if (sysfs_streq(page, "push-pull")) {
1176 entry->flags &= ~(GPIO_OPEN_DRAIN | GPIO_OPEN_SOURCE);
1177 } else if (sysfs_streq(page, "open-drain")) {
1178 entry->flags &= ~GPIO_OPEN_SOURCE;
1179 entry->flags |= GPIO_OPEN_DRAIN;
1180 } else if (sysfs_streq(page, "open-source")) {
1181 entry->flags &= ~GPIO_OPEN_DRAIN;
1182 entry->flags |= GPIO_OPEN_SOURCE;
1183 } else {
1184 count = -EINVAL;
1185 }
1186
1187 return count;
1188}
1189
1190CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, drive);
1191
1192static ssize_t
1193gpio_virtuser_lookup_entry_config_pull_show(struct config_item *item, char *page)
1194{
1195 enum gpio_lookup_flags flags = gpio_virtuser_lookup_get_flags(item);
1196 const char *repr;
1197
1198 if (flags & GPIO_PULL_UP)
1199 repr = "pull-up";
1200 else if (flags & GPIO_PULL_DOWN)
1201 repr = "pull-down";
1202 else if (flags & GPIO_PULL_DISABLE)
1203 repr = "pull-disabled";
1204 else
1205 repr = "as-is";
1206
1207 return sprintf(page, "%s\n", repr);
1208}
1209
1210static ssize_t
1211gpio_virtuser_lookup_entry_config_pull_store(struct config_item *item,
1212 const char *page, size_t count)
1213{
1214 struct gpio_virtuser_lookup_entry *entry =
1215 to_gpio_virtuser_lookup_entry(item);
1216 struct gpio_virtuser_device *dev = entry->parent->parent;
1217
1218 guard(mutex)(&dev->lock);
1219
1220 if (gpio_virtuser_device_is_live(dev))
1221 return -EBUSY;
1222
1223 if (sysfs_streq(page, "pull-up")) {
1224 entry->flags &= ~(GPIO_PULL_DOWN | GPIO_PULL_DISABLE);
1225 entry->flags |= GPIO_PULL_UP;
1226 } else if (sysfs_streq(page, "pull-down")) {
1227 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DISABLE);
1228 entry->flags |= GPIO_PULL_DOWN;
1229 } else if (sysfs_streq(page, "pull-disabled")) {
1230 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DOWN);
1231 entry->flags |= GPIO_PULL_DISABLE;
1232 } else if (sysfs_streq(page, "as-is")) {
1233 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DOWN |
1234 GPIO_PULL_DISABLE);
1235 } else {
1236 count = -EINVAL;
1237 }
1238
1239 return count;
1240}
1241
1242CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, pull);
1243
1244static ssize_t
1245gpio_virtuser_lookup_entry_config_active_low_show(struct config_item *item,
1246 char *page)
1247{
1248 enum gpio_lookup_flags flags = gpio_virtuser_lookup_get_flags(item);
1249
1250 return sprintf(page, "%c\n", flags & GPIO_ACTIVE_LOW ? '1' : '0');
1251}
1252
1253static ssize_t
1254gpio_virtuser_lookup_entry_config_active_low_store(struct config_item *item,
1255 const char *page,
1256 size_t count)
1257{
1258 struct gpio_virtuser_lookup_entry *entry =
1259 to_gpio_virtuser_lookup_entry(item);
1260 struct gpio_virtuser_device *dev = entry->parent->parent;
1261 bool active_low;
1262 int ret;
1263
1264 ret = kstrtobool(page, &active_low);
1265 if (ret)
1266 return ret;
1267
1268 guard(mutex)(&dev->lock);
1269
1270 if (gpio_virtuser_device_is_live(dev))
1271 return -EBUSY;
1272
1273 if (active_low)
1274 entry->flags |= GPIO_ACTIVE_LOW;
1275 else
1276 entry->flags &= ~GPIO_ACTIVE_LOW;
1277
1278 return count;
1279}
1280
1281CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, active_low);
1282
1283static ssize_t
1284gpio_virtuser_lookup_entry_config_transitory_show(struct config_item *item,
1285 char *page)
1286{
1287 enum gpio_lookup_flags flags = gpio_virtuser_lookup_get_flags(item);
1288
1289 return sprintf(page, "%c\n", flags & GPIO_TRANSITORY ? '1' : '0');
1290}
1291
1292static ssize_t
1293gpio_virtuser_lookup_entry_config_transitory_store(struct config_item *item,
1294 const char *page,
1295 size_t count)
1296{
1297 struct gpio_virtuser_lookup_entry *entry =
1298 to_gpio_virtuser_lookup_entry(item);
1299 struct gpio_virtuser_device *dev = entry->parent->parent;
1300 bool transitory;
1301 int ret;
1302
1303 ret = kstrtobool(page, &transitory);
1304 if (ret)
1305 return ret;
1306
1307 guard(mutex)(&dev->lock);
1308
1309 if (gpio_virtuser_device_is_live(dev))
1310 return -EBUSY;
1311
1312 if (transitory)
1313 entry->flags |= GPIO_TRANSITORY;
1314 else
1315 entry->flags &= ~GPIO_TRANSITORY;
1316
1317 return count;
1318}
1319
1320CONFIGFS_ATTR(gpio_virtuser_lookup_entry_config_, transitory);
1321
1322static struct configfs_attribute *gpio_virtuser_lookup_entry_config_attrs[] = {
1323 &gpio_virtuser_lookup_entry_config_attr_key,
1324 &gpio_virtuser_lookup_entry_config_attr_offset,
1325 &gpio_virtuser_lookup_entry_config_attr_drive,
1326 &gpio_virtuser_lookup_entry_config_attr_pull,
1327 &gpio_virtuser_lookup_entry_config_attr_active_low,
1328 &gpio_virtuser_lookup_entry_config_attr_transitory,
1329 NULL
1330};
1331
1332static ssize_t
1333gpio_virtuser_device_config_dev_name_show(struct config_item *item,
1334 char *page)
1335{
1336 struct gpio_virtuser_device *dev = to_gpio_virtuser_device(item);
1337 struct platform_device *pdev;
1338
1339 guard(mutex)(&dev->lock);
1340
1341 pdev = dev->probe_data.pdev;
1342 if (pdev)
1343 return sprintf(page, "%s\n", dev_name(&pdev->dev));
1344
1345 return sprintf(page, "gpio-sim.%d\n", dev->id);
1346}
1347
1348CONFIGFS_ATTR_RO(gpio_virtuser_device_config_, dev_name);
1349
1350static ssize_t gpio_virtuser_device_config_live_show(struct config_item *item,
1351 char *page)
1352{
1353 struct gpio_virtuser_device *dev = to_gpio_virtuser_device(item);
1354 bool live;
1355
1356 scoped_guard(mutex, &dev->lock)
1357 live = gpio_virtuser_device_is_live(dev);
1358
1359 return sprintf(page, "%c\n", live ? '1' : '0');
1360}
1361
1362static size_t
1363gpio_virtuser_get_lookup_count(struct gpio_virtuser_device *dev)
1364{
1365 struct gpio_virtuser_lookup *lookup;
1366 size_t count = 0;
1367
1368 lockdep_assert_held(&dev->lock);
1369
1370 list_for_each_entry(lookup, &dev->lookup_list, siblings)
1371 count += list_count_nodes(&lookup->entry_list);
1372
1373 return count;
1374}
1375
1376static int
1377gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev)
1378{
1379 size_t num_entries = gpio_virtuser_get_lookup_count(dev);
1380 struct gpio_virtuser_lookup_entry *entry;
1381 struct gpio_virtuser_lookup *lookup;
1382 unsigned int i = 0, idx;
1383
1384 lockdep_assert_held(&dev->lock);
1385
1386 struct gpiod_lookup_table *table __free(kfree) =
1387 kzalloc(struct_size(table, table, num_entries + 1), GFP_KERNEL);
1388 if (!table)
1389 return -ENOMEM;
1390
1391 table->dev_id = kasprintf(GFP_KERNEL, "gpio-virtuser.%d", dev->id);
1392 if (!table->dev_id)
1393 return -ENOMEM;
1394
1395 list_for_each_entry(lookup, &dev->lookup_list, siblings) {
1396 idx = 0;
1397 list_for_each_entry(entry, &lookup->entry_list, siblings) {
1398 table->table[i++] =
1399 GPIO_LOOKUP_IDX(entry->key,
1400 entry->offset < 0 ? U16_MAX : entry->offset,
1401 lookup->con_id, idx++, entry->flags);
1402 }
1403 }
1404
1405 gpiod_add_lookup_table(table);
1406 dev->lookup_table = no_free_ptr(table);
1407
1408 return 0;
1409}
1410
1411static void
1412gpio_virtuser_remove_lookup_table(struct gpio_virtuser_device *dev)
1413{
1414 gpiod_remove_lookup_table(dev->lookup_table);
1415 kfree(dev->lookup_table->dev_id);
1416 kfree(dev->lookup_table);
1417 dev->lookup_table = NULL;
1418}
1419
1420static struct fwnode_handle *
1421gpio_virtuser_make_device_swnode(struct gpio_virtuser_device *dev)
1422{
1423 struct property_entry properties[2];
1424 struct gpio_virtuser_lookup *lookup;
1425 unsigned int i = 0;
1426 size_t num_ids;
1427
1428 memset(properties, 0, sizeof(properties));
1429
1430 num_ids = list_count_nodes(&dev->lookup_list);
1431 char **ids __free(kfree) = kcalloc(num_ids + 1, sizeof(*ids),
1432 GFP_KERNEL);
1433 if (!ids)
1434 return ERR_PTR(-ENOMEM);
1435
1436 list_for_each_entry(lookup, &dev->lookup_list, siblings)
1437 ids[i++] = lookup->con_id;
1438
1439 properties[0] = PROPERTY_ENTRY_STRING_ARRAY_LEN("gpio-virtuser,ids",
1440 ids, num_ids);
1441
1442 return fwnode_create_software_node(properties, NULL);
1443}
1444
1445static int
1446gpio_virtuser_device_activate(struct gpio_virtuser_device *dev)
1447{
1448 struct platform_device_info pdevinfo;
1449 struct fwnode_handle *swnode;
1450 int ret;
1451
1452 lockdep_assert_held(&dev->lock);
1453
1454 if (list_empty(&dev->lookup_list))
1455 return -ENODATA;
1456
1457 swnode = gpio_virtuser_make_device_swnode(dev);
1458 if (IS_ERR(swnode))
1459 return PTR_ERR(swnode);
1460
1461 memset(&pdevinfo, 0, sizeof(pdevinfo));
1462 pdevinfo.name = "gpio-virtuser";
1463 pdevinfo.id = dev->id;
1464 pdevinfo.fwnode = swnode;
1465
1466 ret = gpio_virtuser_make_lookup_table(dev);
1467 if (ret)
1468 goto err_remove_swnode;
1469
1470 ret = dev_sync_probe_register(&dev->probe_data, &pdevinfo);
1471 if (ret)
1472 goto err_remove_lookup_table;
1473
1474 return 0;
1475
1476err_remove_lookup_table:
1477 gpio_virtuser_remove_lookup_table(dev);
1478err_remove_swnode:
1479 fwnode_remove_software_node(swnode);
1480
1481 return ret;
1482}
1483
1484static void
1485gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
1486{
1487 struct fwnode_handle *swnode;
1488
1489 lockdep_assert_held(&dev->lock);
1490
1491 swnode = dev_fwnode(&dev->probe_data.pdev->dev);
1492 dev_sync_probe_unregister(&dev->probe_data);
1493 gpio_virtuser_remove_lookup_table(dev);
1494 fwnode_remove_software_node(swnode);
1495}
1496
1497static void
1498gpio_virtuser_device_lockup_configfs(struct gpio_virtuser_device *dev, bool lock)
1499{
1500 struct configfs_subsystem *subsys = dev->group.cg_subsys;
1501 struct gpio_virtuser_lookup_entry *entry;
1502 struct gpio_virtuser_lookup *lookup;
1503
1504 /*
1505 * The device only needs to depend on leaf lookup entries. This is
1506 * sufficient to lock up all the configfs entries that the
1507 * instantiated, alive device depends on.
1508 */
1509 list_for_each_entry(lookup, &dev->lookup_list, siblings) {
1510 list_for_each_entry(entry, &lookup->entry_list, siblings) {
1511 if (lock)
1512 WARN_ON(configfs_depend_item_unlocked(
1513 subsys, &entry->group.cg_item));
1514 else
1515 configfs_undepend_item_unlocked(
1516 &entry->group.cg_item);
1517 }
1518 }
1519}
1520
1521static ssize_t
1522gpio_virtuser_device_config_live_store(struct config_item *item,
1523 const char *page, size_t count)
1524{
1525 struct gpio_virtuser_device *dev = to_gpio_virtuser_device(item);
1526 int ret = 0;
1527 bool live;
1528
1529 ret = kstrtobool(page, &live);
1530 if (ret)
1531 return ret;
1532
1533 if (live)
1534 gpio_virtuser_device_lockup_configfs(dev, true);
1535
1536 scoped_guard(mutex, &dev->lock) {
1537 if (live == gpio_virtuser_device_is_live(dev))
1538 ret = -EPERM;
1539 else if (live)
1540 ret = gpio_virtuser_device_activate(dev);
1541 else
1542 gpio_virtuser_device_deactivate(dev);
1543 }
1544
1545 /*
1546 * Undepend is required only if device disablement (live == 0)
1547 * succeeds or if device enablement (live == 1) fails.
1548 */
1549 if (live == !!ret)
1550 gpio_virtuser_device_lockup_configfs(dev, false);
1551
1552 return ret ?: count;
1553}
1554
1555CONFIGFS_ATTR(gpio_virtuser_device_config_, live);
1556
1557static struct configfs_attribute *gpio_virtuser_device_config_attrs[] = {
1558 &gpio_virtuser_device_config_attr_dev_name,
1559 &gpio_virtuser_device_config_attr_live,
1560 NULL
1561};
1562
1563static void
1564gpio_virtuser_lookup_entry_config_group_release(struct config_item *item)
1565{
1566 struct gpio_virtuser_lookup_entry *entry =
1567 to_gpio_virtuser_lookup_entry(item);
1568 struct gpio_virtuser_device *dev = entry->parent->parent;
1569
1570 guard(mutex)(&dev->lock);
1571
1572 list_del(&entry->siblings);
1573
1574 kfree(entry->key);
1575 kfree(entry);
1576}
1577
1578static struct
1579configfs_item_operations gpio_virtuser_lookup_entry_config_item_ops = {
1580 .release = gpio_virtuser_lookup_entry_config_group_release,
1581};
1582
1583static const struct
1584config_item_type gpio_virtuser_lookup_entry_config_group_type = {
1585 .ct_item_ops = &gpio_virtuser_lookup_entry_config_item_ops,
1586 .ct_attrs = gpio_virtuser_lookup_entry_config_attrs,
1587 .ct_owner = THIS_MODULE,
1588};
1589
1590static struct config_group *
1591gpio_virtuser_make_lookup_entry_group(struct config_group *group,
1592 const char *name)
1593{
1594 struct gpio_virtuser_lookup *lookup =
1595 to_gpio_virtuser_lookup(&group->cg_item);
1596 struct gpio_virtuser_device *dev = lookup->parent;
1597
1598 guard(mutex)(&dev->lock);
1599
1600 if (gpio_virtuser_device_is_live(dev))
1601 return ERR_PTR(-EBUSY);
1602
1603 struct gpio_virtuser_lookup_entry *entry __free(kfree) =
1604 kzalloc(sizeof(*entry), GFP_KERNEL);
1605 if (!entry)
1606 return ERR_PTR(-ENOMEM);
1607
1608 config_group_init_type_name(&entry->group, name,
1609 &gpio_virtuser_lookup_entry_config_group_type);
1610 entry->flags = GPIO_LOOKUP_FLAGS_DEFAULT;
1611 entry->parent = lookup;
1612 list_add_tail(&entry->siblings, &lookup->entry_list);
1613
1614 return &no_free_ptr(entry)->group;
1615}
1616
1617static void gpio_virtuser_lookup_config_group_release(struct config_item *item)
1618{
1619 struct gpio_virtuser_lookup *lookup = to_gpio_virtuser_lookup(item);
1620 struct gpio_virtuser_device *dev = lookup->parent;
1621
1622 guard(mutex)(&dev->lock);
1623
1624 list_del(&lookup->siblings);
1625
1626 kfree(lookup->con_id);
1627 kfree(lookup);
1628}
1629
1630static struct configfs_item_operations gpio_virtuser_lookup_config_item_ops = {
1631 .release = gpio_virtuser_lookup_config_group_release,
1632};
1633
1634static struct
1635configfs_group_operations gpio_virtuser_lookup_config_group_ops = {
1636 .make_group = gpio_virtuser_make_lookup_entry_group,
1637};
1638
1639static const struct config_item_type gpio_virtuser_lookup_config_group_type = {
1640 .ct_group_ops = &gpio_virtuser_lookup_config_group_ops,
1641 .ct_item_ops = &gpio_virtuser_lookup_config_item_ops,
1642 .ct_owner = THIS_MODULE,
1643};
1644
1645static struct config_group *
1646gpio_virtuser_make_lookup_group(struct config_group *group, const char *name)
1647{
1648 struct gpio_virtuser_device *dev =
1649 to_gpio_virtuser_device(&group->cg_item);
1650
1651 if (strlen(name) > (GPIO_VIRTUSER_NAME_BUF_LEN - 1))
1652 return ERR_PTR(-E2BIG);
1653
1654 guard(mutex)(&dev->lock);
1655
1656 if (gpio_virtuser_device_is_live(dev))
1657 return ERR_PTR(-EBUSY);
1658
1659 struct gpio_virtuser_lookup *lookup __free(kfree) =
1660 kzalloc(sizeof(*lookup), GFP_KERNEL);
1661 if (!lookup)
1662 return ERR_PTR(-ENOMEM);
1663
1664 lookup->con_id = kstrdup(name, GFP_KERNEL);
1665 if (!lookup->con_id)
1666 return ERR_PTR(-ENOMEM);
1667
1668 config_group_init_type_name(&lookup->group, name,
1669 &gpio_virtuser_lookup_config_group_type);
1670 INIT_LIST_HEAD(&lookup->entry_list);
1671 lookup->parent = dev;
1672 list_add_tail(&lookup->siblings, &dev->lookup_list);
1673
1674 return &no_free_ptr(lookup)->group;
1675}
1676
1677static void gpio_virtuser_device_config_group_release(struct config_item *item)
1678{
1679 struct gpio_virtuser_device *dev = to_gpio_virtuser_device(item);
1680
1681 guard(mutex)(&dev->lock);
1682
1683 if (gpio_virtuser_device_is_live(dev))
1684 gpio_virtuser_device_deactivate(dev);
1685
1686 mutex_destroy(&dev->lock);
1687 ida_free(&gpio_virtuser_ida, dev->id);
1688 kfree(dev);
1689}
1690
1691static struct configfs_item_operations gpio_virtuser_device_config_item_ops = {
1692 .release = gpio_virtuser_device_config_group_release,
1693};
1694
1695static struct configfs_group_operations gpio_virtuser_device_config_group_ops = {
1696 .make_group = gpio_virtuser_make_lookup_group,
1697};
1698
1699static const struct config_item_type gpio_virtuser_device_config_group_type = {
1700 .ct_group_ops = &gpio_virtuser_device_config_group_ops,
1701 .ct_item_ops = &gpio_virtuser_device_config_item_ops,
1702 .ct_attrs = gpio_virtuser_device_config_attrs,
1703 .ct_owner = THIS_MODULE,
1704};
1705
1706static struct config_group *
1707gpio_virtuser_config_make_device_group(struct config_group *group,
1708 const char *name)
1709{
1710 struct gpio_virtuser_device *dev __free(kfree) = kzalloc(sizeof(*dev),
1711 GFP_KERNEL);
1712 if (!dev)
1713 return ERR_PTR(-ENOMEM);
1714
1715 dev->id = ida_alloc(&gpio_virtuser_ida, GFP_KERNEL);
1716 if (dev->id < 0)
1717 return ERR_PTR(dev->id);
1718
1719 config_group_init_type_name(&dev->group, name,
1720 &gpio_virtuser_device_config_group_type);
1721 mutex_init(&dev->lock);
1722 INIT_LIST_HEAD(&dev->lookup_list);
1723 dev_sync_probe_init(&dev->probe_data);
1724
1725 return &no_free_ptr(dev)->group;
1726}
1727
1728static struct configfs_group_operations gpio_virtuser_config_group_ops = {
1729 .make_group = gpio_virtuser_config_make_device_group,
1730};
1731
1732static const struct config_item_type gpio_virtuser_config_type = {
1733 .ct_group_ops = &gpio_virtuser_config_group_ops,
1734 .ct_owner = THIS_MODULE,
1735};
1736
1737static struct configfs_subsystem gpio_virtuser_config_subsys = {
1738 .su_group = {
1739 .cg_item = {
1740 .ci_namebuf = "gpio-virtuser",
1741 .ci_type = &gpio_virtuser_config_type,
1742 },
1743 },
1744};
1745
1746static int __init gpio_virtuser_init(void)
1747{
1748 int ret;
1749
1750 ret = platform_driver_register(&gpio_virtuser_driver);
1751 if (ret) {
1752 pr_err("Failed to register the platform driver: %d\n", ret);
1753 return ret;
1754 }
1755
1756 config_group_init(&gpio_virtuser_config_subsys.su_group);
1757 mutex_init(&gpio_virtuser_config_subsys.su_mutex);
1758 ret = configfs_register_subsystem(&gpio_virtuser_config_subsys);
1759 if (ret) {
1760 pr_err("Failed to register the '%s' configfs subsystem: %d\n",
1761 gpio_virtuser_config_subsys.su_group.cg_item.ci_namebuf,
1762 ret);
1763 goto err_plat_drv_unreg;
1764 }
1765
1766 gpio_virtuser_dbg_root = debugfs_create_dir("gpio-virtuser", NULL);
1767 if (IS_ERR(gpio_virtuser_dbg_root)) {
1768 ret = PTR_ERR(gpio_virtuser_dbg_root);
1769 pr_err("Failed to create the debugfs tree: %d\n", ret);
1770 goto err_configfs_unreg;
1771 }
1772
1773 return 0;
1774
1775err_configfs_unreg:
1776 configfs_unregister_subsystem(&gpio_virtuser_config_subsys);
1777err_plat_drv_unreg:
1778 mutex_destroy(&gpio_virtuser_config_subsys.su_mutex);
1779 platform_driver_unregister(&gpio_virtuser_driver);
1780
1781 return ret;
1782}
1783module_init(gpio_virtuser_init);
1784
1785static void __exit gpio_virtuser_exit(void)
1786{
1787 configfs_unregister_subsystem(&gpio_virtuser_config_subsys);
1788 mutex_destroy(&gpio_virtuser_config_subsys.su_mutex);
1789 platform_driver_unregister(&gpio_virtuser_driver);
1790 debugfs_remove_recursive(gpio_virtuser_dbg_root);
1791}
1792module_exit(gpio_virtuser_exit);
1793
1794MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
1795MODULE_DESCRIPTION("Virtual GPIO consumer module");
1796MODULE_LICENSE("GPL");