drivers/staging/greybus/camera.c
Source file repositories/reference/linux-study-clean/drivers/staging/greybus/camera.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/greybus/camera.c- Extension
.c- Size
- 32423 bytes
- Lines
- 1368
- Domain
- Driver Families
- Bucket
- drivers/staging
- 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/fs.hlinux/kernel.hlinux/module.hlinux/slab.hlinux/string.hlinux/uaccess.hlinux/vmalloc.hlinux/greybus.hgb-camera.hgreybus_protocols.h
Detected Declarations
struct gb_camera_debugfs_bufferstruct gb_camerastruct gb_camera_stream_configstruct gb_camera_fmt_infostruct ap_csi_config_requeststruct gb_camera_debugfs_entryenum gb_camera_debugs_buffer_idenum gb_camera_statefunction gb_camera_operation_sync_flagsfunction gb_camera_get_max_pkt_sizefunction gb_camera_configure_streams_validate_responsefunction gb_camera_set_intf_power_modefunction gb_camera_set_power_modefunction gb_camera_setup_data_connectionfunction gb_camera_teardown_data_connectionfunction gb_camera_capabilitiesfunction gb_camera_configure_streamsfunction gb_camera_capturefunction gb_camera_flushfunction gb_camera_request_handlerfunction gb_camera_mbus_to_gbfunction gb_camera_gb_to_mbusfunction gb_camera_op_capabilitiesfunction gb_camera_op_configure_streamsfunction gb_camera_op_capturefunction gb_camera_op_flushfunction gb_camera_debugfs_capabilitiesfunction gb_camera_debugfs_configure_streamsfunction gb_camera_debugfs_capturefunction gb_camera_debugfs_flushfunction gb_camera_debugfs_readfunction gb_camera_debugfs_writefunction gb_camera_debugfs_openfunction gb_camera_debugfs_initfunction gb_camera_debugfs_cleanupfunction gb_camera_cleanupfunction gb_camera_release_modulefunction gb_camera_probefunction gb_camera_disconnectfunction gb_camera_suspendfunction gb_camera_resume
Annotated Snippet
static const struct file_operations gb_camera_debugfs_ops = {
.open = gb_camera_debugfs_open,
.read = gb_camera_debugfs_read,
.write = gb_camera_debugfs_write,
};
static int gb_camera_debugfs_init(struct gb_camera *gcam)
{
struct gb_connection *connection = gcam->connection;
char dirname[27];
unsigned int i;
/*
* Create root debugfs entry and a file entry for each camera operation.
*/
snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id,
gcam->bundle->id);
gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get());
gcam->debugfs.buffers =
vmalloc(array_size(GB_CAMERA_DEBUGFS_BUFFER_MAX,
sizeof(*gcam->debugfs.buffers)));
if (!gcam->debugfs.buffers)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
const struct gb_camera_debugfs_entry *entry =
&gb_camera_debugfs_entries[i];
gcam->debugfs.buffers[i].length = 0;
debugfs_create_file_aux(entry->name, entry->mask,
gcam->debugfs.root, gcam, entry,
&gb_camera_debugfs_ops);
}
return 0;
}
static void gb_camera_debugfs_cleanup(struct gb_camera *gcam)
{
debugfs_remove_recursive(gcam->debugfs.root);
vfree(gcam->debugfs.buffers);
}
/* -----------------------------------------------------------------------------
* Init & Cleanup
*/
static void gb_camera_cleanup(struct gb_camera *gcam)
{
gb_camera_debugfs_cleanup(gcam);
mutex_lock(&gcam->mutex);
if (gcam->data_connection) {
gb_connection_disable(gcam->data_connection);
gb_connection_destroy(gcam->data_connection);
gcam->data_connection = NULL;
}
if (gcam->connection) {
gb_connection_disable(gcam->connection);
gb_connection_destroy(gcam->connection);
gcam->connection = NULL;
}
mutex_unlock(&gcam->mutex);
}
static void gb_camera_release_module(struct kref *ref)
{
struct gb_camera_module *cam_mod =
container_of(ref, struct gb_camera_module, refcount);
kfree(cam_mod->priv);
}
static int gb_camera_probe(struct gb_bundle *bundle,
const struct greybus_bundle_id *id)
{
struct gb_connection *conn;
struct gb_camera *gcam;
u16 mgmt_cport_id = 0;
u16 data_cport_id = 0;
unsigned int i;
int ret;
/*
* The camera bundle must contain exactly two CPorts, one for the
* camera management protocol and one for the camera data protocol.
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/fs.h`, `linux/kernel.h`, `linux/module.h`, `linux/slab.h`, `linux/string.h`, `linux/uaccess.h`, `linux/vmalloc.h`.
- Detected declarations: `struct gb_camera_debugfs_buffer`, `struct gb_camera`, `struct gb_camera_stream_config`, `struct gb_camera_fmt_info`, `struct ap_csi_config_request`, `struct gb_camera_debugfs_entry`, `enum gb_camera_debugs_buffer_id`, `enum gb_camera_state`, `function gb_camera_operation_sync_flags`, `function gb_camera_get_max_pkt_size`.
- Atlas domain: Driver Families / drivers/staging.
- 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.