aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorSaravana Kannan <skannan@codeaurora.org>2012-04-26 01:58:56 -0400
committerMike Turquette <mturquette@linaro.org>2012-05-01 21:13:20 -0400
commit0197b3ea0f66cd2a11417f58fe1812858ea77908 (patch)
tree73b49012db637bb7f7dad53ee2edf2c6d651ffda /drivers/clk
parente447c50e3af5dcad3075c80bd1bdc4e2024b8186 (diff)
clk: Use a separate struct for holding init data.
Create a struct clk_init_data to hold all data that needs to be passed from the platfrom specific driver to the common clock framework during clock registration. Add a pointer to this struct inside clk_hw. This has several advantages: * Completely hides struct clk from many clock platform drivers and static clock initialization code that don't care for static initialization of the struct clks. * For platforms that want to do complete static initialization, it removed the need to directly mess with the struct clk's fields while still allowing to statically allocate struct clk. This keeps the code more future proof even if they include clk-private.h. * Simplifies the generic clk_register() function and allows adding optional fields in the future without modifying the function signature. * Simplifies the static initialization of clocks on all platforms by removing the need for forward delcarations or convoluted macros. Signed-off-by: Saravana Kannan <skannan@codeaurora.org> [mturquette@linaro.org: kept DEFINE_CLK_* macros and __clk_init] Signed-off-by: Mike Turquette <mturquette@linaro.org> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Jeremy Kerr <jeremy.kerr@canonical.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Arnd Bergman <arnd.bergmann@linaro.org> Cc: Paul Walmsley <paul@pwsan.com> Cc: Shawn Guo <shawn.guo@freescale.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Jamie Iles <jamie@jamieiles.com> Cc: Richard Zhao <richard.zhao@linaro.org> Cc: Saravana Kannan <skannan@codeaurora.org> Cc: Magnus Damm <magnus.damm@gmail.com> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Linus Walleij <linus.walleij@stericsson.com> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Amit Kucheria <amit.kucheria@linaro.org> Cc: Deepak Saxena <dsaxena@linaro.org> Cc: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/clk-divider.c14
-rw-r--r--drivers/clk/clk-fixed-rate.c14
-rw-r--r--drivers/clk/clk-gate.c15
-rw-r--r--drivers/clk/clk-mux.c10
-rw-r--r--drivers/clk/clk.c89
5 files changed, 89 insertions, 53 deletions
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 90627e4069af..8ea11b444528 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -167,6 +167,7 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
167{ 167{
168 struct clk_divider *div; 168 struct clk_divider *div;
169 struct clk *clk; 169 struct clk *clk;
170 struct clk_init_data init;
170 171
171 /* allocate the divider */ 172 /* allocate the divider */
172 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); 173 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
@@ -175,19 +176,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
175 return ERR_PTR(-ENOMEM); 176 return ERR_PTR(-ENOMEM);
176 } 177 }
177 178
179 init.name = name;
180 init.ops = &clk_divider_ops;
181 init.flags = flags;
182 init.parent_names = (parent_name ? &parent_name: NULL);
183 init.num_parents = (parent_name ? 1 : 0);
184
178 /* struct clk_divider assignments */ 185 /* struct clk_divider assignments */
179 div->reg = reg; 186 div->reg = reg;
180 div->shift = shift; 187 div->shift = shift;
181 div->width = width; 188 div->width = width;
182 div->flags = clk_divider_flags; 189 div->flags = clk_divider_flags;
183 div->lock = lock; 190 div->lock = lock;
191 div->hw.init = &init;
184 192
185 /* register the clock */ 193 /* register the clock */
186 clk = clk_register(dev, name, 194 clk = clk_register(dev, &div->hw);
187 &clk_divider_ops, &div->hw,
188 (parent_name ? &parent_name: NULL),
189 (parent_name ? 1 : 0),
190 flags);
191 195
192 if (IS_ERR(clk)) 196 if (IS_ERR(clk))
193 kfree(div); 197 kfree(div);
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index b555a04c8df8..cbd246229786 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -52,6 +52,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
52{ 52{
53 struct clk_fixed_rate *fixed; 53 struct clk_fixed_rate *fixed;
54 struct clk *clk; 54 struct clk *clk;
55 struct clk_init_data init;
55 56
56 /* allocate fixed-rate clock */ 57 /* allocate fixed-rate clock */
57 fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); 58 fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
@@ -60,15 +61,18 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
60 return ERR_PTR(-ENOMEM); 61 return ERR_PTR(-ENOMEM);
61 } 62 }
62 63
64 init.name = name;
65 init.ops = &clk_fixed_rate_ops;
66 init.flags = flags;
67 init.parent_names = (parent_name ? &parent_name: NULL);
68 init.num_parents = (parent_name ? 1 : 0);
69
63 /* struct clk_fixed_rate assignments */ 70 /* struct clk_fixed_rate assignments */
64 fixed->fixed_rate = fixed_rate; 71 fixed->fixed_rate = fixed_rate;
72 fixed->hw.init = &init;
65 73
66 /* register the clock */ 74 /* register the clock */
67 clk = clk_register(dev, name, 75 clk = clk_register(dev, &fixed->hw);
68 &clk_fixed_rate_ops, &fixed->hw,
69 (parent_name ? &parent_name : NULL),
70 (parent_name ? 1 : 0),
71 flags);
72 76
73 if (IS_ERR(clk)) 77 if (IS_ERR(clk))
74 kfree(fixed); 78 kfree(fixed);
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 00216164fb9d..578465e04be6 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -119,6 +119,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
119{ 119{
120 struct clk_gate *gate; 120 struct clk_gate *gate;
121 struct clk *clk; 121 struct clk *clk;
122 struct clk_init_data init;
122 123
123 /* allocate the gate */ 124 /* allocate the gate */
124 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 125 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
@@ -127,18 +128,20 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
127 return ERR_PTR(-ENOMEM); 128 return ERR_PTR(-ENOMEM);
128 } 129 }
129 130
131 init.name = name;
132 init.ops = &clk_gate_ops;
133 init.flags = flags;
134 init.parent_names = (parent_name ? &parent_name: NULL);
135 init.num_parents = (parent_name ? 1 : 0);
136
130 /* struct clk_gate assignments */ 137 /* struct clk_gate assignments */
131 gate->reg = reg; 138 gate->reg = reg;
132 gate->bit_idx = bit_idx; 139 gate->bit_idx = bit_idx;
133 gate->flags = clk_gate_flags; 140 gate->flags = clk_gate_flags;
134 gate->lock = lock; 141 gate->lock = lock;
142 gate->hw.init = &init;
135 143
136 /* register the clock */ 144 clk = clk_register(dev, &gate->hw);
137 clk = clk_register(dev, name,
138 &clk_gate_ops, &gate->hw,
139 (parent_name ? &parent_name : NULL),
140 (parent_name ? 1 : 0),
141 flags);
142 145
143 if (IS_ERR(clk)) 146 if (IS_ERR(clk))
144 kfree(gate); 147 kfree(gate);
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 6e58f11ab81f..8e97491902e7 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -95,6 +95,7 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
95{ 95{
96 struct clk_mux *mux; 96 struct clk_mux *mux;
97 struct clk *clk; 97 struct clk *clk;
98 struct clk_init_data init;
98 99
99 /* allocate the mux */ 100 /* allocate the mux */
100 mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); 101 mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
@@ -103,6 +104,12 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
103 return ERR_PTR(-ENOMEM); 104 return ERR_PTR(-ENOMEM);
104 } 105 }
105 106
107 init.name = name;
108 init.ops = &clk_mux_ops;
109 init.flags = flags;
110 init.parent_names = parent_names;
111 init.num_parents = num_parents;
112
106 /* struct clk_mux assignments */ 113 /* struct clk_mux assignments */
107 mux->reg = reg; 114 mux->reg = reg;
108 mux->shift = shift; 115 mux->shift = shift;
@@ -110,8 +117,7 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
110 mux->flags = clk_mux_flags; 117 mux->flags = clk_mux_flags;
111 mux->lock = lock; 118 mux->lock = lock;
112 119
113 clk = clk_register(dev, name, &clk_mux_ops, &mux->hw, 120 clk = clk_register(dev, &mux->hw);
114 parent_names, num_parents, flags);
115 121
116 if (IS_ERR(clk)) 122 if (IS_ERR(clk))
117 kfree(mux); 123 kfree(mux);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2dd20c01134d..c81803b9ba35 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1169,26 +1169,6 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
1169 * 1169 *
1170 * Initializes the lists in struct clk, queries the hardware for the 1170 * Initializes the lists in struct clk, queries the hardware for the
1171 * parent and rate and sets them both. 1171 * parent and rate and sets them both.
1172 *
1173 * Any struct clk passed into __clk_init must have the following members
1174 * populated:
1175 * .name
1176 * .ops
1177 * .hw
1178 * .parent_names
1179 * .num_parents
1180 * .flags
1181 *
1182 * Essentially, everything that would normally be passed into clk_register is
1183 * assumed to be initialized already in __clk_init. The other members may be
1184 * populated, but are optional.
1185 *
1186 * __clk_init is only exposed via clk-private.h and is intended for use with
1187 * very large numbers of clocks that need to be statically initialized. It is
1188 * a layering violation to include clk-private.h from any code which implements
1189 * a clock's .ops; as such any statically initialized clock data MUST be in a
1190 * separate C file from the logic that implements it's operations. Returns 0
1191 * on success, otherwise an error code.
1192 */ 1172 */
1193int __clk_init(struct device *dev, struct clk *clk) 1173int __clk_init(struct device *dev, struct clk *clk)
1194{ 1174{
@@ -1321,14 +1301,47 @@ out:
1321} 1301}
1322 1302
1323/** 1303/**
1304 * __clk_register - register a clock and return a cookie.
1305 *
1306 * Same as clk_register, except that the .clk field inside hw shall point to a
1307 * preallocated (generally statically allocated) struct clk. None of the fields
1308 * of the struct clk need to be initialized.
1309 *
1310 * The data pointed to by .init and .clk field shall NOT be marked as init
1311 * data.
1312 *
1313 * __clk_register is only exposed via clk-private.h and is intended for use with
1314 * very large numbers of clocks that need to be statically initialized. It is
1315 * a layering violation to include clk-private.h from any code which implements
1316 * a clock's .ops; as such any statically initialized clock data MUST be in a
1317 * separate C file from the logic that implements it's operations. Returns 0
1318 * on success, otherwise an error code.
1319 */
1320struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
1321{
1322 int ret;
1323 struct clk *clk;
1324
1325 clk = hw->clk;
1326 clk->name = hw->init->name;
1327 clk->ops = hw->init->ops;
1328 clk->hw = hw;
1329 clk->flags = hw->init->flags;
1330 clk->parent_names = hw->init->parent_names;
1331 clk->num_parents = hw->init->num_parents;
1332
1333 ret = __clk_init(dev, clk);
1334 if (ret)
1335 return ERR_PTR(ret);
1336
1337 return clk;
1338}
1339EXPORT_SYMBOL_GPL(__clk_register);
1340
1341/**
1324 * clk_register - allocate a new clock, register it and return an opaque cookie 1342 * clk_register - allocate a new clock, register it and return an opaque cookie
1325 * @dev: device that is registering this clock 1343 * @dev: device that is registering this clock
1326 * @name: clock name
1327 * @ops: operations this clock supports
1328 * @hw: link to hardware-specific clock data 1344 * @hw: link to hardware-specific clock data
1329 * @parent_names: array of string names for all possible parents
1330 * @num_parents: number of possible parents
1331 * @flags: framework-level hints and quirks
1332 * 1345 *
1333 * clk_register is the primary interface for populating the clock tree with new 1346 * clk_register is the primary interface for populating the clock tree with new
1334 * clock nodes. It returns a pointer to the newly allocated struct clk which 1347 * clock nodes. It returns a pointer to the newly allocated struct clk which
@@ -1336,9 +1349,7 @@ out:
1336 * rest of the clock API. In the event of an error clk_register will return an 1349 * rest of the clock API. In the event of an error clk_register will return an
1337 * error code; drivers must test for an error code after calling clk_register. 1350 * error code; drivers must test for an error code after calling clk_register.
1338 */ 1351 */
1339struct clk *clk_register(struct device *dev, const char *name, 1352struct clk *clk_register(struct device *dev, struct clk_hw *hw)
1340 const struct clk_ops *ops, struct clk_hw *hw,
1341 const char **parent_names, u8 num_parents, unsigned long flags)
1342{ 1353{
1343 int i, ret; 1354 int i, ret;
1344 struct clk *clk; 1355 struct clk *clk;
@@ -1350,15 +1361,20 @@ struct clk *clk_register(struct device *dev, const char *name,
1350 goto fail_out; 1361 goto fail_out;
1351 } 1362 }
1352 1363
1353 clk->name = name; 1364 clk->name = kstrdup(hw->init->name, GFP_KERNEL);
1354 clk->ops = ops; 1365 if (!clk->name) {
1366 pr_err("%s: could not allocate clk->name\n", __func__);
1367 ret = -ENOMEM;
1368 goto fail_name;
1369 }
1370 clk->ops = hw->init->ops;
1355 clk->hw = hw; 1371 clk->hw = hw;
1356 clk->flags = flags; 1372 clk->flags = hw->init->flags;
1357 clk->num_parents = num_parents; 1373 clk->num_parents = hw->init->num_parents;
1358 hw->clk = clk; 1374 hw->clk = clk;
1359 1375
1360 /* allocate local copy in case parent_names is __initdata */ 1376 /* allocate local copy in case parent_names is __initdata */
1361 clk->parent_names = kzalloc((sizeof(char*) * num_parents), 1377 clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents),
1362 GFP_KERNEL); 1378 GFP_KERNEL);
1363 1379
1364 if (!clk->parent_names) { 1380 if (!clk->parent_names) {
@@ -1369,8 +1385,9 @@ struct clk *clk_register(struct device *dev, const char *name,
1369 1385
1370 1386
1371 /* copy each string name in case parent_names is __initdata */ 1387 /* copy each string name in case parent_names is __initdata */
1372 for (i = 0; i < num_parents; i++) { 1388 for (i = 0; i < clk->num_parents; i++) {
1373 clk->parent_names[i] = kstrdup(parent_names[i], GFP_KERNEL); 1389 clk->parent_names[i] = kstrdup(hw->init->parent_names[i],
1390 GFP_KERNEL);
1374 if (!clk->parent_names[i]) { 1391 if (!clk->parent_names[i]) {
1375 pr_err("%s: could not copy parent_names\n", __func__); 1392 pr_err("%s: could not copy parent_names\n", __func__);
1376 ret = -ENOMEM; 1393 ret = -ENOMEM;
@@ -1387,6 +1404,8 @@ fail_parent_names_copy:
1387 kfree(clk->parent_names[i]); 1404 kfree(clk->parent_names[i]);
1388 kfree(clk->parent_names); 1405 kfree(clk->parent_names);
1389fail_parent_names: 1406fail_parent_names:
1407 kfree(clk->name);
1408fail_name:
1390 kfree(clk); 1409 kfree(clk);
1391fail_out: 1410fail_out:
1392 return ERR_PTR(ret); 1411 return ERR_PTR(ret);