drivers/media/cec/core/cec-core.c
Source file repositories/reference/linux-study-clean/drivers/media/cec/core/cec-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/cec/core/cec-core.c- Extension
.c- Size
- 11417 bytes
- Lines
- 446
- Domain
- Driver Families
- Bucket
- drivers/media
- 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/errno.hlinux/init.hlinux/kernel.hlinux/kmod.hlinux/mm.hlinux/module.hlinux/slab.hlinux/string.hlinux/types.hcec-priv.h
Detected Declarations
function cec_devnode_releasefunction cec_devnode_registerfunction cec_devnode_unregisterfunction cec_error_inj_writefunction cec_error_inj_showfunction cec_error_inj_openfunction cec_register_adapterfunction cec_unregister_adapterfunction cec_delete_adapterfunction cec_devnode_initfunction cec_devnode_exitmodule init cec_devnode_initexport cec_allocate_adapterexport cec_register_adapterexport cec_unregister_adapterexport cec_delete_adapter
Annotated Snippet
static const struct bus_type cec_bus_type = {
.name = CEC_NAME,
};
/*
* Register a cec device node
*
* The registration code assigns minor numbers and registers the new device node
* with the kernel. An error is returned if no free minor number can be found,
* or if the registration of the device node fails.
*
* Zero is returned on success.
*
* Note that if the cec_devnode_register call fails, the release() callback of
* the cec_devnode structure is *not* called, so the caller is responsible for
* freeing any data.
*/
static int __must_check cec_devnode_register(struct cec_devnode *devnode,
struct module *owner)
{
int minor;
int ret;
/* Part 1: Find a free minor number */
mutex_lock(&cec_devnode_lock);
minor = find_first_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES);
if (minor == CEC_NUM_DEVICES) {
mutex_unlock(&cec_devnode_lock);
pr_err("could not get a free minor\n");
return -ENFILE;
}
set_bit(minor, cec_devnode_nums);
mutex_unlock(&cec_devnode_lock);
devnode->minor = minor;
devnode->dev.bus = &cec_bus_type;
devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor);
devnode->dev.release = cec_devnode_release;
dev_set_name(&devnode->dev, "cec%d", devnode->minor);
device_initialize(&devnode->dev);
/* Part 2: Initialize and register the character device */
cdev_init(&devnode->cdev, &cec_devnode_fops);
devnode->cdev.owner = owner;
kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
devnode->registered = true;
ret = cdev_device_add(&devnode->cdev, &devnode->dev);
if (ret) {
devnode->registered = false;
pr_err("%s: cdev_device_add failed\n", __func__);
goto clr_bit;
}
return 0;
clr_bit:
mutex_lock(&cec_devnode_lock);
clear_bit(devnode->minor, cec_devnode_nums);
mutex_unlock(&cec_devnode_lock);
return ret;
}
/*
* Unregister a cec device node
*
* This unregisters the passed device. Future open calls will be met with
* errors.
*
* This function can safely be called if the device node has never been
* registered or has already been unregistered.
*/
static void cec_devnode_unregister(struct cec_adapter *adap)
{
struct cec_devnode *devnode = &adap->devnode;
struct cec_fh *fh;
mutex_lock(&devnode->lock);
/* Check if devnode was never registered or already unregistered */
if (!devnode->registered || devnode->unregistered) {
mutex_unlock(&devnode->lock);
return;
}
devnode->registered = false;
devnode->unregistered = true;
mutex_lock(&devnode->lock_fhs);
list_for_each_entry(fh, &devnode->fhs, list)
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/errno.h`, `linux/init.h`, `linux/kernel.h`, `linux/kmod.h`, `linux/mm.h`, `linux/module.h`, `linux/slab.h`.
- Detected declarations: `function cec_devnode_release`, `function cec_devnode_register`, `function cec_devnode_unregister`, `function cec_error_inj_write`, `function cec_error_inj_show`, `function cec_error_inj_open`, `function cec_register_adapter`, `function cec_unregister_adapter`, `function cec_delete_adapter`, `function cec_devnode_init`.
- Atlas domain: Driver Families / drivers/media.
- 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.