clk: tegra: common periph_clk_enb_refcnt and clks
authorPeter De Schrijver <pdeschrijver@nvidia.com>
Mon, 2 Sep 2013 12:22:02 +0000 (15:22 +0300)
committerPeter De Schrijver <pdeschrijver@nvidia.com>
Tue, 26 Nov 2013 16:46:18 +0000 (18:46 +0200)
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>
drivers/clk/tegra/clk-periph.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.c
drivers/clk/tegra/clk.h

index 735b0243261ca7b889bf9b15f86d09296f75aaf6..5102d5e58c04cf293b616cdcbab44151ae826fca 100644 (file)
@@ -197,6 +197,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
        periph->divider.reg = div ? (clk_base + offset) : NULL;
        periph->gate.clk_base = clk_base;
        periph->gate.regs = bank;
+       periph->gate.enable_refcnt = periph_clk_enb_refcnt;
 
        clk = clk_register(NULL, &periph->hw);
        if (IS_ERR(clk))
index 8507067d5dd63a177119800f5ac626bee91babf2..9729af823eaf3f6663605f76c53cc6a66d79a895 100644 (file)
@@ -57,8 +57,6 @@
 #define CPU_FINETRIM_R_FCPU_6_SHIFT    10              /* ftop */
 #define CPU_FINETRIM_R_FCPU_6_MASK     (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT)
 
-#define CLK_OUT_ENB_NUM                        6
-
 #define TEGRA114_CLK_PERIPH_BANKS      5
 
 #define PLLC_BASE 0x80
@@ -266,8 +264,6 @@ static struct cpu_clk_suspend_context {
 } tegra114_cpu_clk_sctx;
 #endif
 
-static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
-
 static void __iomem *clk_base;
 static void __iomem *pmc_base;
 
@@ -712,59 +708,53 @@ static unsigned long tegra114_input_freq[] = {
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,\
-                       _clk_id, _parents##_idx, 0)
+                       _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
                            _clk_num, _gate_flags, _clk_id, flags)\
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,\
-                       _clk_id, _parents##_idx, flags)
+                       _clk_num, _gate_flags, _clk_id, _parents##_idx, flags)
 
 #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
                             _clk_num, _gate_flags, _clk_id)    \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,\
-                       _clk_id, _parents##_idx, 0)
+                       _clk_num, _gate_flags, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
                            _clk_num, _gate_flags, _clk_id, flags)\
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT |    \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
-                       _parents##_idx, flags)
+                       _gate_flags, _clk_id, _parents##_idx, flags)
 
 #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT |    \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
-                       _parents##_idx, 0)
+                       _gate_flags, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
                             _clk_num, _clk_id)                 \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART |  \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0)
+                       0, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\
                             _clk_num, _clk_id)                 \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\
-                       _clk_num, periph_clk_enb_refcnt, 0, _clk_id,\
-                       _parents##_idx, 0)
+                       _clk_num,  0, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
                              _mux_shift, _mux_mask, _clk_num, \
                              _gate_flags, _clk_id)                     \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
                        _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_num, _gate_flags,  \
                        _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \
@@ -772,16 +762,14 @@ static unsigned long tegra114_input_freq[] = {
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \
                        29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT |    \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
-                       _parents##_idx, 0)
+                       _gate_flags, _clk_id, _parents##_idx, 0)
 
 #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset,  _clk_num,\
                                 _gate_flags, _clk_id)          \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \
                        _offset, 16, 0xE01F, 0, 0, 8, 1,                \
