前面我们已经完成了CCF子系统的分析,也说明了如何实现CCF驱动,本章为该专栏的最后一篇文章,
本章我们将实现一个虚拟的gpio clk gate驱动。本章大概分为如下几个章节:
一、 本次驱动开发涉及的知识点
二、clk provider driver的实现流程说明
三、gpio clk gate driver驱动设计
一、 本次驱动开发涉及的知识点
本次驱动实践主要涉及如下几个方面的知识点:
- Platform device、platform drvier
- Gpio 驱动使用
- Clk provider驱动开发流程
二、clk provider driver的实现流程说明
关于clk provider driver的开发流程,在上一篇文章中已经做了说明,此处再说明一下,主要实现
流程包括如下两步:
- 完成clk的注册,主要是调用clk_register接口,完成上述章节一所述的内容;
- 完成该clk provider的map,这种map机制可以理解为定义了clk consumer与clk_provider的映射关系,即该clk provider可以给哪些clk consumer提供时钟(如针对非设备树模式,则定义了clk consumer的设备名称、clk consumer的时钟使用名称),而clk provider的map存在两种方式:
- 若linux不支持设备树机制,则通过调用接口clk_register_clkdev,完成这种映射操作(即完成下图中“非设备树模式下clk_core的map”)。
- 若linux支持设备树机制,则通过调用接口of_clk_add_provider,完成map操作(即完成下图中“设备树模式下clk_core的map”)
三、gpio clk gate driver驱动设计
本次我们主要实现gpio clk gate driver,本次实现的平台为ubuntu16.04,我们使用之前模拟的gpio chip driver,提供gpio index,从而通过gpio 的值实现gpio clk gate driver。。另外针对clk gate,仅需要提供enable、disable、is_enabled接口即可。
相关数据结构
结构体struct virt_gpio_clk_gate作为本次gpio clk gate driver的数据结构,主要包含clk provier device、gpio index描述信息;
struct virt_gpio_clk_gate
{
struct gpio_desc *gpiod_clk_gate;
struct clk_hw hw;
};
而结构体gpio_clk_gate_platform_data主要用于传递platform device for clk provider的enable gpio index信息,因为此次我们使用ubuntu16.04进行验证,因此使用该模式传递gpio 信息,包含gpio index、是否低有效等信息。
struct gpio_clk_gate_platform_data
{
int enable_gpio_index;
int active_low;
};
gpio clk provider driver实现
Gpio clk provider driver的实现如下,主要完成clk provider device注册、clk_ops的实现(enable、disable、is_enabled)等。如下即为clk provider driver的probe接口,主要调用clk_register完成clk provider的注册、并调用of_clk_add_provider/clk_register_clkdev实现clk provider的map。
该gpio clk gate provider 的clk_ops操作接口定义如下:
gpio clk consumer driver实现
该consumer driver驱动主要用于验证gpio clk provider driver是否生效,我们在probe接口完成clk的enable操作;而在remove接口完成clk 的disable操作。接口实现如下:
Virt gpio chip driver
该驱动使用的是gpio driver子系统专栏中实现的虚拟gpio驱动,本处不再细述,想要了解的童鞋请参考之前的文章。
测试验证:
- 加载virt gpio 驱动
-
- insmod virt_gpio_dev.ko;
- insmod virt_gpio.ko
- 加载gpio clk gate 驱动
-
- insmod gpio_clk_platform.ko
- insmod gpio_clk_driver.ko
- 加载clk consumer device驱动
-
- insmod gpio_comsumer_device.ko
- 查看当前gpio的值:
- 加载clk consumer driver驱动
-
- insmod gpio_comsumer_driver.ko
- 查看当前gpio的值
此时gpio已经改变,clk已经使能;
- 卸载clk consumer driver驱动
-
- insmod gpio_comsumer_driver.ko
- 查看当前gpio的值
此时gpio已经修改为0,clk 已经关闭;
以上就是本章的主要内容,我们主要实现一个gpio clk gate provider driver,至此我们基本上已完成CCF子系统的学习,本章的驱动代码链接稍后给出。