Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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