完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
花了一个entity的链接简图,忽略了link
其中彩色线条是enable的,黑线是disable 使用上面的图来分析 v4l2_pipeline_pm_use,从stream_cif_mipi_id0这个entity开始 v4l2_pipeline_pm_use(&vnode->vdev.entity, 1); v4l2_pipeline_pm_use() int v4l2_pipeline_pm_use(struct media_entity *entity, int use) { /* * 一切都是基于media的,所以要先找到media * use传入的是1 */ struct media_device *mdev = entity->graph_obj.mdev; int change = use ? 1 : -1; int ret; mutex_lock(&mdev->graph_mutex); /* Apply use count to node. */ /* * 更新entity使用计数 */ entity->use_count += change; WARN_ON(entity->use_count < 0); /* Apply power change to connected non-nodes. */ /* * 上面这句话的意思是 * 将电源更改应用于连接的非节点 * 非节点是什么意思?非video节点?所以这里更改的事subdev节点? */ /* * medv->pm_count_walk 这个变量实在media_device_register_entity中 * 被赋值的 * 该变量类型是 struct media_graph * 可以看上一篇文章中的一个graph变量 */ ret = pipeline_pm_power(entity, change, &mdev->pm_count_walk); if (ret < 0) entity->use_count -= change; mutex_unlock(&mdev->graph_mutex); return ret; } v4l2_pipeline_pm_use() -> pipeline_pm_power() static int pipeline_pm_power(struct media_entity *entity, int change, struct media_graph *graph) { struct media_entity *first = entity; int ret = 0; if (!change) return 0; media_graph_walk_start(graph, entity); while (!ret && (entity = media_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(entity)) ret = pipeline_pm_power_one(entity, change); if (!ret) return ret; ... } media_graph_walk_next 代码量有些大,会占用不少篇幅,所以还是看上一篇文章吧,这篇文章只会贴一些关键代码用于理解分析 这里贴一下log的部分打印 [ 77.491726] rkcif rkcif_mipi_lvds: begin graph walk at 'stream_cif_mipi_id0' [ 77.491730] entity->name 0 is stream_cif_mipi_id0 [ 77.491743] is backlink! [ 77.491757] entity->name 2 is rockchip-mipi-csi2 [ 77.491777] rkcif rkcif_mipi_lvds: walk: pushing 'rockchip-mipi-csi2' on stack [ 77.491781] entity->name 0 is rockchip-mipi-csi2 [ 77.491794] is backlink! [ 77.491808] entity->name 2 is rockchip-mipi-dphy-rx [ 77.491828] rkcif rkcif_mipi_lvds: walk: pushing 'rockchip-mipi-dphy-rx' on stack [ 77.491832] entity->name 0 is rockchip-mipi-dphy-rx [ 77.491847] is link! [ 77.491860] entity->name 1 is rockchip-mipi-csi2 [ 77.491880] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-csi2' (already seen) [ 77.491884] entity->name 0 is rockchip-mipi-dphy-rx [ 77.491898] is backlink! [ 77.491912] entity->name 2 is m01_f_imx291 1-001a [ 77.491931] rkcif rkcif_mipi_lvds: walk: pushing 'm01_f_imx291 1-001a' on stack [ 77.491935] entity->name 0 is m01_f_imx291 1-001a [ 77.491949] is link! [ 77.491960] entity->name 1 is rockchip-mipi-dphy-rx [ 77.491974] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-dphy-rx' (already seen) [ 77.491982] rkcif rkcif_mipi_lvds: walk: returning entity 'm01_f_imx291 1-001a' 其中media_graph_walk_next中 #define link_top(en) ((en)->stack[(en)->top].link) #define stack_top(en) ((en)->stack[(en)->top].entity) struct media_entity *media_graph_walk_next(struct media_graph *graph) { struct media_entity *entity; ... while (link_top(graph) != &stack_top(graph)->links) media_graph_walk_iter(graph); entity = stack_pop(graph); dev_dbg(entity->graph_obj.mdev->dev, "walk: returning entity '%s'n", entity->name); return entity; } 退出while循环的条件是什么? &stack_top(graph) -> links 是链表头的地址,link_top(graph) 是links链表上的成员的地址 当两者相等的时候,也就是说links链表上的遍历完成的时候,就会退出while。 根据log,解释一下过程 /* * media_graph_walk_start 中打印,top = 1 */ [ 77.491726] rkcif rkcif_mipi_lvds: begin graph walk at 'stream_cif_mipi_id0' /* * 找到了stream_cif_mipi_id0的backlink * 因为stream_cif_mipi_id0没有source pad,所以没有link只有backlink * 通过backlink找到了source entity rockchip-mipi-csi2 */ [ 77.491730] entity->name 0 is stream_cif_mipi_id0 [ 77.491743] is backlink! [ 77.491757] entity->name 2 is rockchip-mipi-csi2 /* * 简图中可以知道 stream_cif_mipi_id0:0 <---> rockchip-mipi-csi2:1 * 这2个pad是enable的 * 所以这里会入栈 * top = 2 */ [ 77.491777] rkcif rkcif_mipi_lvds: walk: pushing 'rockchip-mipi-csi2' on stack /* * 由于执行了一次入栈操作,top的值发生了改变 * 所以这里不会在继续遍历stream_cif_mipi_id0的links * 而是去遍历rockchip-mipi-csi2的links * 首先遍历的是backlink * 这就找到了source entity rockchip-mipi-dphy-rx */ [ 77.491781] entity->name 0 is rockchip-mipi-csi2 [ 77.491794] is backlink! [ 77.491808] entity->name 2 is rockchip-mipi-dphy-rx /* * rockchip-mipi-csi2:0 <---> rockchip-mipi-dphy-rx:1 * top = 3 * 入栈操作 */ [ 77.491828] rkcif rkcif_mipi_lvds: walk: pushing 'rockchip-mipi-dphy-rx' on stack /* * 于是遍历rockchip-mipi-dphy-rx的links * 首先是link,对于是link还是backlink,还是看驱动中links挂载的顺序 * 使用link的时候,是向后走,这样就会找到sink entity rockchip-mipi-csi2 * 由于之前stream_cif_mipi_id0操作的时候,已经访问过rockchip-mipi-csi2了 * 所以会跳过rockchip-mipi-csi2 */ [ 77.491832] entity->name 0 is rockchip-mipi-dphy-rx [ 77.491847] is link! [ 77.491860] entity->name 1 is rockchip-mipi-csi2 [ 77.491880] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-csi2' (already seen) /* * 因为没有执行入栈操作,所以这里会继续遍历rockchip-mipi-dphy-rx的links * 这次找到了backlink * 向前找到了 source entity m01_f_imx291 1-001a */ [ 77.491884] entity->name 0 is rockchip-mipi-dphy-rx [ 77.491898] is backlink! [ 77.491912] entity->name 2 is m01_f_imx291 1-001a /* * rockchip-mipi-dphy-rx:0 <----> m01_f_imx291 1-001a:1 * top = 4 * 入栈操作 */ [ 77.491931] rkcif rkcif_mipi_lvds: walk: pushing 'm01_f_imx291 1-001a' on stack /* * 入栈操作导致top值改变 * 这里遍历m01_f_imx291 1-001a links * 由于没有sink pad,所以只有link,没有backlink */ [ 77.491935] entity->name 0 is m01_f_imx291 1-001a [ 77.491949] is link! [ 77.491960] entity->name 1 is rockchip-mipi-dphy-rx /* * 通过link,向后找到了rockchip-mipi-dphy-rx * 但是在rockchip-mipi-csi2操作中rockchip-mipi-dphy-rx已经访问过了 */ [ 77.491974] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-dphy-rx' (already seen) /* * 由于没有入栈操作 * 所以继续遍历m01_f_imx291 1-001a links * 由于只有一个link,所以就出现了满足上面分析的退出while的条件 */ [ 77.491982] rkcif rkcif_mipi_lvds: walk: returning entity 'm01_f_imx291 1-001a' 此时对应的栈内数据如下 while (!ret && (entity = media_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(entity)) ret = pipeline_pm_power_one(entity, change); 接着会判断返回的entity是不是subdev,是的话,会调core到s_power 这里和上一篇文章分析的get_remote_terminal_sensor不一样,这里不会判断是不是camera,而退出 继续通过log分析 /* * 这里为什么会返回entity 'rockchip-mipi-dphy-rx' * 因为media_greaph_walk_next有个出栈操作 * 之前top = 4 对应imx291 * 出栈后 top = 3 对应 rockchip-mipi-dphy-rx * 所以这里会遍历rockchip-mipi-dphy-rx的links * 之前已经遍历了其backlink及link。而且只有这2个link,之前已经遍历完了 * 所以满足while退出条件 */ [ 193.566342] rkcif rkcif_mipi_lvds: walk: returning entity 'rockchip-mipi-dphy-rx' /* * 由于有进行了出栈操作 * top = 2 * 于是对应 entity rockchip-mipi-csi2 * 遍历rockchip-mipi-csi2的links * 这里计算一下rockchip-mipi-csi2有几个link * rockchip-mipi-csi2:0 ---- rockchip-mipi-dphy-rx:1 1个backlink enable * rockchip-mipi-csi2:1 ---- stream_cif_mipi_id0:0 1个link enable * rockchip-mipi-csi2:1 ---- stream_cif_mipi_id1:0 1个link disable * rockchip-mipi-csi2:1 ---- stream_cif_mipi_id2:0 1个link disable * rockchip-mipi-csi2:1 ---- stream_cif_mipi_id3:0 1个link disable * * rockchip-mipi-csi2:2 ---- stream_cif_mipi_id0:0 1个link disable * rockchip-mipi-csi2:2 ---- stream_cif_mipi_id1:0 1个link enable * rockchip-mipi-csi2:2 ---- stream_cif_mipi_id2:0 1个link disable * rockchip-mipi-csi2:2 ---- stream_cif_mipi_id3:0 1个link disable * * rockchip-mipi-csi2:3 ---- stream_cif_mipi_id0:0 1个link disable * rockchip-mipi-csi2:3 ---- stream_cif_mipi_id1:0 1个link disable * rockchip-mipi-csi2:3 ---- stream_cif_mipi_id2:0 1个link enable * rockchip-mipi-csi2:3 ---- stream_cif_mipi_id3:0 1个link disable * * rockchip-mipi-csi2:4 ---- stream_cif_mipi_id0:0 1个link disable * rockchip-mipi-csi2:4 ---- stream_cif_mipi_id1:0 1个link disable * rockchip-mipi-csi2:4 ---- stream_cif_mipi_id2:0 1个link disable * rockchip-mipi-csi2:4 ---- stream_cif_mipi_id3:0 1个link enable * * 也就是17个links * 上面的log分析中,知道backlink已经被遍历了,还有16个links * 于是继续遍历links */ [ 193.566361] entity->name 0 is rockchip-mipi-csi2 [ 193.566375] is link! [ 193.566388] entity->name 1 is stream_cif_mipi_id0 /* * entity 'stream_cif_mipi_id0' 已经被访问过了,所以跳过 * 无入栈操作 */ [ 193.566405] rkcif rkcif_mipi_lvds: walk: skipping entity 'stream_cif_mipi_id0' (already seen) /* * 遍历下一个link * 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id1':0 disable * 无入栈操作 */ [ 193.566414] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id1':0 /* * 遍历下一个link * 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id2':0 disable * 无入栈操作 */ [ 193.566421] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id2':0 /* * 遍历下一个link * 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id3':0 disable * 无入栈操作 */ [ 193.566428] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id3':0 /* * rockchip-mipi-csi2:1的links遍历完了 * 继续遍历rockchip-mipi-csi2:2的links * rockchip-mipi-csi2:2 找到了 'stream_cif_mipi_id0':0 * 但是'stream_cif_mipi_id0':0之前已经访问过了 */ [ 193.566436] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id0':0 /* * rockchip-mipi-csi2:2 <---> stream_cif_mipi_id1:0 enable * 找到了 entity stream_cif_mipi_id1 * 于是进行入栈操作 * top = 3 */ [ 193.566439] entity->name 0 is rockchip-mipi-csi2 [ 193.566451] is link! [ 193.566463] entity->name 1 is stream_cif_mipi_id1 [ 193.566479] rkcif rkcif_mipi_lvds: walk: pushing 'stream_cif_mipi_id1' on stack /* * 由于入栈操作 * 这里就找到了刚入栈的 entity stream_cif_mipi_id1 * 于是遍历其links * 找到了 rockchip-mipi-csi2':1 * 但是 rockchip-mipi-csi2':1 --- 'stream_cif_mipi_id1':0 disable */ [ 193.566486] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id1':0 [ 193.566489] entity->name 0 is stream_cif_mipi_id1 [ 193.566498] is backlink! [ 193.566508] entity->name 2 is rockchip-mipi-csi2 /* * 继续遍历links * 找到了entity 'rockchip-mipi-csi2':2 * 'rockchip-mipi-csi2':2 <---> 'stream_cif_mipi_id1':0 enable * 但是 'rockchip-mipi-csi2':2 也访问过了 */ [ 193.566525] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-csi2' (already seen) /* * 'rockchip-mipi-csi2':3 --- 'stream_cif_mipi_id1':0 disable */ [ 193.566532] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id1':0 /* * 'rockchip-mipi-csi2':4 --- 'stream_cif_mipi_id1':0 disable */ [ 193.566540] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id1':0 /* * stream_cif_mipi_id1 links遍历完了,出栈操作 * top = 2 * 对应 entity rockchip-mipi-csi2 */ [ 193.566545] rkcif rkcif_mipi_lvds: walk: returning entity 'stream_cif_mipi_id1' /* * 继续遍历 entity rockchip-mipi-csi2:2的links * * 'rockchip-mipi-csi2':2 --- 'stream_cif_mipi_id2':0 disable */ [ 193.566552] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id2':0 /* * 'rockchip-mipi-csi2':2 --- 'stream_cif_mipi_id3':0 disable */ [ 193.566560] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id3':0 /* * 'rockchip-mipi-csi2':2 遍历完了 * 下面开始遍历 'rockchip-mipi-csi2':3 * 'rockchip-mipi-csi2':3 --- 'stream_cif_mipi_id0':0 disable */ [ 193.566568] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id0':0 /* * 'rockchip-mipi-csi2':3 --- 'stream_cif_mipi_id1':0 disable */ [ 193.566575] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id1':0 /* * 'rockchip-mipi-csi2':3 <---> 'stream_cif_mipi_id2':0 enable */ [ 193.566578] entity->name 0 is rockchip-mipi-csi2 [ 193.566591] is link! [ 193.566603] entity->name 1 is stream_cif_mipi_id2 /* * 入栈操作 * top = 3 */ [ 193.566619] rkcif rkcif_mipi_lvds: walk: pushing 'stream_cif_mipi_id2' on stack /* * 遍历stream_cif_mipi_id2 的links * 'rockchip-mipi-csi2':1 已经被访问过了 */ [ 193.566626] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id2':0 /* * 'rockchip-mipi-csi2':2 已经被访问过了 */ [ 193.566633] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id2':0 /* * 'rockchip-mipi-csi2':3 <---> 'stream_cif_mipi_id2':0 enable * 但是'rockchip-mipi-csi2':3 也被访问过了 * 所以也不会出现入栈操作 */ [ 193.566637] entity->name 0 is stream_cif_mipi_id2 [ 193.566648] is backlink! [ 193.566663] entity->name 2 is rockchip-mipi-csi2 [ 193.566678] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-csi2' (already seen) /* * 'rockchip-mipi-csi2':4 --- 'stream_cif_mipi_id2':0 disable */ [ 193.566685] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id2':0 /* * stream_cif_mipi_id2 遍历完成 * 进行出栈操作 * top = 2 */ [ 193.566691] rkcif rkcif_mipi_lvds: walk: returning entity 'stream_cif_mipi_id2' /* * 由于出栈操作 * 现在又对应entity rockchip-mipi-csi2 * 继续遍历 'rockchip-mipi-csi2':3 * 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id3':0 disable */ [ 193.566698] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id3':0 /* * 'rockchip-mipi-csi2':3 遍历完了,遍历'rockchip-mipi-csi2':4 * 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id0':0 disable */ [ 193.566705] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id0':0 /* * * 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id1':0 disable */ [ 193.566720] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id1':0 /* * * 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id2':0 disable */ [ 193.566734] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id2':0 /* * 'rockchip-mipi-csi2':4 <---> 'stream_cif_mipi_id3':0 enable */ [ 193.566743] entity->name 0 is rockchip-mipi-csi2 [ 193.566764] is link! [ 193.566783] entity->name 1 is stream_cif_mipi_id3 /* * stream_cif_mipi_id3 入栈 * top = 3 */ [ 193.566801] rkcif rkcif_mipi_lvds: walk: pushing 'stream_cif_mipi_id3' on stack /* * 遍历 stream_cif_mipi_id3的links * 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id3':0 disable */ [ 193.566809] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':1 -> 'stream_cif_mipi_id3':0 /* * 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id3':0 disable */ [ 193.566817] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id3':0 /* * 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id3':0 disable */ [ 193.566823] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id3':0 /* * * 'rockchip-mipi-csi2':4 <---> 'stream_cif_mipi_id3':0 enable */ [ 193.566827] entity->name 0 is stream_cif_mipi_id3 [ 193.566838] is backlink! [ 193.566851] entity->name 2 is rockchip-mipi-csi2 /* * 由于* 'rockchip-mipi-csi2':4 已经访问过了 */ [ 193.566866] rkcif rkcif_mipi_lvds: walk: skipping entity 'rockchip-mipi-csi2' (already seen) /* * stream_cif_mipi_id3 遍历完 * 出栈操作 * top = 2 */ [ 193.566872] rkcif rkcif_mipi_lvds: walk: returning entity 'stream_cif_mipi_id3' /* * rockchip-mipi-csi2 遍历完 * 出栈操作 * top = 1 */ [ 193.566877] rkcif rkcif_mipi_lvds: walk: returning entity 'rockchip-mipi-csi2' /* * 此时对应 entity stream_cif_mipi_id0 * 继续遍历 stream_cif_mipi_id0 的links * 之前遍历了'rockchip-mipi-csi2':1 * 所以现在从 'rockchip-mipi-csi2':2开始 * 'rockchip-mipi-csi2':2 --- 'stream_cif_mipi_id0':0 disable */ [ 193.566887] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':2 -> 'stream_cif_mipi_id0':0 /* * 'rockchip-mipi-csi2':3 --- 'stream_cif_mipi_id0':0 disable */ [ 193.566894] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':3 -> 'stream_cif_mipi_id0':0 /* * 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id0':0 di***ale */ [ 193.566901] rkcif rkcif_mipi_lvds: walk: skipping disabled link 'rockchip-mipi-csi2':4 -> 'stream_cif_mipi_id0':0 /* * stream_cif_mipi_id0 遍历完成 * 出栈操作 * top = 0 */ [ 193.566907] rkcif rkcif_mipi_lvds: walk: returning entity 'stream_cif_mipi_id0' /* * top = 0 已经没有数据了,退出。。 */ |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
626 浏览 0 评论
887 浏览 1 评论
784 浏览 1 评论
1997 浏览 1 评论
3242 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 19:26 , Processed in 0.539433 second(s), Total 44, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号