Peng Fan +

clock framework part 1

clk framework是基于consumer和provider来设计的。consumer故名思议是使用clk的个体。这里我们看一下consumer可以使用的API有哪些

int clk_prepare(struct clk *clk);
void clk_unprepare(struct clk *clk);
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);
void devm_clk_put(struct device *dev, struct clk *clk);
long clk_round_rate(struct clk *clk, unsigned long rate);
int clk_set_rate(struct clk *clk, unsigned long rate);
bool clk_has_parent(struct clk *clk, struct clk *parent);
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
int clk_set_min_rate(struct clk *clk, unsigned long rate);
int clk_set_max_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);
static inline int clk_prepare_enable(struct clk *clk)
static inline void clk_disable_unprepare(struct clk *clk)

在驱动中我们一般这样用:clk_ipg = devm_clk_get(&pdev->dev, "ipg");,在dts里面的描述如下:

clocks = <&clks IMX6UL_CLK_USDHC1>,                                                               
         <&clks IMX6UL_CLK_USDHC1>,                                                               
         <&clks IMX6UL_CLK_USDHC1>;                                                               
clock-names = "ipg", "ahb", "per";

clk_round_rate:注释是这样的:

/**                                                                             
 * clk_round_rate - adjust a rate to the exact rate a clock can provide         
 * @clk: clock source                                                           
 * @rate: desired clock rate in Hz                                              
 *                                                                              
 * This answers the question "if I were to pass @rate to clk_set_rate(),        
 * what clock rate would I end up with?" without changing the hardware          
 * in any way.  In other words:                                                 
 *                                                                              
 *   rate = clk_round_rate(clk, r);                                             
 *                                                                              
 * and:                                                                            
 *                                                                              
 *   clk_set_rate(clk, r);                                                       
 *   rate = clk_get_rate(clk);                                                  
 *                                                                              
 * are equivalent except the former does not modify the clock hardware          
 * in any way.                                                                     
 *                                                                              
 * Returns rounded clock rate in Hz, or negative errno.                         
 */

支持devicetree的API:

struct clk *of_clk_get(struct device_node *np, int index);
struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);

Blog

Opinion

Project