Lines Matching +full:gpio +full:- +full:dir

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Configurable virtual GPIO consumer module.
5 * Copyright (C) 2023-2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
19 #include <linux/gpio/consumer.h>
20 #include <linux/gpio/machine.h>
77 int dir; member
98 init_completion(&ctx->work_completion); in gpio_virtuser_init_irq_work_context()
104 irq_work_queue(&ctx->work); in gpio_virtuser_irq_work_queue_sync()
105 wait_for_completion(&ctx->work_completion); in gpio_virtuser_irq_work_queue_sync()
124 struct gpio_descs *descs = ctx->descs; in gpio_virtuser_get_value_array_atomic()
126 ctx->ret = gpiod_get_array_value(descs->ndescs, descs->desc, in gpio_virtuser_get_value_array_atomic()
127 descs->info, ctx->values); in gpio_virtuser_get_value_array_atomic()
128 complete(&ctx->work_completion); in gpio_virtuser_get_value_array_atomic()
137 return gpiod_get_array_value_cansleep(descs->ndescs, in gpio_virtuser_get_array_value()
138 descs->desc, in gpio_virtuser_get_array_value()
139 descs->info, values); in gpio_virtuser_get_array_value()
156 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_value_array_do_read()
157 struct gpio_descs *descs = data->ad.descs; in gpio_virtuser_value_array_do_read()
161 unsigned long *values __free(bitmap) = bitmap_zalloc(descs->ndescs, in gpio_virtuser_value_array_do_read()
164 return -ENOMEM; in gpio_virtuser_value_array_do_read()
170 bufsize = descs->ndescs + 2; in gpio_virtuser_value_array_do_read()
174 return -ENOMEM; in gpio_virtuser_value_array_do_read()
176 gpio_virtuser_dbgfs_emit_value_array(buf, values, descs->ndescs); in gpio_virtuser_value_array_do_read()
179 descs->ndescs + 1); in gpio_virtuser_value_array_do_read()
194 return -EINVAL; in gpio_virtuser_dbgfs_parse_value_array()
204 struct gpio_descs *descs = ctx->descs; in gpio_virtuser_set_value_array_atomic()
206 ctx->ret = gpiod_set_array_value(descs->ndescs, descs->desc, in gpio_virtuser_set_value_array_atomic()
207 descs->info, ctx->values); in gpio_virtuser_set_value_array_atomic()
208 complete(&ctx->work_completion); in gpio_virtuser_set_value_array_atomic()
217 return gpiod_set_array_value_cansleep(descs->ndescs, in gpio_virtuser_set_array_value()
218 descs->desc, in gpio_virtuser_set_array_value()
219 descs->info, values); in gpio_virtuser_set_array_value()
236 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_value_array_do_write()
237 struct gpio_descs *descs = data->ad.descs; in gpio_virtuser_value_array_do_write()
240 if (count - 1 != descs->ndescs) in gpio_virtuser_value_array_do_write()
241 return -EINVAL; in gpio_virtuser_value_array_do_write()
245 return -ENOMEM; in gpio_virtuser_value_array_do_write()
251 unsigned long *values __free(bitmap) = bitmap_zalloc(descs->ndescs, in gpio_virtuser_value_array_do_write()
254 return -ENOMEM; in gpio_virtuser_value_array_do_write()
256 ret = gpio_virtuser_dbgfs_parse_value_array(buf, count - 1, values); in gpio_virtuser_value_array_do_write()
321 ctx->ret = gpiod_get_direction(ctx->desc); in gpio_virtuser_do_get_direction_atomic()
322 complete(&ctx->work_completion); in gpio_virtuser_do_get_direction_atomic()
343 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_direction_do_read()
344 struct gpio_desc *desc = data->ad.desc; in gpio_virtuser_direction_do_read()
346 int dir; in gpio_virtuser_direction_do_read() local
349 dir = gpiod_get_direction(desc); in gpio_virtuser_direction_do_read()
351 dir = gpio_virtuser_get_direction_atomic(desc); in gpio_virtuser_direction_do_read()
352 if (dir < 0) in gpio_virtuser_direction_do_read()
353 return dir; in gpio_virtuser_direction_do_read()
355 snprintf(buf, sizeof(buf), "%s\n", dir ? "input" : "output"); in gpio_virtuser_direction_do_read()
360 static int gpio_virtuser_set_direction(struct gpio_desc *desc, int dir, int val) in gpio_virtuser_set_direction() argument
362 if (dir) in gpio_virtuser_set_direction()
373 ctx->ret = gpio_virtuser_set_direction(ctx->desc, ctx->dir, ctx->val); in gpio_virtuser_do_set_direction_atomic()
374 complete(&ctx->work_completion); in gpio_virtuser_do_set_direction_atomic()
378 int dir, int val) in gpio_virtuser_set_direction_atomic() argument
385 ctx.dir = dir; in gpio_virtuser_set_direction_atomic()
398 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_direction_do_write()
399 struct gpio_desc *desc = data->ad.desc; in gpio_virtuser_direction_do_write()
401 int ret, dir, val = 0; in gpio_virtuser_direction_do_write() local
410 dir = 1; in gpio_virtuser_direction_do_write()
411 } else if (strcmp(trimmed, "output-high") == 0) { in gpio_virtuser_direction_do_write()
412 dir = 0; in gpio_virtuser_direction_do_write()
414 } else if (strcmp(trimmed, "output-low") == 0) { in gpio_virtuser_direction_do_write()
415 dir = val = 0; in gpio_virtuser_direction_do_write()
417 return -EINVAL; in gpio_virtuser_direction_do_write()
421 ret = gpio_virtuser_set_direction(desc, dir, val); in gpio_virtuser_direction_do_write()
423 ret = gpio_virtuser_set_direction_atomic(desc, dir, val); in gpio_virtuser_direction_do_write()
483 ret = gpiod_get_value_cansleep(ld->ad.desc); in gpio_virtuser_value_get()
497 return -EINVAL; in gpio_virtuser_value_set()
499 gpiod_set_value_cansleep(ld->ad.desc, (int)val); in gpio_virtuser_value_set()
514 ctx->val = gpiod_get_value(ctx->desc); in gpio_virtuser_get_value_atomic()
515 complete(&ctx->work_completion); in gpio_virtuser_get_value_atomic()
525 ctx.desc = ld->ad.desc; in gpio_virtuser_value_atomic_get()
542 gpiod_set_value(ctx->desc, ctx->val); in gpio_virtuser_set_value_atomic()
543 complete(&ctx->work_completion); in gpio_virtuser_set_value_atomic()
552 return -EINVAL; in gpio_virtuser_value_atomic_set()
556 ctx.desc = ld->ad.desc; in gpio_virtuser_value_atomic_set()
573 *val = READ_ONCE(ld->debounce); in gpio_virtuser_debounce_get()
584 return -E2BIG; in gpio_virtuser_debounce_set()
586 ret = gpiod_set_debounce(ld->ad.desc, (unsigned int)val); in gpio_virtuser_debounce_set()
588 /* Don't propagate errno unknown to user-space. */ in gpio_virtuser_debounce_set()
589 return ret == -ENOTSUPP ? -EOPNOTSUPP : ret; in gpio_virtuser_debounce_set()
591 WRITE_ONCE(ld->debounce, (unsigned int)val); in gpio_virtuser_debounce_set()
605 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_consumer_read()
611 scoped_guard(mutex, &data->consumer_lock) in gpio_virtuser_consumer_read()
612 ret = snprintf(buf, sizeof(buf), "%s\n", data->consumer); in gpio_virtuser_consumer_read()
621 struct gpio_virtuser_line_data *data = file->private_data; in gpio_virtuser_consumer_write()
630 buf[strlen(buf) - 1] = '\0'; in gpio_virtuser_consumer_write()
632 ret = gpiod_set_consumer_name(data->ad.desc, buf); in gpio_virtuser_consumer_write()
636 scoped_guard(mutex, &data->consumer_lock) in gpio_virtuser_consumer_write()
637 strscpy(data->consumer, buf, sizeof(data->consumer)); in gpio_virtuser_consumer_write()
654 *val = atomic_read(&ld->irq_count); in gpio_virtuser_interrupts_get()
663 atomic_inc(&ld->irq_count); in gpio_virtuser_irq_handler()
674 return -EINVAL; in gpio_virtuser_interrupts_set()
677 irq = gpiod_to_irq(ld->ad.desc); in gpio_virtuser_interrupts_set()
686 ld->consumer, data); in gpio_virtuser_interrupts_set()
690 atomic_set(&ld->irq, irq); in gpio_virtuser_interrupts_set()
692 irq = atomic_xchg(&ld->irq, 0); in gpio_virtuser_interrupts_set()
756 ret = debugfs_create_file(attr->name, 0644, parent, data, in gpio_virtuser_create_debugfs_attrs()
757 attr->fops); in gpio_virtuser_create_debugfs_attrs()
775 return -ENOMEM; in gpio_virtuser_dbgfs_init_line_array_attrs()
777 data->ad.descs = descs; in gpio_virtuser_dbgfs_init_line_array_attrs()
781 return -ENOMEM; in gpio_virtuser_dbgfs_init_line_array_attrs()
783 data->ad.dbgfs_dir = debugfs_create_dir(name, dbgfs_entry); in gpio_virtuser_dbgfs_init_line_array_attrs()
784 if (IS_ERR(data->ad.dbgfs_dir)) in gpio_virtuser_dbgfs_init_line_array_attrs()
785 return PTR_ERR(data->ad.dbgfs_dir); in gpio_virtuser_dbgfs_init_line_array_attrs()
790 data->ad.dbgfs_dir, data); in gpio_virtuser_dbgfs_init_line_array_attrs()
805 return -ENOMEM; in gpio_virtuser_dbgfs_init_line_attrs()
807 data->ad.desc = desc; in gpio_virtuser_dbgfs_init_line_attrs()
808 strscpy(data->consumer, id); in gpio_virtuser_dbgfs_init_line_attrs()
809 atomic_set(&data->irq, 0); in gpio_virtuser_dbgfs_init_line_attrs()
810 atomic_set(&data->irq_count, 0); in gpio_virtuser_dbgfs_init_line_attrs()
814 return -ENOMEM; in gpio_virtuser_dbgfs_init_line_attrs()
816 ret = devm_mutex_init(dev, &data->consumer_lock); in gpio_virtuser_dbgfs_init_line_attrs()
820 data->ad.dbgfs_dir = debugfs_create_dir(name, dbgfs_entry); in gpio_virtuser_dbgfs_init_line_attrs()
821 if (IS_ERR(data->ad.dbgfs_dir)) in gpio_virtuser_dbgfs_init_line_attrs()
822 return PTR_ERR(data->ad.dbgfs_dir); in gpio_virtuser_dbgfs_init_line_attrs()
827 data->ad.dbgfs_dir, data); in gpio_virtuser_dbgfs_init_line_attrs()
839 char *dash = strrchr(prop->name, '-'); in gpio_virtuser_prop_is_gpio()
841 return dash && strcmp(dash, "-gpios") == 0; in gpio_virtuser_prop_is_gpio()
845 * If this is an OF-based system, then we iterate over properties and consider
846 * all whose names end in "-gpios". For configfs we expect an additional string
847 * array property - "gpio-virtuser,ids" - containing the list of all GPIO IDs
858 "gpio-virtuser,ids"); in gpio_virtuser_count_ids()
878 "gpio-virtuser,ids", in gpio_virtuser_get_ids()
885 dash = strrchr(prop->name, '-'); in gpio_virtuser_get_ids()
886 diff = dash - prop->name; in gpio_virtuser_get_ids()
888 tmp = devm_kmemdup(dev, prop->name, diff + 1, in gpio_virtuser_get_ids()
891 return -ENOMEM; in gpio_virtuser_get_ids()
902 struct device *dev = &pdev->dev; in gpio_virtuser_probe()
915 return dev_err_probe(dev, -EINVAL, "No GPIO IDs specified\n"); in gpio_virtuser_probe()
919 return -ENOMEM; in gpio_virtuser_probe()
947 for (j = 0; j < descs->ndescs; j++) { in gpio_virtuser_probe()
949 descs->desc[j], ids[i], in gpio_virtuser_probe()
962 { .compatible = "gpio-virtuser" },
969 .name = "gpio-virtuser",
999 snprintf(devname, sizeof(devname), "gpio-virtuser.%d", vdev->id); in gpio_virtuser_bus_notifier_call()
1006 vdev->driver_bound = true; in gpio_virtuser_bus_notifier_call()
1009 vdev->driver_bound = false; in gpio_virtuser_bus_notifier_call()
1015 complete(&vdev->probe_completion); in gpio_virtuser_bus_notifier_call()
1030 lockdep_assert_held(&dev->lock); in gpio_virtuser_device_is_live()
1032 return !!dev->pdev; in gpio_virtuser_device_is_live()
1079 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_key_show()
1081 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_key_show()
1083 return sprintf(page, "%s\n", entry->key ?: ""); in gpio_virtuser_lookup_entry_config_key_show()
1092 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_key_store()
1097 return -ENOMEM; in gpio_virtuser_lookup_entry_config_key_store()
1101 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_key_store()
1104 return -EBUSY; in gpio_virtuser_lookup_entry_config_key_store()
1106 kfree(entry->key); in gpio_virtuser_lookup_entry_config_key_store()
1107 entry->key = no_free_ptr(key); in gpio_virtuser_lookup_entry_config_key_store()
1120 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_offset_show()
1123 scoped_guard(mutex, &dev->lock) in gpio_virtuser_lookup_entry_config_offset_show()
1124 offset = entry->offset; in gpio_virtuser_lookup_entry_config_offset_show()
1135 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_offset_store()
1144 * Non-negative means: 'key' represents the label of the chip with in gpio_virtuser_lookup_entry_config_offset_store()
1148 * the greatest offset we can accept is (U16_MAX - 1). in gpio_virtuser_lookup_entry_config_offset_store()
1150 if (offset > (U16_MAX - 1)) in gpio_virtuser_lookup_entry_config_offset_store()
1151 return -EINVAL; in gpio_virtuser_lookup_entry_config_offset_store()
1153 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_offset_store()
1156 return -EBUSY; in gpio_virtuser_lookup_entry_config_offset_store()
1158 entry->offset = offset; in gpio_virtuser_lookup_entry_config_offset_store()
1170 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_get_flags()
1172 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_get_flags()
1174 return entry->flags; in gpio_virtuser_lookup_get_flags()
1184 repr = "open-drain"; in gpio_virtuser_lookup_entry_config_drive_show()
1186 repr = "open-source"; in gpio_virtuser_lookup_entry_config_drive_show()
1188 repr = "push-pull"; in gpio_virtuser_lookup_entry_config_drive_show()
1199 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_drive_store()
1201 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_drive_store()
1204 return -EBUSY; in gpio_virtuser_lookup_entry_config_drive_store()
1206 if (sysfs_streq(page, "push-pull")) { in gpio_virtuser_lookup_entry_config_drive_store()
1207 entry->flags &= ~(GPIO_OPEN_DRAIN | GPIO_OPEN_SOURCE); in gpio_virtuser_lookup_entry_config_drive_store()
1208 } else if (sysfs_streq(page, "open-drain")) { in gpio_virtuser_lookup_entry_config_drive_store()
1209 entry->flags &= ~GPIO_OPEN_SOURCE; in gpio_virtuser_lookup_entry_config_drive_store()
1210 entry->flags |= GPIO_OPEN_DRAIN; in gpio_virtuser_lookup_entry_config_drive_store()
1211 } else if (sysfs_streq(page, "open-source")) { in gpio_virtuser_lookup_entry_config_drive_store()
1212 entry->flags &= ~GPIO_OPEN_DRAIN; in gpio_virtuser_lookup_entry_config_drive_store()
1213 entry->flags |= GPIO_OPEN_SOURCE; in gpio_virtuser_lookup_entry_config_drive_store()
1215 count = -EINVAL; in gpio_virtuser_lookup_entry_config_drive_store()
1230 repr = "pull-up"; in gpio_virtuser_lookup_entry_config_pull_show()
1232 repr = "pull-down"; in gpio_virtuser_lookup_entry_config_pull_show()
1234 repr = "pull-disabled"; in gpio_virtuser_lookup_entry_config_pull_show()
1236 repr = "as-is"; in gpio_virtuser_lookup_entry_config_pull_show()
1247 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_pull_store()
1249 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_pull_store()
1252 return -EBUSY; in gpio_virtuser_lookup_entry_config_pull_store()
1254 if (sysfs_streq(page, "pull-up")) { in gpio_virtuser_lookup_entry_config_pull_store()
1255 entry->flags &= ~(GPIO_PULL_DOWN | GPIO_PULL_DISABLE); in gpio_virtuser_lookup_entry_config_pull_store()
1256 entry->flags |= GPIO_PULL_UP; in gpio_virtuser_lookup_entry_config_pull_store()
1257 } else if (sysfs_streq(page, "pull-down")) { in gpio_virtuser_lookup_entry_config_pull_store()
1258 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DISABLE); in gpio_virtuser_lookup_entry_config_pull_store()
1259 entry->flags |= GPIO_PULL_DOWN; in gpio_virtuser_lookup_entry_config_pull_store()
1260 } else if (sysfs_streq(page, "pull-disabled")) { in gpio_virtuser_lookup_entry_config_pull_store()
1261 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DOWN); in gpio_virtuser_lookup_entry_config_pull_store()
1262 entry->flags |= GPIO_PULL_DISABLE; in gpio_virtuser_lookup_entry_config_pull_store()
1263 } else if (sysfs_streq(page, "as-is")) { in gpio_virtuser_lookup_entry_config_pull_store()
1264 entry->flags &= ~(GPIO_PULL_UP | GPIO_PULL_DOWN | in gpio_virtuser_lookup_entry_config_pull_store()
1267 count = -EINVAL; in gpio_virtuser_lookup_entry_config_pull_store()
1291 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_active_low_store()
1299 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_active_low_store()
1302 return -EBUSY; in gpio_virtuser_lookup_entry_config_active_low_store()
1305 entry->flags |= GPIO_ACTIVE_LOW; in gpio_virtuser_lookup_entry_config_active_low_store()
1307 entry->flags &= ~GPIO_ACTIVE_LOW; in gpio_virtuser_lookup_entry_config_active_low_store()
1330 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_transitory_store()
1338 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_transitory_store()
1341 return -EBUSY; in gpio_virtuser_lookup_entry_config_transitory_store()
1344 entry->flags |= GPIO_TRANSITORY; in gpio_virtuser_lookup_entry_config_transitory_store()
1346 entry->flags &= ~GPIO_TRANSITORY; in gpio_virtuser_lookup_entry_config_transitory_store()
1370 guard(mutex)(&dev->lock); in gpio_virtuser_device_config_dev_name_show()
1372 pdev = dev->pdev; in gpio_virtuser_device_config_dev_name_show()
1374 return sprintf(page, "%s\n", dev_name(&pdev->dev)); in gpio_virtuser_device_config_dev_name_show()
1376 return sprintf(page, "gpio-sim.%d\n", dev->id); in gpio_virtuser_device_config_dev_name_show()
1387 scoped_guard(mutex, &dev->lock) in gpio_virtuser_device_config_live_show()
1399 lockdep_assert_held(&dev->lock); in gpio_virtuser_get_lookup_count()
1401 list_for_each_entry(lookup, &dev->lookup_list, siblings) in gpio_virtuser_get_lookup_count()
1402 count += list_count_nodes(&lookup->entry_list); in gpio_virtuser_get_lookup_count()
1415 lockdep_assert_held(&dev->lock); in gpio_virtuser_make_lookup_table()
1420 return -ENOMEM; in gpio_virtuser_make_lookup_table()
1422 table->dev_id = kasprintf(GFP_KERNEL, "gpio-virtuser.%d", dev->id); in gpio_virtuser_make_lookup_table()
1423 if (!table->dev_id) in gpio_virtuser_make_lookup_table()
1424 return -ENOMEM; in gpio_virtuser_make_lookup_table()
1426 list_for_each_entry(lookup, &dev->lookup_list, siblings) { in gpio_virtuser_make_lookup_table()
1427 list_for_each_entry(entry, &lookup->entry_list, siblings) { in gpio_virtuser_make_lookup_table()
1428 table->table[i] = in gpio_virtuser_make_lookup_table()
1429 GPIO_LOOKUP_IDX(entry->key, in gpio_virtuser_make_lookup_table()
1430 entry->offset < 0 ? U16_MAX : entry->offset, in gpio_virtuser_make_lookup_table()
1431 lookup->con_id, i, entry->flags); in gpio_virtuser_make_lookup_table()
1437 dev->lookup_table = no_free_ptr(table); in gpio_virtuser_make_lookup_table()
1452 num_ids = list_count_nodes(&dev->lookup_list); in gpio_virtuser_make_device_swnode()
1456 return ERR_PTR(-ENOMEM); in gpio_virtuser_make_device_swnode()
1458 list_for_each_entry(lookup, &dev->lookup_list, siblings) in gpio_virtuser_make_device_swnode()
1459 ids[i++] = lookup->con_id; in gpio_virtuser_make_device_swnode()
1461 properties[0] = PROPERTY_ENTRY_STRING_ARRAY_LEN("gpio-virtuser,ids", in gpio_virtuser_make_device_swnode()
1475 lockdep_assert_held(&dev->lock); in gpio_virtuser_device_activate()
1477 if (list_empty(&dev->lookup_list)) in gpio_virtuser_device_activate()
1478 return -ENODATA; in gpio_virtuser_device_activate()
1485 pdevinfo.name = "gpio-virtuser"; in gpio_virtuser_device_activate()
1486 pdevinfo.id = dev->id; in gpio_virtuser_device_activate()
1495 reinit_completion(&dev->probe_completion); in gpio_virtuser_device_activate()
1496 dev->driver_bound = false; in gpio_virtuser_device_activate()
1497 bus_register_notifier(&platform_bus_type, &dev->bus_notifier); in gpio_virtuser_device_activate()
1501 bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); in gpio_virtuser_device_activate()
1506 wait_for_completion(&dev->probe_completion); in gpio_virtuser_device_activate()
1507 bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); in gpio_virtuser_device_activate()
1509 if (!dev->driver_bound) { in gpio_virtuser_device_activate()
1512 return -ENXIO; in gpio_virtuser_device_activate()
1515 dev->pdev = pdev; in gpio_virtuser_device_activate()
1525 lockdep_assert_held(&dev->lock); in gpio_virtuser_device_deactivate()
1527 swnode = dev_fwnode(&dev->pdev->dev); in gpio_virtuser_device_deactivate()
1528 platform_device_unregister(dev->pdev); in gpio_virtuser_device_deactivate()
1530 dev->pdev = NULL; in gpio_virtuser_device_deactivate()
1531 gpiod_remove_lookup_table(dev->lookup_table); in gpio_virtuser_device_deactivate()
1532 kfree(dev->lookup_table); in gpio_virtuser_device_deactivate()
1547 guard(mutex)(&dev->lock); in gpio_virtuser_device_config_live_store()
1550 return -EPERM; in gpio_virtuser_device_config_live_store()
1573 struct gpio_virtuser_device *dev = entry->parent->parent; in gpio_virtuser_lookup_entry_config_group_release()
1575 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_entry_config_group_release()
1577 list_del(&entry->siblings); in gpio_virtuser_lookup_entry_config_group_release()
1579 kfree(entry->key); in gpio_virtuser_lookup_entry_config_group_release()
1600 to_gpio_virtuser_lookup(&group->cg_item); in gpio_virtuser_make_lookup_entry_group()
1601 struct gpio_virtuser_device *dev = lookup->parent; in gpio_virtuser_make_lookup_entry_group()
1603 guard(mutex)(&dev->lock); in gpio_virtuser_make_lookup_entry_group()
1606 return ERR_PTR(-EBUSY); in gpio_virtuser_make_lookup_entry_group()
1611 return ERR_PTR(-ENOMEM); in gpio_virtuser_make_lookup_entry_group()
1613 config_group_init_type_name(&entry->group, name, in gpio_virtuser_make_lookup_entry_group()
1615 entry->flags = GPIO_LOOKUP_FLAGS_DEFAULT; in gpio_virtuser_make_lookup_entry_group()
1616 entry->parent = lookup; in gpio_virtuser_make_lookup_entry_group()
1617 list_add_tail(&entry->siblings, &lookup->entry_list); in gpio_virtuser_make_lookup_entry_group()
1619 return &no_free_ptr(entry)->group; in gpio_virtuser_make_lookup_entry_group()
1625 struct gpio_virtuser_device *dev = lookup->parent; in gpio_virtuser_lookup_config_group_release()
1627 guard(mutex)(&dev->lock); in gpio_virtuser_lookup_config_group_release()
1629 list_del(&lookup->siblings); in gpio_virtuser_lookup_config_group_release()
1631 kfree(lookup->con_id); in gpio_virtuser_lookup_config_group_release()
1654 to_gpio_virtuser_device(&group->cg_item); in gpio_virtuser_make_lookup_group()
1656 if (strlen(name) > (GPIO_VIRTUSER_NAME_BUF_LEN - 1)) in gpio_virtuser_make_lookup_group()
1657 return ERR_PTR(-E2BIG); in gpio_virtuser_make_lookup_group()
1659 guard(mutex)(&dev->lock); in gpio_virtuser_make_lookup_group()
1662 return ERR_PTR(-EBUSY); in gpio_virtuser_make_lookup_group()
1667 return ERR_PTR(-ENOMEM); in gpio_virtuser_make_lookup_group()
1669 lookup->con_id = kstrdup(name, GFP_KERNEL); in gpio_virtuser_make_lookup_group()
1670 if (!lookup->con_id) in gpio_virtuser_make_lookup_group()
1671 return ERR_PTR(-ENOMEM); in gpio_virtuser_make_lookup_group()
1673 config_group_init_type_name(&lookup->group, name, in gpio_virtuser_make_lookup_group()
1675 INIT_LIST_HEAD(&lookup->entry_list); in gpio_virtuser_make_lookup_group()
1676 lookup->parent = dev; in gpio_virtuser_make_lookup_group()
1677 list_add_tail(&lookup->siblings, &dev->lookup_list); in gpio_virtuser_make_lookup_group()
1679 return &no_free_ptr(lookup)->group; in gpio_virtuser_make_lookup_group()
1686 guard(mutex)(&dev->lock); in gpio_virtuser_device_config_group_release()
1691 mutex_destroy(&dev->lock); in gpio_virtuser_device_config_group_release()
1692 ida_free(&gpio_virtuser_ida, dev->id); in gpio_virtuser_device_config_group_release()
1718 return ERR_PTR(-ENOMEM); in gpio_virtuser_config_make_device_group()
1720 dev->id = ida_alloc(&gpio_virtuser_ida, GFP_KERNEL); in gpio_virtuser_config_make_device_group()
1721 if (dev->id < 0) in gpio_virtuser_config_make_device_group()
1722 return ERR_PTR(dev->id); in gpio_virtuser_config_make_device_group()
1724 config_group_init_type_name(&dev->group, name, in gpio_virtuser_config_make_device_group()
1726 mutex_init(&dev->lock); in gpio_virtuser_config_make_device_group()
1727 INIT_LIST_HEAD(&dev->lookup_list); in gpio_virtuser_config_make_device_group()
1728 dev->bus_notifier.notifier_call = gpio_virtuser_bus_notifier_call; in gpio_virtuser_config_make_device_group()
1729 init_completion(&dev->probe_completion); in gpio_virtuser_config_make_device_group()
1731 return &no_free_ptr(dev)->group; in gpio_virtuser_config_make_device_group()
1746 .ci_namebuf = "gpio-virtuser",
1772 gpio_virtuser_dbg_root = debugfs_create_dir("gpio-virtuser", NULL); in gpio_virtuser_init()
1801 MODULE_DESCRIPTION("Virtual GPIO consumer module");