1. 程式人生 > 其它 >裝置驅動-memory-region和of_reserved_mem_device_init將裝置與reserved mem關聯

裝置驅動-memory-region和of_reserved_mem_device_init將裝置與reserved mem關聯

上一篇: RESERVEDMEM_OF_DECLARE 對 dts 中預留的記憶體進行匹配和初始化

https://www.cnblogs.com/zhangzhiwei122/p/16125744.html

 

另外,dts 中,通常使用 memory-region 將裝置和 reserved memory 關聯起來,如下:

 

 

 fb0 通過 memory-region 關聯到  display_reserved 這塊 reserved memory 上面;

 

of_reserved_mem_device_init

include/linux/of_reserved_mem.h 

傳入引數 dev, 找到 dev 中 memory-region 對應的 reserved memory .然後呼叫 reserved_memory 物件的  ops->device_init( reserved_memory * rmem, device * dev );

  81static inline int of_reserved_mem_device_init(struct device *dev)
  82{
  83        return of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
  84}

 

reserved memory 結構體中的ops 

include/linux/of_reserved_mem.h 

  11struct reserved_mem {
  12        const char                      *name;
  
13 unsigned long fdt_node; 14 unsigned long phandle; 15 const struct reserved_mem_ops *ops; 16 phys_addr_t base; 17 phys_addr_t size; 18 void *priv;
19}; 20 21struct reserved_mem_ops { 22 int (*device_init)(struct reserved_mem *rmem, 23 struct device *dev); 24 void (*device_release)(struct reserved_mem *rmem, 25 struct device *dev); 26};

 

of_reserved_mem_device_init_by_idx 

從  of_reserved_mem_device_init 進入時,dev , dev_node, idx = 0 ;

 321int of_reserved_mem_device_init_by_idx(struct device *dev,
 322                                       struct device_node *np, int idx)
 323{
 324        struct rmem_assigned_device *rd;
 325        struct device_node *target;
 326        struct reserved_mem *rmem;
 327        int ret;
 328
 329        if (!np || !dev)
 330                return -EINVAL;
 331
 332        target = of_parse_phandle(np, "memory-region", idx);
 333        if (!target)
 334                return -ENODEV;
 335
 336        if (!of_device_is_available(target)) {
 337                of_node_put(target);
 338                return 0;
 339        }
 340
 341        rmem = __find_rmem(target);
 342        of_node_put(target);
 343
 344        if (!rmem || !rmem->ops || !rmem->ops->device_init)
 345                return -EINVAL;
 346
 347        rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
 348        if (!rd)
 349                return -ENOMEM;
 350
 351        ret = rmem->ops->device_init(rmem, dev);
 352        if (ret == 0) {
 353                rd->dev = dev;
 354                rd->rmem = rmem;
 355
 356                mutex_lock(&of_rmem_assigned_device_mutex);
 357                list_add(&rd->list, &of_rmem_assigned_device_list);
 358                mutex_unlock(&of_rmem_assigned_device_mutex);
 359
 360                dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
 361        } else {
 362                kfree(rd);
 363        }
 364
 365        return ret;
 366}
 367EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx);

332 ~ 342 通過 memory-region 找對應的 reserved memory 

344 ~ 345 檢查 有 rmem->ops   rmem->ops->device_init 函式 

 

351 呼叫  rmem->ops->device_init(rmem, dev) ; 

成功的話,就 將 建立的物件 reserved_memory_device  加入到  of_rmem_assigned_device_list 裡面 ,記錄 rmem 分配到 device 裡面了。