1. 内核版本
5.2.0
2. 请看devm_regmap_init_i2c (include/linux/regmap.h)
/**
* devm_regmap_init_i2c() - Initialise managed register map
*
* @i2c: Device that will be interacted with
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer
* to a struct regmap. The regmap will be automatically freed by the
* device management code.*/
#define devm_regmap_init_i2c(i2c, config) __regmap_lockdep_wrapper(__devm_regmap_init_i2c, #config,
i2c, config)
3. 看看__regmap_lockdep_wrapper
/** Wrapper for regmap_init macros to include a unique lockdep key and name
* for each call. No-op if CONFIG_LOCKDEP is not set.
*
* @fn: Real function to call (in the form __[*_]regmap_init[_*])
* @name: Config variable name (#config in the calling macro)
**/#define __regmap_lockdep_wrapper(fn, name, ...) (
({static structlock_class_key _key;
fn(__VA_ARGS__,&_key,
KBUILD_BASENAME":"__stringify(__LINE__)":""(" name ")->lock");
})
)
4. KBUILD_BASENAME的定义在哪里?
在编译时由编译选项-D提供,如此处为:
-DKBUILD_BASENAME='"regmap_i2c"'
5. 展开
假设__LINE__等于99行,那么
(
({
static structlock_class_key _key;
__devm_regmap_init_i2c(__VA_ARGS__, &_key,
"regmap_i2c:99:config->lock");})
)
6. 看看__devm_regmap_init_i2c的执行路径
__devm_regmap_init_i2c
-> regmap_get_i2c_bus
-> __devm_regmap_init
-> devres_alloc
-> __regmap_init
7. 重点分析__regmap_init
map->dev =dev;
map->bus =bus;
map->bus_context =bus_context;
map->max_register = config->max_register;
map->wr_table = config->wr_table;
map->rd_table = config->rd_table;
map->volatile_table = config->volatile_table;
map->precious_table = config->precious_table;
map->wr_noinc_table = config->wr_noinc_table;
map->rd_noinc_table = config->rd_noinc_table;
map->writeable_reg = config->writeable_reg;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
map->writeable_noinc_reg = config->writeable_noinc_reg;
map->readable_noinc_reg = config->readable_noinc_reg;
map->cache_type = config->cache_type;
总结:
做的主要工作即为填充map结构体