drivers/base/devres.c
Source file repositories/reference/linux-study-clean/drivers/base/devres.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/base/devres.c- Extension
.c- Size
- 34910 bytes
- Lines
- 1349
- Domain
- Driver Families
- Bucket
- drivers/base
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/device.hlinux/module.hlinux/slab.hlinux/percpu.hasm/sections.hbase.htrace.h
Detected Declarations
struct devresstruct devres_groupstruct action_devresstruct devres_actionstruct pages_devresfunction devres_node_initfunction free_nodefunction devres_set_node_dbginfofunction devres_dbgfunction devres_logfunction group_open_releasefunction check_dr_sizefunction dr_node_releasefunction dr_node_freefunction add_drfunction replace_drfunction devres_for_each_resfunction free_drfunction devres_allocfunction devres_node_addfunction devres_allocfunction list_for_each_entry_reversefunction devres_node_removefunction devres_destroyfunction devres_releasefunction remove_nodesfunction release_nodesfunction list_for_each_entry_safe_reversefunction devres_release_allfunction devres_group_freefunction list_for_each_entry_reversefunction devres_close_groupfunction devres_remove_groupfunction devres_release_groupfunction devm_action_matchfunction devm_action_releasefunction devm_action_freefunction __devm_add_actionfunction voidfunction list_for_each_entry_reversefunction devm_is_action_addedfunction voidfunction devm_remove_action_nowarnfunction devm_release_actionfunction devm_kmalloc_releasefunction kreallocfunction devm_kmallocfunction devm_kmemdup_const
Annotated Snippet
struct devres {
struct devres_node node;
dr_release_t release;
/*
* Some archs want to perform DMA into kmalloc caches
* and need a guaranteed alignment larger than
* the alignment of a 64-bit integer.
* Thus we use ARCH_DMA_MINALIGN for data[] which will force the same
* alignment for struct devres when allocated by kmalloc().
*/
u8 __aligned(ARCH_DMA_MINALIGN) data[];
};
struct devres_group {
struct devres_node node[2];
void *id;
int color;
/* -- 8 pointers */
};
void devres_node_init(struct devres_node *node,
dr_node_release_t release,
dr_node_free_t free_node)
{
INIT_LIST_HEAD(&node->entry);
node->release = release;
node->free_node = free_node;
}
static inline void free_node(struct devres_node *node)
{
node->free_node(node);
}
void devres_set_node_dbginfo(struct devres_node *node, const char *name,
size_t size)
{
node->name = name;
node->size = size;
}
#ifdef CONFIG_DEBUG_DEVRES
static int log_devres = 0;
module_param_named(log, log_devres, int, S_IRUGO | S_IWUSR);
static void devres_dbg(struct device *dev, struct devres_node *node,
const char *op)
{
if (unlikely(log_devres))
dev_err(dev, "DEVRES %3s %p %s (%zu bytes)\n",
op, node, node->name, node->size);
}
#else /* CONFIG_DEBUG_DEVRES */
#define devres_dbg(dev, node, op) do {} while (0)
#endif /* CONFIG_DEBUG_DEVRES */
static void devres_log(struct device *dev, struct devres_node *node,
const char *op)
{
trace_devres_log(dev, op, node, node->name, node->size);
devres_dbg(dev, node, op);
}
/*
* Release functions for devres group. These callbacks are used only
* for identification.
*/
static void group_open_release(struct device *dev, struct devres_node *node)
{
/* noop */
}
static void group_close_release(struct device *dev, struct devres_node *node)
{
/* noop */
}
static struct devres_group *node_to_group(struct devres_node *node)
{
if (node->release == &group_open_release)
return container_of(node, struct devres_group, node[0]);
if (node->release == &group_close_release)
return container_of(node, struct devres_group, node[1]);
return NULL;
}
static bool check_dr_size(size_t size, size_t *tot_size)
{
/* We must catch any near-SIZE_MAX cases that could overflow. */
if (unlikely(check_add_overflow(sizeof(struct devres),
Annotation
- Immediate include surface: `linux/device.h`, `linux/module.h`, `linux/slab.h`, `linux/percpu.h`, `asm/sections.h`, `base.h`, `trace.h`.
- Detected declarations: `struct devres`, `struct devres_group`, `struct action_devres`, `struct devres_action`, `struct pages_devres`, `function devres_node_init`, `function free_node`, `function devres_set_node_dbginfo`, `function devres_dbg`, `function devres_log`.
- Atlas domain: Driver Families / drivers/base.
- Implementation status: integration 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.