Linux的移植(3)
时钟驱动
在SoC中,晶振、PLL、驱动和门等会形成一个时钟树形结构,针对时钟部件碎片化的问题,Linux实现了一套统一的时钟框架,称为通用时钟。
这套统一的时钟框架包含两部分:硬件无关时钟定义及API、硬件相关接口及回调。
硬件无关部分
在内核中,时钟在软件层被抽象成了clk结构体,其主要是作为clk核心层内部的描述。同时还有时钟的操作接口的定义,这些接口向上为上层软件提供统一的时钟操作API,向下为硬件驱动实现提供标准的驱动实现框架。其定义如下:
1 |
|
硬件相关部分
对于具体SoC而言,需要去实现自己SoC的clk驱动,clk驱动的实现采用内核提供的clk框架,在clk框架中,clk_hw用于驱动中对于硬件时钟的描述,在clk驱动中主要实现的是硬件的初始化和将clk硬件实例注册到clk子系统的核心层。在clk核心层中,clk结构体就将clk硬件和clk相关操作联系起来,使得上层软件接口与下层硬件接口相通。clk_hw的定义如下所示。
1 | struct clk_hw { |
从clk核心层到具体芯片clk驱动的调用顺序为:
clk_enable(clk)=》clk->ops->enable(clk->hw)
目前内核通常通过设备树来描述电路板上的时钟树,以及时钟与设备之间的绑定关系。因此在clk驱动中需要从设备树获取相关信息,注册时钟控制器为一个时钟树的提供者,并建立各个时钟与索引的映射。
要分析clk驱动的具体实现,可参考drivers/clk/目录下的各不同平台关于clk驱动的实现。
dmaengine
dmaengine是一套通用的DMA驱动框架,该框架为具体使用DMA通道的设备驱动提供了一套统一的API,而且定义了用具体的DMA控制器实现这一套API的方法。
我们可以基于dmaengine所定义的标准化的DMA控制方法,来简单地实现各种类型的DMA传输工作。对于特定硬件DMA驱动,所要完成的主要工作就是实现封装在内核dma_device结构体中的那些成员函数。
dma_device实例通过dma_async_device_register()接口注册;在其中的成员函数中,一般通过链表管理DMA描述符的运行、free等队列;成员函数device_issue_pending()用于实现DMA传输开启的功能;当DMA传输完成后,驱动中注册的中断服务程序的顶半部和或底半部会调用DMA描述符dma_async_tx_descriptor中设置的回调函数。
典型的dmaengine驱动可参考drivers/dma/sirf-dma.c、drivers/dma/omap-dma.c等
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com
文章标题:Linux的移植(3)
本文作者:红尘追风
发布时间:2016-12-21, 18:49:28
原始链接:http://www.micernel.com/2016/12/21/Linux%E7%9A%84%E7%A7%BB%E6%A4%8D(3)/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。