日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

linux clk时钟源管理

發(fā)布時間:2023/12/19 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 linux clk时钟源管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

硬件資源越來越龐大和復雜,內(nèi)核的另一個挑戰(zhàn)就是要便捷的管理這些資源。同時,面對如此之多的平臺不同的CPU,管理機制需要統(tǒng)一適用,這就需要對資源的管理抽象到更加通用的層次。CPU中各個模塊都需要時鐘驅(qū)動,內(nèi)核需要一種機制能通用所有的平臺,方便的管理CPU上所有的clk資源。這里分析Linux對clk的管理。
Linux version: 2.6.38
平臺: i.mx53 (mxc),以下所有平臺相關部分都特指i.mx53
涉及的源文件有:

include/linux/clk.hdrivers/clk/clkdev.carch/arm/plat-mxc/clock.carch/arm/mach-mx5/clock.c
1. clk通用接口

內(nèi)核定義了一套標準的接口(include/linux/clk.h),用于所有的平臺之上。每個時鐘源對象使用一個struct clk結構來表示。而struct clk結構的具體內(nèi)容由各平臺自己定義。clk.h頭文件定義了操作一個clk對象的所有接口。內(nèi)核的其他地方可以也只能使用clk.h中提供的這些接口函數(shù)來操作clk。

struct clk *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);
struct clk *clk_get_sys(const char *dev_id, const char *con_id);
int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
			struct device *dev);

2. struct clk

clk結構體是平臺相關的。在arch/arm/mach-mx5/clock.c中會預先描述CPU中所有的clk對象。

parent - clk是由parent分出來的。那么如果parent關閉了,當前clk也就沒有了。secondary - 第二時鐘源,用于enable/disable當前clk。usecount - 引用計數(shù)。get_rate, set_rate, enable, disable, set_parent - 很顯然,這些函數(shù)指針指到實際操作的函數(shù)。clk.h中的各接口函數(shù)最后都會調(diào)用到這里的函數(shù)指針。函數(shù)指針是隔離變化的最好辦法,在這里一下就把層次抽象出來了。

2. clocks鏈表

arch/arm/mach-mx5/clock.c中不僅定義了所有的clk對象,而且每個clk對象還要對應一個struct clk_lookup結構。在初始化時,會將所有的clk_loopup結構添加進入clocks鏈表中。

struct clk_lookup {
	struct list_head	node;
	const char		*dev_id;
	const char		*con_id;
	struct clk		*clk;
};

clk_lookup,顧名思義就知道它是用來查找struct clk結構的。有了它,就可以通過設備名或時鐘源的名字來找到相應的struct clk結構。鏈表操作位于drivers/clk/clkdev.c

3. clk平臺通用操作

arch/arm/plat-mxc/clock.c源文件中定義了mxc平臺clock的通用操作接口。

enable/disable函數(shù)中可以看到引用計數(shù)usecount的作用。一個clk只有當其usecount為0的時候才會做實際的打開動作,也只有usecount為0時才能確認沒有被任何其他設備使用,可以禁止了。層次關系被遞歸調(diào)用和引用計數(shù)巧妙的實現(xiàn)。

static void __clk_disable(struct clk *clk)
{
	if (clk == NULL || IS_ERR(clk))
		return;
	WARN_ON(!clk->usecount);

	if (!(--clk->usecount)) {
		if (clk->disable)
			clk->disable(clk);

		__clk_disable(clk->secondary);
		__clk_disable(clk->parent);
	}
}

static int __clk_enable(struct clk *clk)
{
	if (clk == NULL || IS_ERR(clk))
		return -EINVAL;

	if (clk->usecount++ == 0) {
		__clk_enable(clk->parent);
		__clk_enable(clk->secondary);

		if (clk->enable)
			clk->enable(clk);
	}
	return 0;
}

4. clk與pm

為了省電,當不需要clk時將其關閉,上面的clk_enable/clk_disable實現(xiàn)了此功能。除了關閉clk省電,還可以降低clk頻率以達到省電的目的。當系統(tǒng)當前負載較輕,不需要clk跑在那么高的頻率時,就可以對該clk降頻了。從這些關系可以看到,clk與電源管理,cpufreq等都可能有關聯(lián)。

mxc為各時鐘定義了幾個屬性標志:

arch/arm/plat-mxc/include/mach/clock.h

/* Clock flags */
#define RATE_PROPAGATES		(1 << 0)	/* Program children too */
#define ALWAYS_ENABLED		(1 << 1)	/* Clock cannot be disabled */
#define RATE_FIXED		(1 << 2)	/* Fixed clock rate */
#define CPU_FREQ_TRIG_UPDATE	(1 << 3)	/* CPUFREQ trig update */
#define AHB_HIGH_SET_POINT	(1 << 4)	/* Requires max AHB clock */
#define AHB_MED_SET_POINT	(1 << 5)	/* Requires med AHB clock */

總結

以上是生活随笔為你收集整理的linux clk时钟源管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。