赞
踩
CCF: common clock frameword
hws[i] = desc->clk_register(cprman, desc->data);
参考https://mp.csdn.net/mp_blog/creation/editor/138153040
1. provider 创建了of_clk_provider 结构体,并且存放在全局变量of_clk_providers 中
2. of_clk_provider 提供了data, 和get/get_hw 函数
参考
bcm2835_clk_probe(struct platform_device *pdev)
{ for (i = 0; i < asize; i++) {
desc = &clk_desc_array[i];
if (desc->clk_register && desc->data &&
(desc->supported & pdata->soc)) {
hws[i] = desc->clk_register(cprman, desc->data);
}
}ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
&cprman->onecell);}
假设consumer 设备树节点中存在 clocks = <0x03 0x2d>;
a. 根据0x03 获取 provider 的struct device_node A,
b. 遍历of_clk_providers列表中,of_clk_provier->node 与 A 相等,
则找到provider 的of_clk_provier。
调用of_clk_provier 的get函数, 从of_clk_provier的 data树组中,提取到第0x2d个时钟
参考:
devm_clk_get
clk_get
__of_clk_get_by_name
__of_clk_get
__of_clk_get_from_provider
{list_for_each_entry(provider, &of_clk_providers, link) {
if (provider->node == clkspec->np) {
hw = __of_clk_get_hw_from_provider(provider, clkspec);
clk = __clk_create_clk(hw, dev_id, con_id);
}
}
struct of_clk_provider {
struct list_head link;struct device_node *node; //provider 的设备节点
struct clk *(*get)(struct of_phandle_args *clkspec, void *data);//a. data 包含了已经注册的时钟数组
//b. clkspec->args[0]来自于 consumer节点的clocks属性的时钟说明符,
//c. provider 根据 clkspec 查找data 数据,获取指定的时钟
struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
void *data;
};
-
- int of_clk_add_hw_provider(struct device_node *np,
- struct clk_hw *(*get)(struct of_phandle_args *clkspec,
- void *data),
- void *data)
- {
- struct of_clk_provider *cp;
- int ret;
-
- cp = kzalloc(sizeof(*cp), GFP_KERNEL);
- if (!cp)
- return -ENOMEM;
-
- cp->node = of_node_get(np);
- cp->data = data;
- cp->get_hw = get;
-
- mutex_lock(&of_clk_mutex);
- list_add(&cp->link, &of_clk_providers); //添加到of_clk_providers 全局链表中
- mutex_unlock(&of_clk_mutex);
- pr_debug("Added clk_hw provider from %pOF\n", np);
-
- ret = of_clk_set_defaults(np, true);
- if (ret < 0)
- of_clk_del_provider(np);
-
- return ret;
- }
- =============================================================
- ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, &cprman->onecell);
-
-
- struct clk_hw * of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
- {
- struct clk_hw_onecell_data *hw_data = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx >= hw_data->num) {
- pr_err("%s: invalid index %u\n", __func__, idx);
- return ERR_PTR(-EINVAL);
- }
-
- return hw_data->hws[idx];
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。