参考:
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函数: