0001
0002
0003
0004
0005
0006 #include <linux/clk-provider.h>
0007 #include <linux/slab.h>
0008 #include <linux/err.h>
0009
0010 #include "clk.h"
0011
0012 static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw,
0013 unsigned long parent_rate)
0014 {
0015 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
0016
0017 return sync->rate;
0018 }
0019
0020 static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate,
0021 unsigned long *prate)
0022 {
0023 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
0024
0025 if (rate > sync->max_rate)
0026 return -EINVAL;
0027 else
0028 return rate;
0029 }
0030
0031 static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate,
0032 unsigned long parent_rate)
0033 {
0034 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
0035
0036 sync->rate = rate;
0037 return 0;
0038 }
0039
0040 const struct clk_ops tegra_clk_sync_source_ops = {
0041 .round_rate = clk_sync_source_round_rate,
0042 .set_rate = clk_sync_source_set_rate,
0043 .recalc_rate = clk_sync_source_recalc_rate,
0044 };
0045
0046 struct clk *tegra_clk_register_sync_source(const char *name,
0047 unsigned long max_rate)
0048 {
0049 struct tegra_clk_sync_source *sync;
0050 struct clk_init_data init;
0051 struct clk *clk;
0052
0053 sync = kzalloc(sizeof(*sync), GFP_KERNEL);
0054 if (!sync) {
0055 pr_err("%s: could not allocate sync source clk\n", __func__);
0056 return ERR_PTR(-ENOMEM);
0057 }
0058
0059 sync->max_rate = max_rate;
0060
0061 init.ops = &tegra_clk_sync_source_ops;
0062 init.name = name;
0063 init.flags = 0;
0064 init.parent_names = NULL;
0065 init.num_parents = 0;
0066
0067
0068 sync->hw.init = &init;
0069
0070 clk = clk_register(NULL, &sync->hw);
0071 if (IS_ERR(clk))
0072 kfree(sync);
0073
0074 return clk;
0075 }