drivers/greybus/svc.c
Source file repositories/reference/linux-study-clean/drivers/greybus/svc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/greybus/svc.c- Extension
.c- Size
- 35836 bytes
- Lines
- 1408
- Domain
- Driver Families
- Bucket
- drivers/greybus
- 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/debugfs.hlinux/kstrtox.hlinux/workqueue.hlinux/greybus.hlinux/string_choices.h
Detected Declarations
struct gb_svc_deferred_requestfunction endo_id_showfunction ap_intf_id_showfunction intf_eject_storefunction watchdog_showfunction watchdog_storefunction watchdog_action_showfunction watchdog_action_storefunction gb_svc_pwrmon_rail_count_getfunction gb_svc_pwrmon_rail_names_getfunction gb_svc_pwrmon_sample_getfunction gb_svc_pwrmon_intf_sample_getfunction gb_svc_intf_device_idfunction gb_svc_intf_ejectfunction gb_svc_intf_vsys_setfunction gb_svc_intf_refclk_setfunction gb_svc_intf_unipro_setfunction gb_svc_intf_activatefunction gb_svc_intf_resumefunction gb_svc_dme_peer_getfunction gb_svc_dme_peer_setfunction gb_svc_connection_createfunction gb_svc_connection_destroyfunction gb_svc_route_createfunction gb_svc_route_destroyfunction gb_svc_intf_set_power_modefunction gb_svc_intf_set_power_mode_hibernatefunction gb_svc_pingfunction gb_svc_version_requestfunction pwr_debugfs_voltage_readfunction pwr_debugfs_current_readfunction pwr_debugfs_power_readfunction gb_svc_pwrmon_debugfs_initfunction gb_svc_debugfs_initfunction gb_svc_debugfs_exitfunction gb_svc_hellofunction list_for_each_entryfunction list_for_each_entryfunction gb_svc_process_hello_deferredfunction gb_svc_process_module_insertedfunction gb_svc_process_module_removedfunction gb_svc_process_intf_oopsfunction gb_svc_process_intf_mailbox_eventfunction gb_svc_process_deferred_requestfunction gb_svc_queue_deferred_requestfunction gb_svc_intf_reset_recvfunction gb_svc_module_inserted_recvfunction gb_svc_module_removed_recv
Annotated Snippet
static const struct file_operations pwrmon_debugfs_voltage_fops = {
.read = pwr_debugfs_voltage_read,
};
static const struct file_operations pwrmon_debugfs_current_fops = {
.read = pwr_debugfs_current_read,
};
static const struct file_operations pwrmon_debugfs_power_fops = {
.read = pwr_debugfs_power_read,
};
static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc)
{
int i;
size_t bufsize;
struct dentry *dent;
struct gb_svc_pwrmon_rail_names_get_response *rail_names;
u8 rail_count;
dent = debugfs_create_dir("pwrmon", svc->debugfs_dentry);
if (IS_ERR_OR_NULL(dent))
return;
if (gb_svc_pwrmon_rail_count_get(svc, &rail_count))
goto err_pwrmon_debugfs;
if (!rail_count || rail_count > GB_SVC_PWRMON_MAX_RAIL_COUNT)
goto err_pwrmon_debugfs;
bufsize = struct_size(rail_names, name, rail_count);
rail_names = kzalloc_flex(*rail_names, name, rail_count);
if (!rail_names)
goto err_pwrmon_debugfs;
svc->pwrmon_rails = kzalloc_objs(*svc->pwrmon_rails, rail_count);
if (!svc->pwrmon_rails)
goto err_pwrmon_debugfs_free;
if (gb_svc_pwrmon_rail_names_get(svc, rail_names, bufsize))
goto err_pwrmon_debugfs_free;
for (i = 0; i < rail_count; i++) {
struct dentry *dir;
struct svc_debugfs_pwrmon_rail *rail = &svc->pwrmon_rails[i];
char fname[GB_SVC_PWRMON_RAIL_NAME_BUFSIZE];
snprintf(fname, sizeof(fname), "%s",
(char *)&rail_names->name[i]);
rail->id = i;
rail->svc = svc;
dir = debugfs_create_dir(fname, dent);
debugfs_create_file("voltage_now", 0444, dir, rail,
&pwrmon_debugfs_voltage_fops);
debugfs_create_file("current_now", 0444, dir, rail,
&pwrmon_debugfs_current_fops);
debugfs_create_file("power_now", 0444, dir, rail,
&pwrmon_debugfs_power_fops);
}
kfree(rail_names);
return;
err_pwrmon_debugfs_free:
kfree(rail_names);
kfree(svc->pwrmon_rails);
svc->pwrmon_rails = NULL;
err_pwrmon_debugfs:
debugfs_remove(dent);
}
static void gb_svc_debugfs_init(struct gb_svc *svc)
{
svc->debugfs_dentry = debugfs_create_dir(dev_name(&svc->dev),
gb_debugfs_get());
gb_svc_pwrmon_debugfs_init(svc);
}
static void gb_svc_debugfs_exit(struct gb_svc *svc)
{
debugfs_remove_recursive(svc->debugfs_dentry);
kfree(svc->pwrmon_rails);
svc->pwrmon_rails = NULL;
}
static int gb_svc_hello(struct gb_operation *op)
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/kstrtox.h`, `linux/workqueue.h`, `linux/greybus.h`, `linux/string_choices.h`.
- Detected declarations: `struct gb_svc_deferred_request`, `function endo_id_show`, `function ap_intf_id_show`, `function intf_eject_store`, `function watchdog_show`, `function watchdog_store`, `function watchdog_action_show`, `function watchdog_action_store`, `function gb_svc_pwrmon_rail_count_get`, `function gb_svc_pwrmon_rail_names_get`.
- Atlas domain: Driver Families / drivers/greybus.
- 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.