diff options
-rw-r--r-- | drivers/clk/sunxi/clk-sunxi.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d92e30371d8a..9f31314a9cd7 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -1046,13 +1046,20 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, | |||
1046 | * sunxi_divs_clk_setup() helper data | 1046 | * sunxi_divs_clk_setup() helper data |
1047 | */ | 1047 | */ |
1048 | 1048 | ||
1049 | #define SUNXI_DIVS_MAX_QTY 2 | 1049 | #define SUNXI_DIVS_MAX_QTY 4 |
1050 | #define SUNXI_DIVISOR_WIDTH 2 | 1050 | #define SUNXI_DIVISOR_WIDTH 2 |
1051 | 1051 | ||
1052 | struct divs_data { | 1052 | struct divs_data { |
1053 | const struct factors_data *factors; /* data for the factor clock */ | 1053 | const struct factors_data *factors; /* data for the factor clock */ |
1054 | int ndivs; /* number of children */ | 1054 | int ndivs; /* number of outputs */ |
1055 | /* | ||
1056 | * List of outputs. Refer to the diagram for sunxi_divs_clk_setup(): | ||
1057 | * self or base factor clock refers to the output from the pll | ||
1058 | * itself. The remaining refer to fixed or configurable divider | ||
1059 | * outputs. | ||
1060 | */ | ||
1055 | struct { | 1061 | struct { |
1062 | u8 self; /* is it the base factor clock? (only one) */ | ||
1056 | u8 fixed; /* is it a fixed divisor? if not... */ | 1063 | u8 fixed; /* is it a fixed divisor? if not... */ |
1057 | struct clk_div_table *table; /* is it a table based divisor? */ | 1064 | struct clk_div_table *table; /* is it a table based divisor? */ |
1058 | u8 shift; /* otherwise it's a normal divisor with this shift */ | 1065 | u8 shift; /* otherwise it's a normal divisor with this shift */ |
@@ -1075,23 +1082,26 @@ static const struct divs_data pll5_divs_data __initconst = { | |||
1075 | .div = { | 1082 | .div = { |
1076 | { .shift = 0, .pow = 0, }, /* M, DDR */ | 1083 | { .shift = 0, .pow = 0, }, /* M, DDR */ |
1077 | { .shift = 16, .pow = 1, }, /* P, other */ | 1084 | { .shift = 16, .pow = 1, }, /* P, other */ |
1085 | /* No output for the base factor clock */ | ||
1078 | } | 1086 | } |
1079 | }; | 1087 | }; |
1080 | 1088 | ||
1081 | static const struct divs_data pll6_divs_data __initconst = { | 1089 | static const struct divs_data pll6_divs_data __initconst = { |
1082 | .factors = &sun4i_pll6_data, | 1090 | .factors = &sun4i_pll6_data, |
1083 | .ndivs = 2, | 1091 | .ndivs = 3, |
1084 | .div = { | 1092 | .div = { |
1085 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ | 1093 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ |
1086 | { .fixed = 2 }, /* P, other */ | 1094 | { .fixed = 2 }, /* P, other */ |
1095 | { .self = 1 }, /* base factor clock, 2x */ | ||
1087 | } | 1096 | } |
1088 | }; | 1097 | }; |
1089 | 1098 | ||
1090 | static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { | 1099 | static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { |
1091 | .factors = &sun6i_a31_pll6_data, | 1100 | .factors = &sun6i_a31_pll6_data, |
1092 | .ndivs = 1, | 1101 | .ndivs = 2, |
1093 | .div = { | 1102 | .div = { |
1094 | { .fixed = 2 }, /* normal output */ | 1103 | { .fixed = 2 }, /* normal output */ |
1104 | { .self = 1 }, /* base factor clock, 2x */ | ||
1095 | } | 1105 | } |
1096 | }; | 1106 | }; |
1097 | 1107 | ||
@@ -1122,6 +1132,10 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
1122 | int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; | 1132 | int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; |
1123 | int flags, clkflags; | 1133 | int flags, clkflags; |
1124 | 1134 | ||
1135 | /* if number of children known, use it */ | ||
1136 | if (data->ndivs) | ||
1137 | ndivs = data->ndivs; | ||
1138 | |||
1125 | /* Set up factor clock that we will be dividing */ | 1139 | /* Set up factor clock that we will be dividing */ |
1126 | pclk = sunxi_factors_clk_setup(node, data->factors); | 1140 | pclk = sunxi_factors_clk_setup(node, data->factors); |
1127 | parent = __clk_get_name(pclk); | 1141 | parent = __clk_get_name(pclk); |
@@ -1132,7 +1146,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
1132 | if (!clk_data) | 1146 | if (!clk_data) |
1133 | return; | 1147 | return; |
1134 | 1148 | ||
1135 | clks = kzalloc((SUNXI_DIVS_MAX_QTY+1) * sizeof(*clks), GFP_KERNEL); | 1149 | clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); |
1136 | if (!clks) | 1150 | if (!clks) |
1137 | goto free_clkdata; | 1151 | goto free_clkdata; |
1138 | 1152 | ||
@@ -1142,15 +1156,17 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
1142 | * our RAM clock! */ | 1156 | * our RAM clock! */ |
1143 | clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; | 1157 | clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; |
1144 | 1158 | ||
1145 | /* if number of children known, use it */ | ||
1146 | if (data->ndivs) | ||
1147 | ndivs = data->ndivs; | ||
1148 | |||
1149 | for (i = 0; i < ndivs; i++) { | 1159 | for (i = 0; i < ndivs; i++) { |
1150 | if (of_property_read_string_index(node, "clock-output-names", | 1160 | if (of_property_read_string_index(node, "clock-output-names", |
1151 | i, &clk_name) != 0) | 1161 | i, &clk_name) != 0) |
1152 | break; | 1162 | break; |
1153 | 1163 | ||
1164 | /* If this is the base factor clock, only update clks */ | ||
1165 | if (data->div[i].self) { | ||
1166 | clk_data->clks[i] = pclk; | ||
1167 | continue; | ||
1168 | } | ||
1169 | |||
1154 | gate_hw = NULL; | 1170 | gate_hw = NULL; |
1155 | rate_hw = NULL; | 1171 | rate_hw = NULL; |
1156 | rate_ops = NULL; | 1172 | rate_ops = NULL; |
@@ -1209,9 +1225,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
1209 | clk_register_clkdev(clks[i], clk_name, NULL); | 1225 | clk_register_clkdev(clks[i], clk_name, NULL); |
1210 | } | 1226 | } |
1211 | 1227 | ||
1212 | /* The last clock available on the getter is the parent */ | ||
1213 | clks[i++] = pclk; | ||
1214 | |||
1215 | /* Adjust to the real max */ | 1228 | /* Adjust to the real max */ |
1216 | clk_data->clk_num = i; | 1229 | clk_data->clk_num = i; |
1217 | 1230 | ||