diff options
author | Stephen Warren <swarren@nvidia.com> | 2013-03-25 13:22:24 -0600 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2013-04-04 16:09:05 -0600 |
commit | 441f199a37cfd66c5dd8dd45490bd3ea6971117d (patch) | |
tree | 0f7570e7985ea2b62f558e43d33caef6efa7e989 /drivers/clk | |
parent | 82ce742140f32394cc5be75f1c98cdbbff284582 (diff) |
clk: tegra: defer application of init table
The Tegra clock driver is initialized during the ARM machine descriptor's
.init_irq() hook. It can't be initialized earlier, since dynamic memory
usage is required. It can't be initialized later, since the .init_timer()
hook needs the clocks initialized. However, at this time, udelay()
doesn't work.
The Tegra clock initialization table may enable some PLLs. Enabling a PLL
may require usage of udelay(). Hence, this can't happen right when the
clock driver is initialized.
To solve this, separate the clock driver initialization from the clock
table processing, so they can execute at separate times.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/tegra/clk-tegra20.c | 7 | ||||
-rw-r--r-- | drivers/clk/tegra/clk-tegra30.c | 7 | ||||
-rw-r--r-- | drivers/clk/tegra/clk.c | 10 | ||||
-rw-r--r-- | drivers/clk/tegra/clk.h | 3 |
4 files changed, 25 insertions, 2 deletions
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index a7dc0a93736..a15fb28197b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1252,6 +1252,11 @@ static __initdata struct tegra_clk_init_table init_table[] = { {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */ }; +static void __init tegra20_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, clk_max); +} + /* * Some clocks may be used by different drivers depending on the board * configuration. List those here to register them twice in the clock lookup @@ -1318,7 +1323,7 @@ void __init tegra20_clock_init(struct device_node *np) clk_data.clk_num = ARRAY_SIZE(clks); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - tegra_init_from_table(init_table, clks, clk_max); + tegra_clk_apply_init_table = tegra20_clock_apply_init_table; tegra_cpu_car_ops = &tegra20_cpu_car_ops; } diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 181a6eef5ce..e0ee93c2db6 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1916,6 +1916,11 @@ static __initdata struct tegra_clk_init_table init_table[] = { {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ }; +static void __init tegra30_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, clk_max); +} + /* * Some clocks may be used by different drivers depending on the board * configuration. List those here to register them twice in the clock lookup @@ -1989,7 +1994,7 @@ void __init tegra30_clock_init(struct device_node *np) clk_data.clk_num = ARRAY_SIZE(clks); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - tegra_init_from_table(init_table, clks, clk_max); + tegra_clk_apply_init_table = tegra30_clock_apply_init_table; tegra_cpu_car_ops = &tegra30_cpu_car_ops; } diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index a603b9af0ad..4a61d15425d 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -83,3 +83,13 @@ void __init tegra_clocks_init(void) { of_clk_init(tegra_dt_clk_match); } + +tegra_clk_apply_init_table_func tegra_clk_apply_init_table; + +void __init tegra_clocks_apply_init_table(void) +{ + if (!tegra_clk_apply_init_table) + return; + + tegra_clk_apply_init_table(); +} diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index a09d7dcaf18..3c566e2d518 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -510,4 +510,7 @@ void tegra30_clock_init(struct device_node *np); static inline void tegra30_clock_init(struct device_node *np) {} #endif /* CONFIG_ARCH_TEGRA_3x_SOC */ +typedef void (*tegra_clk_apply_init_table_func)(void); +extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; + #endif /* TEGRA_CLK_H */ |