-                       TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, _gate_flags , _clk_id,   \
-                       mux_d_audio_clk_idx, 0)
+                       TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
+                       _gate_flags , _clk_id,  mux_d_audio_clk_idx, 0)
 
 struct utmi_clk_param {
        /* Oscillator Frequency in KHz */
@@ -946,8 +934,7 @@ static const struct clk_div_table pll_re_div_table[] = {
        { .val = 0, .div = 0 },
 };
 
-static struct clk *clks[TEGRA114_CLK_CLK_MAX];
-static struct clk_onecell_data clk_data;
+static struct clk **clks;
 
 static unsigned long osc_freq;
 static unsigned long pll_ref_freq;
@@ -2229,7 +2216,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
 static void __init tegra114_clock_init(struct device_node *np)
 {
        struct device_node *node;
-       int i;
 
        clk_base = of_iomap(np, 0);
        if (!clk_base) {
@@ -2251,10 +2237,11 @@ static void __init tegra114_clock_init(struct device_node *np)
                return;
        }
 
-       if (tegra114_osc_clk_init(clk_base) < 0)
+       clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS);
+       if (!clks)
                return;
 
-       if (tegra_clk_set_periph_banks(TEGRA114_CLK_PERIPH_BANKS) < 0)
+       if (tegra114_osc_clk_init(clk_base) < 0)
                return;
 
        tegra114_fixed_clk_init(clk_base);
@@ -2264,19 +2251,7 @@ static void __init tegra114_clock_init(struct device_node *np)
        tegra114_pmc_clk_init(pmc_base);
        tegra114_super_clk_init(clk_base);
 
-       for (i = 0; i < ARRAY_SIZE(clks); i++) {
-               if (IS_ERR(clks[i])) {
-                       pr_err
-                           ("Tegra114 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 = ARRAY_SIZE(clks);
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       tegra_add_of_provider(np);
 
        tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
 
index 929a46278d8387c92702322898db8c2855e0fdf9..6bf5c339ab431755008e57b3f97d5c61cbdbca83 100644 (file)
@@ -25,8 +25,6 @@
 
 #include "clk.h"
 
-#define CLK_OUT_ENB_NUM 3
-
 #define OSC_CTRL 0x50
 #define OSC_CTRL_OSC_FREQ_MASK (3<<30)
 #define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
@@ -170,8 +168,6 @@ static struct cpu_clk_suspend_context {
 } tegra20_cpu_clk_sctx;
 #endif
 
-static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
-
 static void __iomem *clk_base;
 static void __iomem *pmc_base;
 
@@ -182,21 +178,21 @@ static DEFINE_SPINLOCK(sysrate_lock);
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,      \
-                       _clk_num, periph_clk_enb_refcnt,                \
+                       _clk_num, \
                        _gate_flags, _clk_id)
 
 #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset,        \
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_num, _gate_flags,  \
                        _clk_id)
 
 #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
                              _clk_num, _gate_flags, _clk_id)   \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_num, _gate_flags,  \
                        _clk_id)
 
 #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
