6
6
#include <linux/io.h>
7
7
#include <linux/clk-provider.h>
8
8
#include <linux/clkdev.h>
9
+ #include <linux/init.h>
9
10
#include <linux/of.h>
10
11
#include <linux/of_address.h>
12
+ #include <linux/of_device.h>
13
+ #include <linux/platform_device.h>
11
14
#include <linux/clk/tegra.h>
12
15
#include <linux/delay.h>
13
16
#include <dt-bindings/clock/tegra20-car.h>
@@ -414,7 +417,7 @@ static struct tegra_clk_pll_params pll_e_params = {
414
417
.fixed_rate = 100000000 ,
415
418
};
416
419
417
- static struct tegra_devclk devclks [] __initdata = {
420
+ static struct tegra_devclk devclks [] = {
418
421
{ .con_id = "pll_c" , .dt_id = TEGRA20_CLK_PLL_C },
419
422
{ .con_id = "pll_c_out1" , .dt_id = TEGRA20_CLK_PLL_C_OUT1 },
420
423
{ .con_id = "pll_p" , .dt_id = TEGRA20_CLK_PLL_P },
@@ -710,13 +713,6 @@ static void tegra20_super_clk_init(void)
710
713
NULL );
711
714
clks [TEGRA20_CLK_CCLK ] = clk ;
712
715
713
- /* SCLK */
714
- clk = tegra_clk_register_super_mux ("sclk" , sclk_parents ,
715
- ARRAY_SIZE (sclk_parents ),
716
- CLK_SET_RATE_PARENT | CLK_IS_CRITICAL ,
717
- clk_base + SCLK_BURST_POLICY , 0 , 4 , 0 , 0 , NULL );
718
- clks [TEGRA20_CLK_SCLK ] = clk ;
719
-
720
716
/* twd */
721
717
clk = clk_register_fixed_factor (NULL , "twd" , "cclk" , 0 , 1 , 4 );
722
718
clks [TEGRA20_CLK_TWD ] = clk ;
@@ -1014,7 +1010,7 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
1014
1010
#endif
1015
1011
};
1016
1012
1017
- static struct tegra_clk_init_table init_table [] __initdata = {
1013
+ static struct tegra_clk_init_table init_table [] = {
1018
1014
{ TEGRA20_CLK_PLL_P , TEGRA20_CLK_CLK_MAX , 216000000 , 1 },
1019
1015
{ TEGRA20_CLK_PLL_P_OUT1 , TEGRA20_CLK_CLK_MAX , 28800000 , 1 },
1020
1016
{ TEGRA20_CLK_PLL_P_OUT2 , TEGRA20_CLK_CLK_MAX , 48000000 , 1 },
@@ -1052,11 +1048,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1052
1048
{ TEGRA20_CLK_CLK_MAX , TEGRA20_CLK_CLK_MAX , 0 , 0 },
1053
1049
};
1054
1050
1055
- static void __init tegra20_clock_apply_init_table (void )
1056
- {
1057
- tegra_init_from_table (init_table , clks , TEGRA20_CLK_CLK_MAX );
1058
- }
1059
-
1060
1051
/*
1061
1052
* Some clocks may be used by different drivers depending on the board
1062
1053
* configuration. List those here to register them twice in the clock lookup
@@ -1076,13 +1067,25 @@ static const struct of_device_id pmc_match[] __initconst = {
1076
1067
{ },
1077
1068
};
1078
1069
1070
+ static bool tegra20_car_initialized ;
1071
+
1079
1072
static struct clk * tegra20_clk_src_onecell_get (struct of_phandle_args * clkspec ,
1080
1073
void * data )
1081
1074
{
1082
1075
struct clk_hw * parent_hw ;
1083
1076
struct clk_hw * hw ;
1084
1077
struct clk * clk ;
1085
1078
1079
+ /*
1080
+ * Timer clocks are needed early, the rest of the clocks shouldn't be
1081
+ * available to device drivers until clock tree is fully initialized.
1082
+ */
1083
+ if (clkspec -> args [0 ] != TEGRA20_CLK_RTC &&
1084
+ clkspec -> args [0 ] != TEGRA20_CLK_TWD &&
1085
+ clkspec -> args [0 ] != TEGRA20_CLK_TIMER &&
1086
+ !tegra20_car_initialized )
1087
+ return ERR_PTR (- EPROBE_DEFER );
1088
+
1086
1089
clk = of_clk_src_onecell_get (clkspec , data );
1087
1090
if (IS_ERR (clk ))
1088
1091
return clk ;
@@ -1149,10 +1152,48 @@ static void __init tegra20_clock_init(struct device_node *np)
1149
1152
tegra_init_dup_clks (tegra_clk_duplicates , clks , TEGRA20_CLK_CLK_MAX );
1150
1153
1151
1154
tegra_add_of_provider (np , tegra20_clk_src_onecell_get );
1152
- tegra_register_devclks (devclks , ARRAY_SIZE (devclks ));
1153
-
1154
- tegra_clk_apply_init_table = tegra20_clock_apply_init_table ;
1155
1155
1156
1156
tegra_cpu_car_ops = & tegra20_cpu_car_ops ;
1157
1157
}
1158
- CLK_OF_DECLARE (tegra20 , "nvidia,tegra20-car" , tegra20_clock_init );
1158
+ CLK_OF_DECLARE_DRIVER (tegra20 , "nvidia,tegra20-car" , tegra20_clock_init );
1159
+
1160
+ /*
1161
+ * Clocks that use runtime PM can't be created at the tegra20_clock_init
1162
+ * time because drivers' base isn't initialized yet, and thus platform
1163
+ * devices can't be created for the clocks. Hence we need to split the
1164
+ * registration of the clocks into two phases. The first phase registers
1165
+ * essential clocks which don't require RPM and are actually used during
1166
+ * early boot. The second phase registers clocks which use RPM and this
1167
+ * is done when device drivers' core API is ready.
1168
+ */
1169
+ static int tegra20_car_probe (struct platform_device * pdev )
1170
+ {
1171
+ struct clk * clk ;
1172
+
1173
+ clk = tegra_clk_register_super_mux ("sclk" , sclk_parents ,
1174
+ ARRAY_SIZE (sclk_parents ),
1175
+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL ,
1176
+ clk_base + SCLK_BURST_POLICY , 0 , 4 , 0 , 0 , NULL );
1177
+ clks [TEGRA20_CLK_SCLK ] = clk ;
1178
+
1179
+ tegra_register_devclks (devclks , ARRAY_SIZE (devclks ));
1180
+ tegra_init_from_table (init_table , clks , TEGRA20_CLK_CLK_MAX );
1181
+ tegra20_car_initialized = true;
1182
+
1183
+ return 0 ;
1184
+ }
1185
+
1186
+ static const struct of_device_id tegra20_car_match [] = {
1187
+ { .compatible = "nvidia,tegra20-car" },
1188
+ { }
1189
+ };
1190
+
1191
+ static struct platform_driver tegra20_car_driver = {
1192
+ .driver = {
1193
+ .name = "tegra20-car" ,
1194
+ .of_match_table = tegra20_car_match ,
1195
+ .suppress_bind_attrs = true,
1196
+ },
1197
+ .probe = tegra20_car_probe ,
1198
+ };
1199
+ builtin_platform_driver (tegra20_car_driver );
0 commit comments