您的位置:首页 > 运维架构 > Linux

Linux 内核clk 添加clk provider

2017-03-27 08:02 176 查看
内核把所有的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;
}
 
 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: