summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra/clk.c
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2013-09-02 16:22:02 +0400
committerPeter De Schrijver <pdeschrijver@nvidia.com>2013-11-26 20:46:18 +0400
commit343a607cb79259429afbb9820bf524d33084e66c (patch)
tree508757a525821d7aad6c6d24caa72447c95907bf /drivers/clk/tegra/clk.c
parentd5ff89a82a6d272d210db68a9487877682c94a24 (diff)
downloadlinux-343a607cb79259429afbb9820bf524d33084e66c.tar.xz
clk: tegra: common periph_clk_enb_refcnt and clks
This patch makes periph_clk_enb_refcnt a global array, dynamically allocated at boottime. It simplifies the macros somewhat and allows clocks common to several Tegra SoCs to be defined in a separate files. Also the clks array becomes global and dynamically allocated which allows the DT registration to be moved to a generic funcion. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra/clk.c')
-rw-r--r--drivers/clk/tegra/clk.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 07f76df2583b..3a95a8757ebc 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -62,7 +62,11 @@
static struct tegra_cpu_car_ops dummy_car_ops;
struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
+int *periph_clk_enb_refcnt;
static int periph_banks;
+static struct clk **clks;
+static int clk_num;
+static struct clk_onecell_data clk_data;
static struct tegra_clk_periph_regs periph_regs[] = {
[0] = {
@@ -119,14 +123,25 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid)
}
}
-int __init tegra_clk_set_periph_banks(int num)
+struct clk ** __init tegra_clk_init(int num, int banks)
{
- if (num > ARRAY_SIZE(periph_regs))
- return -EINVAL;
+ if (WARN_ON(banks > ARRAY_SIZE(periph_regs)))
+ return NULL;
+
+ periph_clk_enb_refcnt = kzalloc(32 * banks *
+ sizeof(*periph_clk_enb_refcnt), GFP_KERNEL);
+ if (!periph_clk_enb_refcnt)
+ return NULL;
- periph_banks = num;
+ periph_banks = banks;
- return 0;
+ clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL);
+ if (!clks)
+ kfree(periph_clk_enb_refcnt);
+
+ clk_num = num;
+
+ return clks;
}
void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
@@ -178,6 +193,25 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
}
}
+void __init tegra_add_of_provider(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < clk_num; i++) {
+ if (IS_ERR(clks[i])) {
+ pr_err
+ ("Tegra clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+ }
+ if (!clks[i])
+ clks[i] = ERR_PTR(-EINVAL);
+ }
+
+ clk_data.clks = clks;
+ clk_data.clk_num = clk_num;
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
void __init tegra_clocks_apply_init_table(void)