diff options
author | Mike Turquette <mturquette@linaro.org> | 2012-03-16 02:11:20 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-03-16 16:35:02 -0400 |
commit | 9d9f78ed9af0e465d2fd15550471956e7f559b9f (patch) | |
tree | 8a65fc0844a35c928162f65b671a8a5786ea03ee /drivers/clk/clk-fixed-rate.c | |
parent | b2476490ef11134b65544d8f062cff96c53e941b (diff) |
clk: basic clock hardware types
Many platforms support simple gateable clocks, fixed-rate clocks,
adjustable divider clocks and multi-parent multiplexer clocks.
This patch introduces basic clock types for the above-mentioned hardware
which share some common characteristics.
Based on original work by Jeremy Kerr and contribution by Jamie Iles.
Dividers and multiplexor clocks originally contributed by Richard Zhao &
Sascha Hauer.
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Mike Turquette <mturquette@ti.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: 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>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/clk/clk-fixed-rate.c')
-rw-r--r-- | drivers/clk/clk-fixed-rate.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c new file mode 100644 index 000000000000..90c79fb5d1bd --- /dev/null +++ b/drivers/clk/clk-fixed-rate.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com> | ||
3 | * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * Fixed rate clock implementation | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/err.h> | ||
17 | |||
18 | /* | ||
19 | * DOC: basic fixed-rate clock that cannot gate | ||
20 | * | ||
21 | * Traits of this clock: | ||
22 | * prepare - clk_(un)prepare only ensures parents are prepared | ||
23 | * enable - clk_enable only ensures parents are enabled | ||
24 | * rate - rate is always a fixed value. No clk_set_rate support | ||
25 | * parent - fixed parent. No clk_set_parent support | ||
26 | */ | ||
27 | |||
28 | #define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) | ||
29 | |||
30 | static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, | ||
31 | unsigned long parent_rate) | ||
32 | { | ||
33 | return to_clk_fixed_rate(hw)->fixed_rate; | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(clk_fixed_rate_recalc_rate); | ||
36 | |||
37 | struct clk_ops clk_fixed_rate_ops = { | ||
38 | .recalc_rate = clk_fixed_rate_recalc_rate, | ||
39 | }; | ||
40 | EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); | ||
41 | |||
42 | struct clk *clk_register_fixed_rate(struct device *dev, const char *name, | ||
43 | const char *parent_name, unsigned long flags, | ||
44 | unsigned long fixed_rate) | ||
45 | { | ||
46 | struct clk_fixed_rate *fixed; | ||
47 | char **parent_names = NULL; | ||
48 | u8 len; | ||
49 | |||
50 | fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); | ||
51 | |||
52 | if (!fixed) { | ||
53 | pr_err("%s: could not allocate fixed clk\n", __func__); | ||
54 | return ERR_PTR(-ENOMEM); | ||
55 | } | ||
56 | |||
57 | /* struct clk_fixed_rate assignments */ | ||
58 | fixed->fixed_rate = fixed_rate; | ||
59 | |||
60 | if (parent_name) { | ||
61 | parent_names = kmalloc(sizeof(char *), GFP_KERNEL); | ||
62 | |||
63 | if (! parent_names) | ||
64 | goto out; | ||
65 | |||
66 | len = sizeof(char) * strlen(parent_name); | ||
67 | |||
68 | parent_names[0] = kmalloc(len, GFP_KERNEL); | ||
69 | |||
70 | if (!parent_names[0]) | ||
71 | goto out; | ||
72 | |||
73 | strncpy(parent_names[0], parent_name, len); | ||
74 | } | ||
75 | |||
76 | out: | ||
77 | return clk_register(dev, name, | ||
78 | &clk_fixed_rate_ops, &fixed->hw, | ||
79 | parent_names, | ||
80 | (parent_name ? 1 : 0), | ||
81 | flags); | ||
82 | } | ||