参考:
devres in linux driver - sammei - 博客园
1、devres_alloc函数:
源码路径:include/linux/device.h
static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
{
return devres_alloc_node(release, size, gfp, NUMA_NO_NODE);
}
devres_alloc_node函数源码路径:drivers/base/devres.c
void * devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, int nid)
{
struct devres *dr;
dr = alloc_dr(release, size, gfp | __GFP_ZERO, nid);
return dr->data;
}
static __always_inline struct devres * alloc_dr(dr_release_t release,
size_t size, gfp_t gfp, int nid)
{
size_t tot_size = sizeof(struct devres) + size;
struct devres *dr;
memset(dr, 0, offsetof(struct devres, data)); //将data成员前面的内存都清零
INIT_LIST_HEAD(&dr->node.entry);
dr->node.release = release;
return dr;
}
2、struct devres结构体定义:
struct devres {
struct devres_node node;
u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
};
3、举例:
struct regmap *__devm_regmap_init(struct device *dev,...)
{
struct regmap **ptr, *regmap;
//data指向分配的资源*ptr,所以指针的指针是二维指针
ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL);
......
}
4、devres_add函数:
void devres_add(struct device *dev, void *res)
{
struct devres *dr = container_of(res, struct devres, data);
......
add_dr(dev, &dr->node);
}
static void add_dr(struct device *dev, struct devres_node *node)
{
list_add_tail(&node->entry, &dev->devres_head);
}
5、其它API函数: