drivers/gpio/gpio-aggregator.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-aggregator.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-aggregator.c- Extension
.c- Size
- 45461 bytes
- Lines
- 1739
- Domain
- Driver Families
- Bucket
- drivers/gpio
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitmap.hlinux/bitops.hlinux/configfs.hlinux/ctype.hlinux/delay.hlinux/export.hlinux/idr.hlinux/kernel.hlinux/list.hlinux/lockdep.hlinux/mod_devicetable.hlinux/module.hlinux/mutex.hlinux/overflow.hlinux/platform_device.hlinux/property.hlinux/slab.hlinux/spinlock.hlinux/string.hlinux/gpio/consumer.hlinux/gpio/driver.hlinux/gpio/forwarder.hlinux/gpio/machine.h
Detected Declarations
struct gpio_aggregatorstruct gpio_aggregator_linestruct gpio_aggregator_pdev_metastruct gpiochip_fwd_timingstruct gpiochip_fwdfunction gpio_aggregator_allocfunction gpio_aggregator_freefunction gpio_aggregator_add_gpiofunction gpio_aggregator_is_activefunction gpio_aggregator_is_activatingfunction gpio_aggregator_count_linesfunction gpio_aggregator_line_allocfunction gpio_aggregator_line_addfunction list_for_each_entryfunction gpio_aggregator_line_delfunction gpio_aggregator_free_linesfunction list_for_each_entry_safefunction gpio_fwd_requestfunction gpio_fwd_get_directionfunction gpio_fwd_direction_inputfunction gpio_fwd_direction_outputfunction gpio_fwd_getfunction gpio_fwd_get_multiplefunction gpio_fwd_get_multiple_lockedfunction gpio_fwd_delayfunction gpio_fwd_setfunction gpio_fwd_set_multiplefunction for_each_set_bitfunction gpio_fwd_set_multiple_lockedfunction gpio_fwd_set_configfunction gpio_fwd_to_irqfunction gpiochip_fwd_delay_of_xlatefunction gpiochip_fwd_setup_delay_linefunction gpiochip_fwd_setup_delay_linefunction gpiochip_fwd_gpio_requestfunction gpiochip_fwd_gpio_get_directionfunction gpiochip_fwd_gpio_direction_outputfunction gpiochip_fwd_gpio_direction_inputfunction gpiochip_fwd_gpio_getfunction gpiochip_fwd_gpio_get_multiplefunction gpiochip_fwd_gpio_setfunction gpiochip_fwd_gpio_set_multiplefunction gpiochip_fwd_gpio_set_configfunction gpiochip_fwd_gpio_to_irqfunction gpiochip_fwd_desc_addfunction gpiochip_fwd_desc_freefunction gpiochip_fwd_registerfunction gpiochip_fwd_create
Annotated Snippet
static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
const char *buf, size_t count)
{
struct gpio_aggregator_pdev_meta meta = { .init_via_sysfs = true };
char name[CONFIGFS_ITEM_NAME_LEN];
struct gpio_aggregator *aggr;
struct platform_device *pdev;
int res;
if (!try_module_get(THIS_MODULE))
return -ENOENT;
/* kernfs guarantees string termination, so count + 1 is safe */
res = gpio_aggregator_alloc(&aggr, count + 1);
if (res)
goto put_module;
memcpy(aggr->args, buf, count + 1);
aggr->init_via_sysfs = true;
aggr->lookups = kzalloc_flex(*aggr->lookups, table, 1);
if (!aggr->lookups) {
res = -ENOMEM;
goto free_ga;
}
aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->id);
if (!aggr->lookups->dev_id) {
res = -ENOMEM;
goto free_table;
}
scnprintf(name, sizeof(name), "%s.%d", AGGREGATOR_LEGACY_PREFIX, aggr->id);
config_group_init_type_name(&aggr->group, name, &gpio_aggregator_device_type);
/* Expose to configfs */
res = configfs_register_group(&gpio_aggregator_subsys.su_group,
&aggr->group);
if (res)
goto free_dev_id;
res = gpio_aggregator_parse(aggr);
if (res)
goto unregister_group;
gpiod_add_lookup_table(aggr->lookups);
pdev = platform_device_register_data(NULL, DRV_NAME, aggr->id, &meta, sizeof(meta));
if (IS_ERR(pdev)) {
res = PTR_ERR(pdev);
goto remove_table;
}
aggr->pdev = pdev;
module_put(THIS_MODULE);
return count;
remove_table:
gpiod_remove_lookup_table(aggr->lookups);
unregister_group:
configfs_unregister_group(&aggr->group);
free_dev_id:
kfree(aggr->lookups->dev_id);
free_table:
kfree(aggr->lookups);
free_ga:
gpio_aggregator_free(aggr);
put_module:
module_put(THIS_MODULE);
return res;
}
static struct driver_attribute driver_attr_gpio_aggregator_new_device =
__ATTR(new_device, 0200, NULL, gpio_aggregator_new_device_store);
static void gpio_aggregator_destroy(struct gpio_aggregator *aggr)
{
scoped_guard(mutex, &aggr->lock) {
if (gpio_aggregator_is_activating(aggr) ||
gpio_aggregator_is_active(aggr))
gpio_aggregator_deactivate(aggr);
}
gpio_aggregator_free_lines(aggr);
configfs_unregister_group(&aggr->group);
kfree(aggr);
}
static ssize_t gpio_aggregator_delete_device_store(struct device_driver *driver,
const char *buf, size_t count)
{
Annotation
- Immediate include surface: `linux/bitmap.h`, `linux/bitops.h`, `linux/configfs.h`, `linux/ctype.h`, `linux/delay.h`, `linux/export.h`, `linux/idr.h`, `linux/kernel.h`.
- Detected declarations: `struct gpio_aggregator`, `struct gpio_aggregator_line`, `struct gpio_aggregator_pdev_meta`, `struct gpiochip_fwd_timing`, `struct gpiochip_fwd`, `function gpio_aggregator_alloc`, `function gpio_aggregator_free`, `function gpio_aggregator_add_gpio`, `function gpio_aggregator_is_active`, `function gpio_aggregator_is_activating`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.