regmap_write

int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
{
    int ret;

    if (!IS_ALIGNED(reg, map->reg_stride))
        return -EINVAL;

    map->lock(map->lock_arg);

    ret = _regmap_write(map, reg, val);

    map->unlock(map->lock_arg);

    return ret;
}
这里直接调用lock/unlock的环境中调用_regmap_write
int _regmap_write(struct regmap *map, unsigned int reg,
          unsigned int val)
{
    int ret;
//根据map得到,这里的context是在__regmap_init_mmio_clk 中的regmap_mmio_gen_context 申请空间并赋值的,其类型是struct regmap_mmio_context *ctx;
    void *context = _regmap_map_get_context(map);
//检查这个reg是否可写,一般这里会返回true
    if (!regmap_writeable(map, reg))
        return -EIO;
//假如map->cache_bypass 等于true的话,则这段if条件不执行
    if (!map->cache_bypass && !map->defer_caching) {
        ret = regcache_write(map, reg, val);
        if (ret != 0)
            return ret;
        if (map->cache_only) {
            map->cache_dirty = true;
            return 0;
        }
    }
//如果打来LOG_DEVICE的话,则可以在kernel log中检测到每次通过regmap_write写寄存器的值
#ifdef LOG_DEVICE
    if (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
        dev_info(map->dev, "%x <= %x\n", reg, val);
#endif

    trace_regmap_reg_write(map, reg, val);
这里调用map->reg_write
    return map->reg_write(context, reg, val);
}

这里的map->reg_write是在__regmap_init 中赋值的
if (!bus) {
706            map->reg_read  = config->reg_read;
707            map->reg_write = config->reg_write;
708    
709            map->defer_caching = false;
710            goto skip_format_initialization;
711        }
这里假定bus为null
而config->reg_read是在regmap_mmio_gen_context 函数中赋值,这里以32bit的寄存器为例

266            case 32:
267                ctx->reg_read = regmap_mmio_read32le;
268                ctx->reg_write = regmap_mmio_write32le;
269                break;

162    static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
163                             unsigned int reg)
164    {
165        return readl(ctx->regs + reg);
166    }

46    #define build_mmio_read(name, size, type, reg, barrier) \
47    static inline type name(const volatile void __iomem *addr) \
48    { type ret; asm volatile("mov" size " %1,%0":reg (ret) \
49    :"m" (*(volatile type __force *)addr) barrier); return ret; }
55    
56    build_mmio_read(readb, "b", unsigned char, "=q", :"memory")
57    build_mmio_read(readw, "w", unsigned short, "=r", :"memory")
58    build_mmio_read(readl, "l", unsigned int, "=r", :"memory")

原来最后也是通过readl 来写寄存器的。

你可能感兴趣的:(Linux,源码分析)