2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * Standard functionality for the common clock API.
10 #include <linux/module.h>
11 #include <linux/clk-provider.h>
12 #include <linux/slab.h>
13 #include <linux/err.h>
16 * DOC: basic fixed multiplier and divider clock that cannot gate
18 * Traits of this clock:
19 * prepare - clk_prepare only ensures that parents are prepared
20 * enable - clk_enable only ensures that parents are enabled
21 * rate - rate is fixed. clk->rate = parent->rate / div * mult
22 * parent - fixed parent. No clk_set_parent support
25 #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
27 static unsigned long clk_factor_recalc_rate(struct clk_hw
*hw
,
28 unsigned long parent_rate
)
30 struct clk_fixed_factor
*fix
= to_clk_fixed_factor(hw
);
31 unsigned long long int rate
;
33 rate
= (unsigned long long int)parent_rate
* fix
->mult
;
34 do_div(rate
, fix
->div
);
35 return (unsigned long)rate
;
38 static long clk_factor_round_rate(struct clk_hw
*hw
, unsigned long rate
,
41 struct clk_fixed_factor
*fix
= to_clk_fixed_factor(hw
);
43 if (__clk_get_flags(hw
->clk
) & CLK_SET_RATE_PARENT
) {
44 unsigned long best_parent
;
46 best_parent
= (rate
/ fix
->mult
) * fix
->div
;
47 *prate
= __clk_round_rate(__clk_get_parent(hw
->clk
),
51 return (*prate
/ fix
->div
) * fix
->mult
;
54 static int clk_factor_set_rate(struct clk_hw
*hw
, unsigned long rate
,
55 unsigned long parent_rate
)
60 struct clk_ops clk_fixed_factor_ops
= {
61 .round_rate
= clk_factor_round_rate
,
62 .set_rate
= clk_factor_set_rate
,
63 .recalc_rate
= clk_factor_recalc_rate
,
65 EXPORT_SYMBOL_GPL(clk_fixed_factor_ops
);
67 struct clk
*clk_register_fixed_factor(struct device
*dev
, const char *name
,
68 const char *parent_name
, unsigned long flags
,
69 unsigned int mult
, unsigned int div
)
71 struct clk_fixed_factor
*fix
;
72 struct clk_init_data init
;
75 fix
= kmalloc(sizeof(*fix
), GFP_KERNEL
);
77 pr_err("%s: could not allocate fixed factor clk\n", __func__
);
78 return ERR_PTR(-ENOMEM
);
81 /* struct clk_fixed_factor assignments */
87 init
.ops
= &clk_fixed_factor_ops
;
88 init
.flags
= flags
| CLK_IS_BASIC
;
89 init
.parent_names
= &parent_name
;
92 clk
= clk_register(dev
, &fix
->hw
);