@@ -204,7 +200,7 @@ static DEFINE_SPINLOCK(sysrate_lock);
                              _gate_flags, _clk_id)                     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        _mux_shift, _mux_width, 0, 0, 0, 0, 0, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_num, _gate_flags,  \
                        _clk_id)
 
 /* IDs assigned here must be in sync with DT bindings definition
@@ -226,8 +222,7 @@ enum tegra20_clk {
        pll_x, cop, audio, pll_ref, twd, clk_max,
 };
 
-static struct clk *clks[clk_max];
-static struct clk_onecell_data clk_data;
+static struct clk **clks;
 
 static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
        { 12000000, 600000000, 600, 12, 0, 8 },
@@ -808,7 +803,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
        TEGRA_INIT_DATA_DIV16("i2c3",   "div-clk",      "tegra-i2c.2",   mux_pllpcm_clkm,   CLK_SOURCE_I2C3,      67,   TEGRA_PERIPH_ON_APB, i2c3),
        TEGRA_INIT_DATA_DIV16("dvc",    "div-clk",      "tegra-i2c.3",   mux_pllpcm_clkm,   CLK_SOURCE_DVC,       47,   TEGRA_PERIPH_ON_APB, dvc),
        TEGRA_INIT_DATA_MUX("hdmi",     NULL,           "hdmi",          mux_pllpdc_clkm,   CLK_SOURCE_HDMI,      51,   0, hdmi),
-       TEGRA_INIT_DATA("pwm",          NULL,           "tegra-pwm",     pwm_parents,       CLK_SOURCE_PWM,       28, 3, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm),
+       TEGRA_INIT_DATA("pwm",          NULL,           "tegra-pwm",     pwm_parents,       CLK_SOURCE_PWM,       28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, pwm),
 };
 
 static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
@@ -1232,7 +1227,6 @@ static const struct of_device_id pmc_match[] __initconst = {
 
 static void __init tegra20_clock_init(struct device_node *np)
 {
-       int i;
        struct device_node *node;
 
        clk_base = of_iomap(np, 0);
@@ -1253,7 +1247,8 @@ static void __init tegra20_clock_init(struct device_node *np)
                BUG();
        }
 
-       if (tegra_clk_set_periph_banks(TEGRA20_CLK_PERIPH_BANKS) < 0)
+       clks = tegra_clk_init(clk_max, TEGRA20_CLK_PERIPH_BANKS);
+       if (!clks)
                return;
 
        tegra20_osc_clk_init();
@@ -1264,22 +1259,9 @@ static void __init tegra20_clock_init(struct device_node *np)
        tegra20_periph_clk_init();
        tegra20_audio_clk_init();
 
-
-       for (i = 0; i < ARRAY_SIZE(clks); i++) {
-               if (IS_ERR(clks[i])) {
-                       pr_err("Tegra20 clk %d: register failed with %ld\n",
-                              i, PTR_ERR(clks[i]));
-                       BUG();
-               }
-               if (!clks[i])
-                       clks[i] = ERR_PTR(-EINVAL);
-       }
-
        tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
 
-       clk_data.clks = clks;
-       clk_data.clk_num = ARRAY_SIZE(clks);
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       tegra_add_of_provider(np);
 
        tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
 
index a66bdabb5c5c79efa2210a0eb5b4c201b35b40d4..c5db42217ba82754d8b785091963d94f5eec0558 100644 (file)
@@ -26,8 +26,6 @@
 
 #include "clk.h"
 
-#define CLK_OUT_ENB_NUM 5
-
 #define OSC_CTRL                       0x50
 #define OSC_CTRL_OSC_FREQ_MASK         (0xF<<28)
 #define OSC_CTRL_OSC_FREQ_13MHZ                (0X0<<28)
@@ -236,8 +234,6 @@ static struct cpu_clk_suspend_context {
 } tegra30_cpu_clk_sctx;
 #endif
 
-static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
-
 static void __iomem *clk_base;
 static void __iomem *pmc_base;
 static unsigned long input_freq;
@@ -253,41 +249,41 @@ static DEFINE_SPINLOCK(sysrate_lock);
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id)
+                       _clk_num, _gate_flags, _clk_id)
 
 #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,     \
-                       _clk_num, periph_clk_enb_refcnt,                \
+                       _clk_num, \
                        _gate_flags, _clk_id)
 
 #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
                             _clk_num, _gate_flags, _clk_id)    \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags, _clk_id)
+                       _clk_num, _gate_flags, _clk_id)
 
 #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset,        \
                            _clk_num, _gate_flags, _clk_id)     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT |          \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,       \
-                       periph_clk_enb_refcnt, _gate_flags, _clk_id)
+                       _gate_flags, _clk_id)
 
 #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
                             _clk_num, _clk_id)                 \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART |        \
                        TEGRA_DIVIDER_ROUND_UP, _clk_num,               \
-                       periph_clk_enb_refcnt, 0, _clk_id)
+                       0, _clk_id)
 
 #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
                              _mux_shift, _mux_width, _clk_num, \
                              _gate_flags, _clk_id)                     \
        TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset,     \
                        _mux_shift, _mux_width, 0, 0, 0, 0, 0,\
-                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_num, _gate_flags,  \
                        _clk_id)
 
 /*
@@ -318,8 +314,7 @@ enum tegra30_clk {
        hclk, pclk, clk_out_1_mux = 300, clk_max
 };
 
-static struct clk *clks[clk_max];
-static struct clk_onecell_data clk_data;
+static struct clk **clks;
 
 /*
  * Structure defining the fields for USB UTMI clocks Parameters.
@@ -1432,7 +1427,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
        TEGRA_INIT_DATA_MUX8("extern1", NULL,           "extern1",              mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1,     120,    0, extern1),
        TEGRA_INIT_DATA_MUX8("extern2", NULL,           "extern2",              mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2,     121,    0, extern2),
        TEGRA_INIT_DATA_MUX8("extern3", NULL,           "extern3",              mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3,     122,    0, extern3),
-       TEGRA_INIT_DATA("pwm",          NULL,           "pwm",                  mux_pllpc_clk32k_clkm,  CLK_SOURCE_PWM,         28, 2, 0, 0, 8, 1, 0, 17, periph_clk_enb_refcnt, 0, pwm),
+       TEGRA_INIT_DATA("pwm",          NULL,           "pwm",                  mux_pllpc_clk32k_clkm,  CLK_SOURCE_PWM,         28, 2, 0, 0, 8, 1, 0, 17, 0, pwm),
 };
 
 static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
@@ -1899,7 +1894,6 @@ static const struct of_device_id pmc_match[] __initconst = {
 static void __init tegra30_clock_init(struct device_node *np)
 {
        struct device_node *node;
-       int i;
 
        clk_base = of_iomap(np, 0);
        if (!clk_base) {
@@ -1919,7 +1913,8 @@ static void __init tegra30_clock_init(struct device_node *np)
                BUG();
        }
 
-       if (tegra_clk_set_periph_banks(TEGRA30_CLK_PERIPH_BANKS) < 0)
+       clks = tegra_clk_init(clk_max, TEGRA30_CLK_PERIPH_BANKS);
+       if (!clks)
                return;
 
        tegra30_osc_clk_init();
@@ -1930,21 +1925,9 @@ static void __init tegra30_clock_init(struct device_node *np)
        tegra30_audio_clk_init();
        tegra30_pmc_clk_init();
 
-       for (i = 0; i < ARRAY_SIZE(clks); i++) {
-               if (IS_ERR(clks[i])) {
-                       pr_err("Tegra30 clk %d: register failed with %ld\n",
-                              i, PTR_ERR(clks[i]));
-                       BUG();
-               }
-               if (!clks[i])
-                       clks[i] = ERR_PTR(-EINVAL);
-       }
-
        tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
 
-       clk_data.clks = clks;
-       clk_data.clk_num = ARRAY_SIZE(clks);
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       tegra_add_of_provider(np);
 
        tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
 
index 07f76df2583b1751657045a3d9ffd956dab97552..3a95a8757ebccb3557ae1810df4cdfa0b6da1c98 100644 (file)
 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)
index 730d37b39488f1749c0840069c588bd2a50b5892..997357ef059e86a49507b14414be6eb15947817c 100644 (file)
@@ -37,6 +37,8 @@ struct tegra_clk_sync_source {
        container_of(_hw, struct tegra_clk_sync_source, hw)
 
 extern const struct clk_ops tegra_clk_sync_source_ops;
+extern int *periph_clk_enb_refcnt;
+
 struct clk *tegra_clk_register_sync_source(const char *name,
                unsigned long fixed_rate, unsigned long max_rate);
 
@@ -442,7 +444,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
 
 #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags,            \
                         _div_shift, _div_width, _div_frac_width,       \
-                        _div_flags, _clk_num, _enb_refcnt,             \
+                        _div_flags, _clk_num,\
                         _gate_flags, _table)                           \
        {                                                               \
                .mux = {                                                \
@@ -460,7 +462,6 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
                .gate = {                                               \
                        .flags = _gate_flags,                           \
                        .clk_num = _clk_num,                            \
-                       .enable_refcnt = _enb_refcnt,                   \
                },                                                      \
                .mux_ops = &clk_mux_ops,                                \
                .div_ops = &tegra_clk_frac_div_ops,                     \
@@ -482,7 +483,7 @@ struct tegra_periph_init_data {
 #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
                        _mux_shift, _mux_mask, _mux_flags, _div_shift,  \
                        _div_width, _div_frac_width, _div_flags,        \
-                       _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\
+                       _clk_num, _gate_flags, _clk_id, _table,         \
                        _flags) \
        {                                                               \
                .name = _name,                                          \
@@ -493,7 +494,6 @@ struct tegra_periph_init_data {
                                           _mux_flags, _div_shift,      \
                                           _div_width, _div_frac_width, \
                                           _div_flags, _clk_num,        \
-                                          _enb_refcnt,                 \
                                           _gate_flags, _table),        \
                .offset = _offset,                                      \
                .con_id = _con_id,                                      \
@@ -504,11 +504,11 @@ struct tegra_periph_init_data {
 #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
                        _mux_shift, _mux_width, _mux_flags, _div_shift, \
                        _div_width, _div_frac_width, _div_flags, \
-                       _clk_num, _enb_refcnt, _gate_flags, _clk_id)    \
+                       _clk_num, _gate_flags, _clk_id) \
        TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
                        _mux_shift, BIT(_mux_width) - 1, _mux_flags,    \
                        _div_shift, _div_width, _div_frac_width, _div_flags, \
-                       _clk_num, _enb_refcnt, _gate_flags, _clk_id,\
+                       _clk_num, _gate_flags, _clk_id,\
                        NULL, 0)
 
 /**
@@ -586,7 +586,9 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
                struct clk *clks[], int clk_max);
 
 struct tegra_clk_periph_regs *get_reg_bank(int clkid);
-int tegra_clk_set_periph_banks(int num);
+struct clk **tegra_clk_init(int num, int periph_banks);
+
+void tegra_add_of_provider(struct device_node *np);
 
 void tegra114_clock_tune_cpu_trimmers_high(void);
 void tegra114_clock_tune_cpu_trimmers_low(void);