clock子系統
Linux的時鐘子系統由CCF(common clock framework)框架管理, CCF向上給用戶提供了通用的時鐘接口,向下給驅動開發者提供硬件操作的接口 。各結構體關系如下:
CCF框架比較簡單,只有這幾個結構體。CCF框架分為了consumer、ccf和provider三部分。
consumer :
時鐘的使用者,clock子系統向consumer的提供通用的時鐘API接口,使其可以屏蔽底層硬件差異。提供給consumer操作的API如下:
struct clk *clk_get(struct device *dev, const char *id);
struct clk *devm_clk_get(struct device *dev, const char *id);
int clk_enable(struct clk *clk);//使能時鐘,不會睡眠
void clk_disable(struct clk *clk);//使能時鐘,不會睡眠
unsigned long clk_get_rate(struct clk *clk);
void clk_put(struct clk *clk);
long clk_round_rate(struct clk *clk, unsigned long rate);
int clk_set_rate(struct clk *clk, unsigned long rate);
int clk_set_parent(struct clk *clk, struct clk *parent);
struct clk *clk_get_parent(struct clk *clk);
int clk_prepare(struct clk *clk);
void clk_unprepare(struct clk *clk);
int clk_prepare_enable(struct clk *clk) //使能時鐘,可能會睡眠
void clk_disable_unprepare(struct clk *clk) //禁止時鐘,可能會睡眠
unsigned long clk_get_rate(struct clk *clk) //獲取時鐘頻率
consumer在使用這些API時,必須先調用devm_clk_get()
或clk_get()
獲取一個struct clk *
指針句柄,后續都通過傳入該句柄來操作,struct clk相當于實例化一個時鐘。
ccf :
clock子系統的核心,用一個struct clk_core
結構體表示,每個注冊設備都對應一個struct clk_core
。
provider(時鐘的提供者) :
struct clk_hw
:表示一個具體的硬件時鐘。
struct clk_init_data
:struct clk_hw結構體成員,用于表示該時鐘下的初始化數據,如時鐘名字name、操作函數ops等。
// include/linux/clk-provider.h
struct clk_hw{
struct clk_core *core;
struct clk *clk;
const struct clk_init_data *init;
}
struct clk_init_data{
const char *name; //時鐘名字
const struct clk_ops *ops; //時鐘硬件操作函數集合
const char *const *parent_names; //父時鐘名字
const struct clk_parent_data *parent_data;
const struct clk_hw **parent_hws;
u8 num_parents;
unsigned long flags;
}
struct clk_ops
:時鐘硬件操作的函數集合,定義了操作硬件的回調函數,consumer在調用clk_set_rate()
等API時會調用到struct clk_ops
具體指向的函數,這個需要芯片廠商開發clock驅動時去實現。
//include/linux/clk-provider.h
struct clk_ops {
int (*prepare)(struct clk_hw *hw);
void (*unprepare)(struct clk_hw *hw);
int (*is_prepared)(struct clk_hw *hw);
void (*unprepare_unused)(struct clk_hw *hw);
int (*enable)(struct clk_hw *hw);
void (*disable)(struct clk_hw *hw);
int (*is_enabled)(struct clk_hw *hw);
void (*disable_unused)(struct clk_hw *hw);
int (*save_context)(struct clk_hw *hw);
void (*restore_context)(struct clk_hw *hw);
unsigned long (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate);
long (*round_rate)(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate);
int (*determine_rate)(struct clk_hw *hw,
struct clk_rate_request *req);
int (*set_parent)(struct clk_hw *hw, u8 index);
u8 (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
int (*set_rate_and_parent)(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate, u8 index);
unsigned long (*recalc_accuracy)(struct clk_hw *hw,
unsigned long parent_accuracy);
int (*get_phase)(struct clk_hw *hw);
int (*set_phase)(struct clk_hw *hw, int degrees);
int (*get_duty_cycle)(struct clk_hw *hw,
struct clk_duty *duty);
int (*set_duty_cycle)(struct clk_hw *hw,
struct clk_duty *duty);
int (*init)(struct clk_hw *hw);
void (*terminate)(struct clk_hw *hw);
void (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
};
struct clk_ops中每個函數功能在include/linux/clk-provider.h
都有具體的說明,在開發clock驅動時,這些函數并不需要全部實現。
-
接口
+關注
關注
33文章
8598瀏覽量
151166 -
Linux
+關注
關注
87文章
11304瀏覽量
209523 -
子系統
+關注
關注
0文章
109瀏覽量
12402
發布評論請先 登錄
相關推薦
評論