Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.7-rc6 100 lines 2.5 kB view raw
1/* 2 * Driver for the ICST307 VCO clock found in the ARM Reference designs. 3 * We wrap the custom interface from <asm/hardware/icst.h> into the generic 4 * clock framework. 5 * 6 * TODO: when all ARM reference designs are migrated to generic clocks, the 7 * ICST clock code from the ARM tree should probably be merged into this 8 * file. 9 */ 10#include <linux/clk.h> 11#include <linux/clkdev.h> 12#include <linux/err.h> 13#include <linux/clk-provider.h> 14 15#include "clk-icst.h" 16 17/** 18 * struct clk_icst - ICST VCO clock wrapper 19 * @hw: corresponding clock hardware entry 20 * @params: parameters for this ICST instance 21 * @rate: current rate 22 * @setvco: function to commit ICST settings to hardware 23 */ 24struct clk_icst { 25 struct clk_hw hw; 26 const struct icst_params *params; 27 unsigned long rate; 28 struct icst_vco (*getvco)(void); 29 void (*setvco)(struct icst_vco); 30}; 31 32#define to_icst(_hw) container_of(_hw, struct clk_icst, hw) 33 34static unsigned long icst_recalc_rate(struct clk_hw *hw, 35 unsigned long parent_rate) 36{ 37 struct clk_icst *icst = to_icst(hw); 38 struct icst_vco vco; 39 40 vco = icst->getvco(); 41 icst->rate = icst_hz(icst->params, vco); 42 return icst->rate; 43} 44 45static long icst_round_rate(struct clk_hw *hw, unsigned long rate, 46 unsigned long *prate) 47{ 48 struct clk_icst *icst = to_icst(hw); 49 struct icst_vco vco; 50 51 vco = icst_hz_to_vco(icst->params, rate); 52 return icst_hz(icst->params, vco); 53} 54 55static int icst_set_rate(struct clk_hw *hw, unsigned long rate, 56 unsigned long parent_rate) 57{ 58 struct clk_icst *icst = to_icst(hw); 59 struct icst_vco vco; 60 61 vco = icst_hz_to_vco(icst->params, rate); 62 icst->rate = icst_hz(icst->params, vco); 63 icst->setvco(vco); 64 return 0; 65} 66 67static const struct clk_ops icst_ops = { 68 .recalc_rate = icst_recalc_rate, 69 .round_rate = icst_round_rate, 70 .set_rate = icst_set_rate, 71}; 72 73struct clk * __init icst_clk_register(struct device *dev, 74 const struct clk_icst_desc *desc) 75{ 76 struct clk *clk; 77 struct clk_icst *icst; 78 struct clk_init_data init; 79 80 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); 81 if (!icst) { 82 pr_err("could not allocate ICST clock!\n"); 83 return ERR_PTR(-ENOMEM); 84 } 85 init.name = "icst"; 86 init.ops = &icst_ops; 87 init.flags = CLK_IS_ROOT; 88 init.parent_names = NULL; 89 init.num_parents = 0; 90 icst->hw.init = &init; 91 icst->params = desc->params; 92 icst->getvco = desc->getvco; 93 icst->setvco = desc->setvco; 94 95 clk = clk_register(dev, &icst->hw); 96 if (IS_ERR(clk)) 97 kfree(icst); 98 99 return clk; 100}