aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2015-03-24 13:22:07 -0400
committerMaxime Ripard <maxime.ripard@free-electrons.com>2015-03-25 14:46:32 -0400
commit934fe5f48ae52841f8a5f5e0411147a8ccd171c1 (patch)
treefb00b27ce88966a502c5c58e9af7558d9c6f4d31
parentb712a623bd5c3b04b005e757945d43441e0aa4a8 (diff)
clk: sunxi: Make divs clocks specify which output is the base factor clock
The current sunxi clock driver has the base factor clock of divs clocks as the last clock output of the clock node. This makes it rather difficult to add new outputs, such as fixed dividers, which were previously unknown. This patch makes the divs clocks data structure specify which output is the factor clock, and updates all current divs clocks accordingly. We can then add new outputs after the factor clocks, at least not breaking backward compatibility with regards to the devicetree bindings. Also replace kzalloc with kcalloc in sunxi_divs_clk_setup(). Signed-off-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c37
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
1052struct divs_data { 1052struct 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
1081static const struct divs_data pll6_divs_data __initconst = { 1089static 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
1090static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { 1099static 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