Linux CommonClock Framework分析之二 CCF子系统内部实现简述

     上一章我们对CCF子系统进行了简述,本章我们将介绍CCF子系统内部设计,说明CCF子系统内部是如何实现的。我们主要从如下几点说明CCF子系统的内部设计流程:

一、 CCF子系统内部数据结构的定义与关联

 

二、CCF子系统提供的接口

 

 

一、 CCF子系统内部数据结构的定义与关联

       在我们学习linux内核各子系统模块时,通过其内部数据结构的定义及关联,即可大致掌握其实现过程及所需要提供的接口等等(本次分析CCF子系统是基于linux4.4内核的)。

如下即为CCF子系统内部数据结构间的关联,可以分为两大部分:

  1. 在clk source注册时,提供clk source的初始配置信息(包含该clk source的操作接口、parent clk的个数及每一个parent clk的名称),即为图中绿色圈圈中的内容,涉及的数据结构主要为struct clk_init_data、struct clk_ops。
  2. Clk_soure注册完成后,clk provider、clk consumer之间的关联信息。

   在下图的数据结构间的关联中,涉及了CCF中clk provider、clk consumer的主要抽象内容,下面对这几个数据结构进行说明:

  1. struct clk_hw则为硬件时钟源的逻辑抽象可以理解为clk  provider;
  2. struct clk_core则可以理解为clk provider的driver,包含了clk provider的访问方法、时钟频率设定、支持的时钟频率、父时钟源的个数以及父时钟源的名称等内容;
  3. 而struct clk则可以理解clk  consumer,包含了指向clk provider的指针、使用者的设备名称、使用者所定义的时钟别名(con_id)。
  4. struct clk_ops则主要是clk provider的操作接口,包含prepare与unprepare操作接口(这两个接口执行时允许sleep,主要是用的互斥锁)、enable与disable接口(这两个接口执行时不允许sleep,里面使用了自旋锁),也包含了速率设置接口、重新计算速率接口、parent设置与获取接口等等,通过这些接口可实现时钟频率的修改、父时钟源的选择、时钟的使能与否等功能。

 

      从我们分析的这么多的外设子系统而言,读者有没有发现该CCF子系统的数据结构中没有使用设备驱动模型,没包含struct device类型的变量。这应该是clk provider主要为系统提供时钟,而一些系统clk的初始化及使能会早于设备驱动模型的初始化,因此没有使用设备驱动模型,但是还是使用了引用计数功能的。

 

上面介绍的是一个clk provider的数据结构关联,而多个clk provier之间有什么关联呢?

级联clk provider的关联

     因为clk之间是支持多级级联的,而一个clk既可以由多个可选的父时钟源、也可以向多个子时钟提供时钟源,因此多个clk provider之间会形成树形的关联结构,如下图所示。

 

 

系统中所有注册的clk provider的关联

 

       上面主要说明了存在父子关系的clk provider之间的关联,那系统上所有已注册的clk provider之间有什么关联呢?这主要有两种情况:

  1. 若一个clk provider是一个root clk provider,即其不需要父节点提供时钟,则将其插入到链表clk_root_list;
  2. 若一个clk provider不是一个root clk provider,但是其父节点尚没有注册到系统中,则将其插入到链表clk_orphan_list中。

     下图是以链表clk_root_list为例画出系统中已注册clk provider之间的关联。即所有的root clk provider均在链表clk_root_list中;而所有的child clk provider则主要在其parent clk provider的child_node链表中。

 

     当系统中注册一个clk provider中,其即会在上述的clk provider关联链表中,在上面的关联图中,大家有没有发现一个问题?上面的关联图中涉及多个链表,那如果搜索一个clk provider岂不是很麻烦呢?这就牵扯到已注册clk provider的搜索问题。

 

已注册clk provider的搜索问题

     当clk consumer需要使用一个clk provider,则涉及到clk provider的搜索,在完成clk provider的搜索后,方可创建clk consumer对象 (struct clk),并加入到clk provider的clks链表中。但是若通过clk_root_list链表进行一级一级的搜索显然时耗费时间的,那如何优化搜索时间呢?还记得我们之前在regulator子系统、pinctrl子系统的分析时,均实现了对应的map关系,从而优化搜索时间,而在CCF子系统中,也提供了类似的map操作。

我们知道LINUX内核的升级过程中增加了OF机制(即设备树),而LINUX内核呢也并没有强制要求所有

的arch均支持OF,因此现在的内核既有支持OF机制,也存在不支持OF机制。因此在CCF子系统的map操作,也涉及到这两块的实现。

 

设备树机制下clk_core的map

     若系统支持设备树时,则主要通过struct device_node作为搜索关键字(一个struct device_node对应设备树中的一个节点)。

  1. 在clk provider driver中,当clk provider完成注册后,针对支持设备树机制的内核,则clk provider driver会将该clk provider的map(即struct of_clk_provider)信息,加入到链表of_clk_providers中;
  2. 在clk consumer中,则在该clk consumer的设备数据节点中引用clk provider对应的节点即可。

不支持设备树机制下clk_core的map

 

若系统不支持设备树时,则主要通过device name、clk config name作为搜索关键字(若对于一个clk provider,其名称为sys_clk4,其可为uart、mmc提供时钟(名称分别为uart_clk、mmc_clk),则可以通过名称“uart_clk/mmc_clk”作为搜索关键字)。

  1. 在clk provider driver中,当clk provider完成注册后,则clk provider driver会将该clk provider的map(即struct clk_lookup类型的变量)信息,加入到链表clocks中(如针对上面的例子,则创建两个strct clk_lookup类型的变量(con_id分别为“uart_clk”、“mmc_clk”),并加入到clocks链表中),完成该clk provider driver map的注册;
  2. 在clk consumer中,则在该clk consumer的驱动中,在链表clocks中搜索即可找到对应的clk provider driver。

 

 

 

二、CCF子系统提供的接口

我们理解上述一中的内容后,基本上也可大致知道CCF子系统需要提供的接口,大致可分为如下几类:

  1. clk provider的注册接口,该接口实现什么功能呢,实现一个clk provider的逻辑抽象对象struct clk_hw类型变量的创建、clk provider driver的创建(struct clk_core)、clk provider的操作接口、父子clk provider的关联等等信息,主要完成上述图一、图二、图三的关联,主要是接口clk_register;
  2. 提供clk provider的map映射,方便clk provider的查找,主要完成上述图四中的关联,主要是接口of_clk_add_provider、clkdev_add;
  3. 提供时钟使能、去使能、时钟频率设置及更新、parent clk provider设置与查找等接口,这主要是对struct clk_ops提供接口的封装,提供统一的对外接口,内部再根据具体的clk provider driver实现的clk_ops操作完成与具体的hw clk的通信,主要为接口clk_enable、clk_disable、clk_prepare、clk_unprepare、clk_set_rate等;
  4. 提供clk consumer的创建及获取接口,主要是通过clk provider map链表中查找对应的clk provider,并创建该clk provider的使用者,并把使用者的信息放到该clk provider driver的链表中。主要为接口clk_get、clk_put、

基本上就是提供以上几种类型的接口。

 

 

 

 

以上即为本章的主要内容,本章主要介绍CCF子系统内部的实现机制,希望对大家有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值