File Index
Files and directories
Sign in
FILE

gpio-virtuser.c

File preview with syntax highlighting.

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