Merge tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-block.git] / drivers / clk / clk-divider.c
CommitLineData
e1bd55e5 1// SPDX-License-Identifier: GPL-2.0
9d9f78ed
MT
2/*
3 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
4 * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
5 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
6 *
9d9f78ed
MT
7 * Adjustable divider clock implementation
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/io.h>
14#include <linux/err.h>
15#include <linux/string.h>
1a3cd184 16#include <linux/log2.h>
9d9f78ed
MT
17
18/*
19 * DOC: basic adjustable divider clock that cannot gate
20 *
21 * Traits of this clock:
22 * prepare - clk_prepare only ensures that parents are prepared
23 * enable - clk_enable only ensures that parents are enabled
9556f9da 24 * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor)
9d9f78ed
MT
25 * parent - fixed parent. No clk_set_parent support
26 */
27
fab88ca7
SB
28static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
29 u8 width)
357c3f0a 30{
e6d3cc7b 31 unsigned int maxdiv = 0, mask = clk_div_mask(width);
357c3f0a
RN
32 const struct clk_div_table *clkt;
33
34 for (clkt = table; clkt->div; clkt++)
fab88ca7 35 if (clkt->div > maxdiv && clkt->val <= mask)
357c3f0a
RN
36 maxdiv = clkt->div;
37 return maxdiv;
38}
39
774b5143
MC
40static unsigned int _get_table_mindiv(const struct clk_div_table *table)
41{
42 unsigned int mindiv = UINT_MAX;
43 const struct clk_div_table *clkt;
44
45 for (clkt = table; clkt->div; clkt++)
46 if (clkt->div < mindiv)
47 mindiv = clkt->div;
48 return mindiv;
49}
50
bca9690b
SB
51static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
52 unsigned long flags)
6d9252bd 53{
bca9690b 54 if (flags & CLK_DIVIDER_ONE_BASED)
e6d3cc7b 55 return clk_div_mask(width);
bca9690b 56 if (flags & CLK_DIVIDER_POWER_OF_TWO)
e6d3cc7b 57 return 1 << clk_div_mask(width);
bca9690b 58 if (table)
fab88ca7 59 return _get_table_maxdiv(table, width);
e6d3cc7b 60 return clk_div_mask(width) + 1;
6d9252bd
RN
61}
62
357c3f0a
RN
63static unsigned int _get_table_div(const struct clk_div_table *table,
64 unsigned int val)
65{
66 const struct clk_div_table *clkt;
67
68 for (clkt = table; clkt->div; clkt++)
69 if (clkt->val == val)
70 return clkt->div;
71 return 0;
72}
73
bca9690b 74static unsigned int _get_div(const struct clk_div_table *table,
afe76c8f 75 unsigned int val, unsigned long flags, u8 width)
6d9252bd 76{
bca9690b 77 if (flags & CLK_DIVIDER_ONE_BASED)
6d9252bd 78 return val;
bca9690b 79 if (flags & CLK_DIVIDER_POWER_OF_TWO)
6d9252bd 80 return 1 << val;
afe76c8f 81 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
e6d3cc7b 82 return val ? val : clk_div_mask(width) + 1;
bca9690b
SB
83 if (table)
84 return _get_table_div(table, val);
6d9252bd
RN
85 return val + 1;
86}
87
357c3f0a
RN
88static unsigned int _get_table_val(const struct clk_div_table *table,
89 unsigned int div)
90{
91 const struct clk_div_table *clkt;
92
93 for (clkt = table; clkt->div; clkt++)
94 if (clkt->div == div)
95 return clkt->val;
96 return 0;
97}
98
bca9690b 99static unsigned int _get_val(const struct clk_div_table *table,
afe76c8f 100 unsigned int div, unsigned long flags, u8 width)
6d9252bd 101{
bca9690b 102 if (flags & CLK_DIVIDER_ONE_BASED)
6d9252bd 103 return div;
bca9690b 104 if (flags & CLK_DIVIDER_POWER_OF_TWO)
6d9252bd 105 return __ffs(div);
afe76c8f 106 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
e6d3cc7b 107 return (div == clk_div_mask(width) + 1) ? 0 : div;
bca9690b
SB
108 if (table)
109 return _get_table_val(table, div);
6d9252bd
RN
110 return div - 1;
111}
9d9f78ed 112
bca9690b
SB
113unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
114 unsigned int val,
115 const struct clk_div_table *table,
12a26c29 116 unsigned long flags, unsigned long width)
9d9f78ed 117{
bca9690b 118 unsigned int div;
9d9f78ed 119
12a26c29 120 div = _get_div(table, val, flags, width);
6d9252bd 121 if (!div) {
bca9690b 122 WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
056b2053 123 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
2f508a95 124 clk_hw_get_name(hw));
6d9252bd
RN
125 return parent_rate;
126 }
9d9f78ed 127
9556f9da 128 return DIV_ROUND_UP_ULL((u64)parent_rate, div);
9d9f78ed 129}
bca9690b
SB
130EXPORT_SYMBOL_GPL(divider_recalc_rate);
131
132static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
133 unsigned long parent_rate)
134{
135 struct clk_divider *divider = to_clk_divider(hw);
136 unsigned int val;
137
138 val = clk_readl(divider->reg) >> divider->shift;
e6d3cc7b 139 val &= clk_div_mask(divider->width);
bca9690b
SB
140
141 return divider_recalc_rate(hw, parent_rate, val, divider->table,
12a26c29 142 divider->flags, divider->width);
bca9690b 143}
9d9f78ed 144
357c3f0a
RN
145static bool _is_valid_table_div(const struct clk_div_table *table,
146 unsigned int div)
147{
148 const struct clk_div_table *clkt;
149
150 for (clkt = table; clkt->div; clkt++)
151 if (clkt->div == div)
152 return true;
153 return false;
154}
155
bca9690b
SB
156static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
157 unsigned long flags)
357c3f0a 158{
bca9690b 159 if (flags & CLK_DIVIDER_POWER_OF_TWO)
1a3cd184 160 return is_power_of_2(div);
bca9690b
SB
161 if (table)
162 return _is_valid_table_div(table, div);
357c3f0a
RN
163 return true;
164}
165
dd23c2cd
MC
166static int _round_up_table(const struct clk_div_table *table, int div)
167{
168 const struct clk_div_table *clkt;
fe52e750 169 int up = INT_MAX;
dd23c2cd
MC
170
171 for (clkt = table; clkt->div; clkt++) {
172 if (clkt->div == div)
173 return clkt->div;
174 else if (clkt->div < div)
175 continue;
176
177 if ((clkt->div - div) < (up - div))
178 up = clkt->div;
179 }
180
181 return up;
182}
183
774b5143
MC
184static int _round_down_table(const struct clk_div_table *table, int div)
185{
186 const struct clk_div_table *clkt;
187 int down = _get_table_mindiv(table);
188
189 for (clkt = table; clkt->div; clkt++) {
190 if (clkt->div == div)
191 return clkt->div;
192 else if (clkt->div > div)
193 continue;
194
195 if ((div - clkt->div) < (div - down))
196 down = clkt->div;
197 }
198
199 return down;
200}
201
bca9690b
SB
202static int _div_round_up(const struct clk_div_table *table,
203 unsigned long parent_rate, unsigned long rate,
204 unsigned long flags)
dd23c2cd 205{
9556f9da 206 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
dd23c2cd 207
bca9690b 208 if (flags & CLK_DIVIDER_POWER_OF_TWO)
dd23c2cd 209 div = __roundup_pow_of_two(div);
bca9690b
SB
210 if (table)
211 div = _round_up_table(table, div);
dd23c2cd
MC
212
213 return div;
214}
215
bca9690b
SB
216static int _div_round_closest(const struct clk_div_table *table,
217 unsigned long parent_rate, unsigned long rate,
218 unsigned long flags)
774b5143 219{
93155142 220 int up, down;
26bac95a 221 unsigned long up_rate, down_rate;
774b5143 222
9556f9da 223 up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
93155142 224 down = parent_rate / rate;
774b5143 225
bca9690b 226 if (flags & CLK_DIVIDER_POWER_OF_TWO) {
93155142
UKK
227 up = __roundup_pow_of_two(up);
228 down = __rounddown_pow_of_two(down);
bca9690b 229 } else if (table) {
93155142
UKK
230 up = _round_up_table(table, up);
231 down = _round_down_table(table, down);
774b5143
MC
232 }
233
9556f9da
BN
234 up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
235 down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
26bac95a
UKK
236
237 return (rate - up_rate) <= (down_rate - rate) ? up : down;
774b5143
MC
238}
239
bca9690b
SB
240static int _div_round(const struct clk_div_table *table,
241 unsigned long parent_rate, unsigned long rate,
242 unsigned long flags)
774b5143 243{
bca9690b
SB
244 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
245 return _div_round_closest(table, parent_rate, rate, flags);
774b5143 246
bca9690b 247 return _div_round_up(table, parent_rate, rate, flags);
774b5143
MC
248}
249
bca9690b
SB
250static bool _is_best_div(unsigned long rate, unsigned long now,
251 unsigned long best, unsigned long flags)
774b5143 252{
bca9690b 253 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
774b5143
MC
254 return abs(rate - now) < abs(rate - best);
255
256 return now <= rate && now > best;
257}
258
bca9690b
SB
259static int _next_div(const struct clk_div_table *table, int div,
260 unsigned long flags)
0e2de78e
MC
261{
262 div++;
263
bca9690b 264 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0e2de78e 265 return __roundup_pow_of_two(div);
bca9690b
SB
266 if (table)
267 return _round_up_table(table, div);
0e2de78e
MC
268
269 return div;
270}
271
22833a91
MR
272static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
273 unsigned long rate,
bca9690b
SB
274 unsigned long *best_parent_rate,
275 const struct clk_div_table *table, u8 width,
276 unsigned long flags)
9d9f78ed 277{
9d9f78ed
MT
278 int i, bestdiv = 0;
279 unsigned long parent_rate, best = 0, now, maxdiv;
081c9025 280 unsigned long parent_rate_saved = *best_parent_rate;
9d9f78ed
MT
281
282 if (!rate)
283 rate = 1;
284
bca9690b 285 maxdiv = _get_maxdiv(table, width, flags);
9d9f78ed 286
98d8a60e 287 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
81536e07 288 parent_rate = *best_parent_rate;
bca9690b 289 bestdiv = _div_round(table, parent_rate, rate, flags);
9d9f78ed
MT
290 bestdiv = bestdiv == 0 ? 1 : bestdiv;
291 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
292 return bestdiv;
293 }
294
295 /*
296 * The maximum divider we can use without overflowing
297 * unsigned long in rate * i below
298 */
299 maxdiv = min(ULONG_MAX / rate, maxdiv);
300
653d1452
MY
301 for (i = _next_div(table, 0, flags); i <= maxdiv;
302 i = _next_div(table, i, flags)) {
081c9025
SG
303 if (rate * i == parent_rate_saved) {
304 /*
305 * It's the most ideal case if the requested rate can be
306 * divided from parent clock without needing to change
307 * parent rate, so return the divider immediately.
308 */
309 *best_parent_rate = parent_rate_saved;
310 return i;
311 }
22833a91 312 parent_rate = clk_hw_round_rate(parent, rate * i);
9556f9da 313 now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
bca9690b 314 if (_is_best_div(rate, now, best, flags)) {
9d9f78ed
MT
315 bestdiv = i;
316 best = now;
317 *best_parent_rate = parent_rate;
318 }
319 }
320
321 if (!bestdiv) {
bca9690b 322 bestdiv = _get_maxdiv(table, width, flags);
22833a91 323 *best_parent_rate = clk_hw_round_rate(parent, 1);
9d9f78ed
MT
324 }
325
326 return bestdiv;
327}
328
22833a91
MR
329long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
330 unsigned long rate, unsigned long *prate,
331 const struct clk_div_table *table,
332 u8 width, unsigned long flags)
9d9f78ed
MT
333{
334 int div;
bca9690b 335
22833a91 336 div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags);
9d9f78ed 337
9556f9da 338 return DIV_ROUND_UP_ULL((u64)*prate, div);
9d9f78ed 339}
22833a91 340EXPORT_SYMBOL_GPL(divider_round_rate_parent);
9d9f78ed 341
b15ee490
JB
342long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
343 unsigned long rate, unsigned long *prate,
344 const struct clk_div_table *table, u8 width,
345 unsigned long flags, unsigned int val)
346{
347 int div;
348
349 div = _get_div(table, val, flags, width);
350
351 /* Even a read-only clock can propagate a rate change */
352 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
353 if (!parent)
354 return -EINVAL;
355
356 *prate = clk_hw_round_rate(parent, rate * div);
357 }
358
359 return DIV_ROUND_UP_ULL((u64)*prate, div);
360}
361EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);
362
363
bca9690b
SB
364static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
365 unsigned long *prate)
9d9f78ed
MT
366{
367 struct clk_divider *divider = to_clk_divider(hw);
bca9690b
SB
368
369 /* if read only, just return current value */
370 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
b15ee490
JB
371 u32 val;
372
373 val = clk_readl(divider->reg) >> divider->shift;
374 val &= clk_div_mask(divider->width);
375
376 return divider_ro_round_rate(hw, rate, prate, divider->table,
377 divider->width, divider->flags,
378 val);
bca9690b
SB
379 }
380
381 return divider_round_rate(hw, rate, prate, divider->table,
382 divider->width, divider->flags);
383}
384
385int divider_get_val(unsigned long rate, unsigned long parent_rate,
386 const struct clk_div_table *table, u8 width,
387 unsigned long flags)
388{
6d9252bd 389 unsigned int div, value;
9d9f78ed 390
9556f9da 391 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
dd23c2cd 392
bca9690b 393 if (!_is_valid_div(table, div, flags))
dd23c2cd
MC
394 return -EINVAL;
395
afe76c8f 396 value = _get_val(table, div, flags, width);
bca9690b 397
e6d3cc7b 398 return min_t(unsigned int, value, clk_div_mask(width));
bca9690b
SB
399}
400EXPORT_SYMBOL_GPL(divider_get_val);
401
402static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
403 unsigned long parent_rate)
404{
405 struct clk_divider *divider = to_clk_divider(hw);
2316a7a3 406 int value;
bca9690b
SB
407 unsigned long flags = 0;
408 u32 val;
9d9f78ed 409
bca9690b
SB
410 value = divider_get_val(rate, parent_rate, divider->table,
411 divider->width, divider->flags);
2316a7a3
AF
412 if (value < 0)
413 return value;
9d9f78ed
MT
414
415 if (divider->lock)
416 spin_lock_irqsave(divider->lock, flags);
661e2180
SB
417 else
418 __acquire(divider->lock);
9d9f78ed 419
d57dfe75 420 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
e6d3cc7b 421 val = clk_div_mask(divider->width) << (divider->shift + 16);
d57dfe75 422 } else {
aa514ce3 423 val = clk_readl(divider->reg);
e6d3cc7b 424 val &= ~(clk_div_mask(divider->width) << divider->shift);
d57dfe75 425 }
2316a7a3 426 val |= (u32)value << divider->shift;
aa514ce3 427 clk_writel(val, divider->reg);
9d9f78ed
MT
428
429 if (divider->lock)
430 spin_unlock_irqrestore(divider->lock, flags);
661e2180
SB
431 else
432 __release(divider->lock);
9d9f78ed
MT
433
434 return 0;
435}
9d9f78ed 436
822c250e 437const struct clk_ops clk_divider_ops = {
9d9f78ed
MT
438 .recalc_rate = clk_divider_recalc_rate,
439 .round_rate = clk_divider_round_rate,
440 .set_rate = clk_divider_set_rate,
441};
442EXPORT_SYMBOL_GPL(clk_divider_ops);
443
50359819
HS
444const struct clk_ops clk_divider_ro_ops = {
445 .recalc_rate = clk_divider_recalc_rate,
446 .round_rate = clk_divider_round_rate,
447};
448EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
449
eb7d264f 450static struct clk_hw *_register_divider(struct device *dev, const char *name,
9d9f78ed
MT
451 const char *parent_name, unsigned long flags,
452 void __iomem *reg, u8 shift, u8 width,
357c3f0a
RN
453 u8 clk_divider_flags, const struct clk_div_table *table,
454 spinlock_t *lock)
9d9f78ed
MT
455{
456 struct clk_divider *div;
eb7d264f 457 struct clk_hw *hw;
0197b3ea 458 struct clk_init_data init;
eb7d264f 459 int ret;
9d9f78ed 460
d57dfe75
HZ
461 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
462 if (width + shift > 16) {
463 pr_warn("divider value exceeds LOWORD field\n");
464 return ERR_PTR(-EINVAL);
465 }
466 }
467
27d54591 468 /* allocate the divider */
d122db7e
SB
469 div = kzalloc(sizeof(*div), GFP_KERNEL);
470 if (!div)
27d54591 471 return ERR_PTR(-ENOMEM);
9d9f78ed 472
0197b3ea 473 init.name = name;
50359819
HS
474 if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
475 init.ops = &clk_divider_ro_ops;
476 else
477 init.ops = &clk_divider_ops;
f7d8caad 478 init.flags = flags | CLK_IS_BASIC;
0197b3ea
SK
479 init.parent_names = (parent_name ? &parent_name: NULL);
480 init.num_parents = (parent_name ? 1 : 0);
481
9d9f78ed
MT
482 /* struct clk_divider assignments */
483 div->reg = reg;
484 div->shift = shift;
485 div->width = width;
486 div->flags = clk_divider_flags;
487 div->lock = lock;
0197b3ea 488 div->hw.init = &init;
357c3f0a 489 div->table = table;
9d9f78ed 490
27d54591 491 /* register the clock */
eb7d264f
SB
492 hw = &div->hw;
493 ret = clk_hw_register(dev, hw);
494 if (ret) {
27d54591 495 kfree(div);
eb7d264f
SB
496 hw = ERR_PTR(ret);
497 }
9d9f78ed 498
eb7d264f 499 return hw;
9d9f78ed 500}
357c3f0a
RN
501
502/**
503 * clk_register_divider - register a divider clock with the clock framework
504 * @dev: device registering this clock
505 * @name: name of this clock
506 * @parent_name: name of clock's parent
507 * @flags: framework-specific flags
508 * @reg: register address to adjust divider
509 * @shift: number of bits to shift the bitfield
510 * @width: width of the bitfield
511 * @clk_divider_flags: divider-specific flags for this clock
512 * @lock: shared register lock for this clock
513 */
514struct clk *clk_register_divider(struct device *dev, const char *name,
515 const char *parent_name, unsigned long flags,
516 void __iomem *reg, u8 shift, u8 width,
517 u8 clk_divider_flags, spinlock_t *lock)
518{
eb7d264f
SB
519 struct clk_hw *hw;
520
521 hw = _register_divider(dev, name, parent_name, flags, reg, shift,
357c3f0a 522 width, clk_divider_flags, NULL, lock);
eb7d264f
SB
523 if (IS_ERR(hw))
524 return ERR_CAST(hw);
525 return hw->clk;
357c3f0a 526}
4c5eeea9 527EXPORT_SYMBOL_GPL(clk_register_divider);
357c3f0a 528
eb7d264f
SB
529/**
530 * clk_hw_register_divider - register a divider clock with the clock framework
531 * @dev: device registering this clock
532 * @name: name of this clock
533 * @parent_name: name of clock's parent
534 * @flags: framework-specific flags
535 * @reg: register address to adjust divider
536 * @shift: number of bits to shift the bitfield
537 * @width: width of the bitfield
538 * @clk_divider_flags: divider-specific flags for this clock
539 * @lock: shared register lock for this clock
540 */
541struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
542 const char *parent_name, unsigned long flags,
543 void __iomem *reg, u8 shift, u8 width,
544 u8 clk_divider_flags, spinlock_t *lock)
545{
546 return _register_divider(dev, name, parent_name, flags, reg, shift,
547 width, clk_divider_flags, NULL, lock);
548}
549EXPORT_SYMBOL_GPL(clk_hw_register_divider);
550
357c3f0a
RN
551/**
552 * clk_register_divider_table - register a table based divider clock with
553 * the clock framework
554 * @dev: device registering this clock
555 * @name: name of this clock
556 * @parent_name: name of clock's parent
557 * @flags: framework-specific flags
558 * @reg: register address to adjust divider
559 * @shift: number of bits to shift the bitfield
560 * @width: width of the bitfield
561 * @clk_divider_flags: divider-specific flags for this clock
562 * @table: array of divider/value pairs ending with a div set to 0
563 * @lock: shared register lock for this clock
564 */
565struct clk *clk_register_divider_table(struct device *dev, const char *name,
566 const char *parent_name, unsigned long flags,
567 void __iomem *reg, u8 shift, u8 width,
568 u8 clk_divider_flags, const struct clk_div_table *table,
569 spinlock_t *lock)
570{
eb7d264f
SB
571 struct clk_hw *hw;
572
573 hw = _register_divider(dev, name, parent_name, flags, reg, shift,
357c3f0a 574 width, clk_divider_flags, table, lock);
eb7d264f
SB
575 if (IS_ERR(hw))
576 return ERR_CAST(hw);
577 return hw->clk;
357c3f0a 578}
4c5eeea9 579EXPORT_SYMBOL_GPL(clk_register_divider_table);
4e3c021f 580
eb7d264f
SB
581/**
582 * clk_hw_register_divider_table - register a table based divider clock with
583 * the clock framework
584 * @dev: device registering this clock
585 * @name: name of this clock
586 * @parent_name: name of clock's parent
587 * @flags: framework-specific flags
588 * @reg: register address to adjust divider
589 * @shift: number of bits to shift the bitfield
590 * @width: width of the bitfield
591 * @clk_divider_flags: divider-specific flags for this clock
592 * @table: array of divider/value pairs ending with a div set to 0
593 * @lock: shared register lock for this clock
594 */
595struct clk_hw *clk_hw_register_divider_table(struct device *dev,
596 const char *name, const char *parent_name, unsigned long flags,
597 void __iomem *reg, u8 shift, u8 width,
598 u8 clk_divider_flags, const struct clk_div_table *table,
599 spinlock_t *lock)
600{
601 return _register_divider(dev, name, parent_name, flags, reg, shift,
602 width, clk_divider_flags, table, lock);
603}
604EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
605
4e3c021f
KK
606void clk_unregister_divider(struct clk *clk)
607{
608 struct clk_divider *div;
609 struct clk_hw *hw;
610
611 hw = __clk_get_hw(clk);
612 if (!hw)
613 return;
614
615 div = to_clk_divider(hw);
616
617 clk_unregister(clk);
618 kfree(div);
619}
620EXPORT_SYMBOL_GPL(clk_unregister_divider);
eb7d264f
SB
621
622/**
623 * clk_hw_unregister_divider - unregister a clk divider
624 * @hw: hardware-specific clock data to unregister
625 */
626void clk_hw_unregister_divider(struct clk_hw *hw)
627{
628 struct clk_divider *div;
629
630 div = to_clk_divider(hw);
631
632 clk_hw_unregister(hw);
633 kfree(div);
634}
635EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);