本文主要是介绍Linux 内核clk 添加clk provider,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
内核把所有的clk provider管理维护起来,这些存放在of_clk_providers链表当中,
这个provider定义如下:
struct of_clk_provider {struct list_head link;
struct device_node *node;struct clk *(*get)(struct of_phandle_args *clkspec, void *data);struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);void *data; };
static LIST_HEAD(of_clk_providers);
static DEFINE_MUTEX(of_clk_lock);
添加函数:
/*** of_clk_add_provider() - Register a clock provider for a node* @np: Device node pointer associated with clock provider* @clk_src_get: callback for decoding clock* @data: context pointer for @clk_src_get callback.*/ int of_clk_add_provider(struct device_node *np,struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,void *data),void *data) {struct of_clk_provider *cp;
cp = kzalloc(sizeof(struct of_clk_provider), GFP_KERNEL);if (!cp)return -ENOMEM;
cp->node = of_node_get(np);cp->data = data;cp->get = clk_src_get;
mutex_lock(&of_clk_lock); list_add(&cp->link, &of_clk_providers);mutex_unlock(&of_clk_lock);pr_debug("Added clock from %s\n", np->full_name);
return 0; }
删除操作 /*** of_clk_del_provider() - Remove a previously registered clock provider* @np: Device node pointer associated with clock provider*/ void of_clk_del_provider(struct device_node *np) {struct of_clk_provider *cp;
mutex_lock(&of_clk_lock);list_for_each_entry(cp, &of_clk_providers, link) {if (cp->node == np) { list_del(&cp->link);of_node_put(cp->node);kfree(cp);break;}}mutex_unlock(&of_clk_lock); }
获取clk:
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) {struct of_clk_provider *provider;struct clk *clk = ERR_PTR(-ENOENT);
/* Check if we have such a provider in our array */mutex_lock(&of_clk_lock);list_for_each_entry(provider, &of_clk_providers, link) {if (provider->node == clkspec->np)clk = provider->get(clkspec, provider->data);if (!IS_ERR(clk))break;}mutex_unlock(&of_clk_lock);
return clk; }
这篇关于Linux 内核clk 添加clk provider的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!