aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/sata_mv.c40
-rw-r--r--drivers/clk/Kconfig12
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/clk-divider.c68
-rw-r--r--drivers/clk/clk-fixed-factor.c95
-rw-r--r--drivers/clk/clk-fixed-rate.c49
-rw-r--r--drivers/clk/clk-gate.c104
-rw-r--r--drivers/clk/clk-mux.c27
-rw-r--r--drivers/clk/clk.c279
-rw-r--r--drivers/clk/mxs/Makefile8
-rw-r--r--drivers/clk/mxs/clk-div.c110
-rw-r--r--drivers/clk/mxs/clk-frac.c139
-rw-r--r--drivers/clk/mxs/clk-imx23.c204
-rw-r--r--drivers/clk/mxs/clk-imx28.c337
-rw-r--r--drivers/clk/mxs/clk-pll.c116
-rw-r--r--drivers/clk/mxs/clk-ref.c154
-rw-r--r--drivers/clk/mxs/clk.c28
-rw-r--r--drivers/clk/mxs/clk.h66
-rw-r--r--drivers/clk/spear/Makefile8
-rw-r--r--drivers/clk/spear/clk-aux-synth.c198
-rw-r--r--drivers/clk/spear/clk-frac-synth.c165
-rw-r--r--drivers/clk/spear/clk-gpt-synth.c154
-rw-r--r--drivers/clk/spear/clk-vco-pll.c363
-rw-r--r--drivers/clk/spear/clk.c36
-rw-r--r--drivers/clk/spear/clk.h134
-rw-r--r--drivers/clk/spear/spear3xx_clock.c612
-rw-r--r--drivers/clk/spear/spear6xx_clock.c342
-rw-r--r--drivers/crypto/mv_cesa.c14
-rw-r--r--drivers/dma/imx-sdma.c40
-rw-r--r--drivers/dma/ipu/ipu_idmac.c6
-rw-r--r--drivers/dma/mv_xor.c15
-rw-r--r--drivers/dma/mv_xor.h1
-rw-r--r--drivers/media/video/mx3_camera.c4
-rw-r--r--drivers/mmc/host/mvsdio.c14
-rw-r--r--drivers/mmc/host/mxcmmc.c39
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c42
-rw-r--r--drivers/mtd/nand/mxc_nand.c6
-rw-r--r--drivers/mtd/nand/orion_nand.c18
-rw-r--r--drivers/net/ethernet/freescale/fec.c35
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c42
-rw-r--r--drivers/rtc/rtc-imxdi.c6
-rw-r--r--drivers/spi/spi-imx.c30
-rw-r--r--drivers/spi/spi-orion.c30
-rw-r--r--drivers/tty/serial/imx.c38
-rw-r--r--drivers/usb/host/ehci-mxc.c62
-rw-r--r--drivers/usb/host/ehci-orion.c16
-rw-r--r--drivers/video/imxfb.c50
-rw-r--r--drivers/w1/masters/mxc_w1.c4
-rw-r--r--drivers/watchdog/imx2_wdt.c2
-rw-r--r--drivers/watchdog/orion_wdt.c16
50 files changed, 3988 insertions, 395 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 7336d4a7ab3..24712adf69d 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -553,6 +553,7 @@ struct mv_host_priv {
553 553
554#if defined(CONFIG_HAVE_CLK) 554#if defined(CONFIG_HAVE_CLK)
555 struct clk *clk; 555 struct clk *clk;
556 struct clk **port_clks;
556#endif 557#endif
557 /* 558 /*
558 * These consistent DMA memory pools give us guaranteed 559 * These consistent DMA memory pools give us guaranteed
@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev)
4027 struct resource *res; 4028 struct resource *res;
4028 int n_ports = 0; 4029 int n_ports = 0;
4029 int rc; 4030 int rc;
4031#if defined(CONFIG_HAVE_CLK)
4032 int port;
4033#endif
4030 4034
4031 ata_print_version_once(&pdev->dev, DRV_VERSION); 4035 ata_print_version_once(&pdev->dev, DRV_VERSION);
4032 4036
@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev)
4054 4058
4055 if (!host || !hpriv) 4059 if (!host || !hpriv)
4056 return -ENOMEM; 4060 return -ENOMEM;
4061#if defined(CONFIG_HAVE_CLK)
4062 hpriv->port_clks = devm_kzalloc(&pdev->dev,
4063 sizeof(struct clk *) * n_ports,
4064 GFP_KERNEL);
4065 if (!hpriv->port_clks)
4066 return -ENOMEM;
4067#endif
4057 host->private_data = hpriv; 4068 host->private_data = hpriv;
4058 hpriv->n_ports = n_ports; 4069 hpriv->n_ports = n_ports;
4059 hpriv->board_idx = chip_soc; 4070 hpriv->board_idx = chip_soc;
@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev)
4066#if defined(CONFIG_HAVE_CLK) 4077#if defined(CONFIG_HAVE_CLK)
4067 hpriv->clk = clk_get(&pdev->dev, NULL); 4078 hpriv->clk = clk_get(&pdev->dev, NULL);
4068 if (IS_ERR(hpriv->clk)) 4079 if (IS_ERR(hpriv->clk))
4069 dev_notice(&pdev->dev, "cannot get clkdev\n"); 4080 dev_notice(&pdev->dev, "cannot get optional clkdev\n");
4070 else 4081 else
4071 clk_enable(hpriv->clk); 4082 clk_prepare_enable(hpriv->clk);
4083
4084 for (port = 0; port < n_ports; port++) {
4085 char port_number[16];
4086 sprintf(port_number, "%d", port);
4087 hpriv->port_clks[port] = clk_get(&pdev->dev, port_number);
4088 if (!IS_ERR(hpriv->port_clks[port]))
4089 clk_prepare_enable(hpriv->port_clks[port]);
4090 }
4072#endif 4091#endif
4073 4092
4074 /* 4093 /*
@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev)
4098err: 4117err:
4099#if defined(CONFIG_HAVE_CLK) 4118#if defined(CONFIG_HAVE_CLK)
4100 if (!IS_ERR(hpriv->clk)) { 4119 if (!IS_ERR(hpriv->clk)) {
4101 clk_disable(hpriv->clk); 4120 clk_disable_unprepare(hpriv->clk);
4102 clk_put(hpriv->clk); 4121 clk_put(hpriv->clk);
4103 } 4122 }
4123 for (port = 0; port < n_ports; port++) {
4124 if (!IS_ERR(hpriv->port_clks[port])) {
4125 clk_disable_unprepare(hpriv->port_clks[port]);
4126 clk_put(hpriv->port_clks[port]);
4127 }
4128 }
4104#endif 4129#endif
4105 4130
4106 return rc; 4131 return rc;
@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
4119 struct ata_host *host = platform_get_drvdata(pdev); 4144 struct ata_host *host = platform_get_drvdata(pdev);
4120#if defined(CONFIG_HAVE_CLK) 4145#if defined(CONFIG_HAVE_CLK)
4121 struct mv_host_priv *hpriv = host->private_data; 4146 struct mv_host_priv *hpriv = host->private_data;
4147 int port;
4122#endif 4148#endif
4123 ata_host_detach(host); 4149 ata_host_detach(host);
4124 4150
4125#if defined(CONFIG_HAVE_CLK) 4151#if defined(CONFIG_HAVE_CLK)
4126 if (!IS_ERR(hpriv->clk)) { 4152 if (!IS_ERR(hpriv->clk)) {
4127 clk_disable(hpriv->clk); 4153 clk_disable_unprepare(hpriv->clk);
4128 clk_put(hpriv->clk); 4154 clk_put(hpriv->clk);
4129 } 4155 }
4156 for (port = 0; port < host->n_ports; port++) {
4157 if (!IS_ERR(hpriv->port_clks[port])) {
4158 clk_disable_unprepare(hpriv->port_clks[port]);
4159 clk_put(hpriv->port_clks[port]);
4160 }
4161 }
4130#endif 4162#endif
4131 return 0; 4163 return 0;
4132} 4164}
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 165e1febae5..4864407e3fc 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -12,6 +12,7 @@ config HAVE_MACH_CLKDEV
12config COMMON_CLK 12config COMMON_CLK
13 bool 13 bool
14 select HAVE_CLK_PREPARE 14 select HAVE_CLK_PREPARE
15 select CLKDEV_LOOKUP
15 ---help--- 16 ---help---
16 The common clock framework is a single definition of struct 17 The common clock framework is a single definition of struct
17 clk, useful across many platforms, as well as an 18 clk, useful across many platforms, as well as an
@@ -22,17 +23,6 @@ config COMMON_CLK
22menu "Common Clock Framework" 23menu "Common Clock Framework"
23 depends on COMMON_CLK 24 depends on COMMON_CLK
24 25
25config COMMON_CLK_DISABLE_UNUSED
26 bool "Disabled unused clocks at boot"
27 depends on COMMON_CLK
28 ---help---
29 Traverses the entire clock tree and disables any clocks that are
30 enabled in hardware but have not been enabled by any device drivers.
31 This saves power and keeps the software model of the clock in line
32 with reality.
33
34 If in doubt, say "N".
35
36config COMMON_CLK_DEBUG 26config COMMON_CLK_DEBUG
37 bool "DebugFS representation of clock tree" 27 bool "DebugFS representation of clock tree"
38 depends on COMMON_CLK 28 depends on COMMON_CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1f736bc11c4..b9a5158a30b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,4 +1,7 @@
1 1
2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o 2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ 3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
4 clk-mux.o clk-divider.o 4 clk-mux.o clk-divider.o clk-fixed-factor.o
5# SoCs specific
6obj-$(CONFIG_ARCH_MXS) += mxs/
7obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index d5ac6a75ea5..8ea11b44452 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -45,7 +45,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
45 45
46 return parent_rate / div; 46 return parent_rate / div;
47} 47}
48EXPORT_SYMBOL_GPL(clk_divider_recalc_rate);
49 48
50/* 49/*
51 * The reverse of DIV_ROUND_UP: The maximum number which 50 * The reverse of DIV_ROUND_UP: The maximum number which
@@ -68,8 +67,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
68 if (divider->flags & CLK_DIVIDER_ONE_BASED) 67 if (divider->flags & CLK_DIVIDER_ONE_BASED)
69 maxdiv--; 68 maxdiv--;
70 69
71 if (!best_parent_rate) { 70 if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
72 parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); 71 parent_rate = *best_parent_rate;
73 bestdiv = DIV_ROUND_UP(parent_rate, rate); 72 bestdiv = DIV_ROUND_UP(parent_rate, rate);
74 bestdiv = bestdiv == 0 ? 1 : bestdiv; 73 bestdiv = bestdiv == 0 ? 1 : bestdiv;
75 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 74 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
@@ -109,24 +108,18 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
109 int div; 108 int div;
110 div = clk_divider_bestdiv(hw, rate, prate); 109 div = clk_divider_bestdiv(hw, rate, prate);
111 110
112 if (prate) 111 return *prate / div;
113 return *prate / div;
114 else {
115 unsigned long r;
116 r = __clk_get_rate(__clk_get_parent(hw->clk));
117 return r / div;
118 }
119} 112}
120EXPORT_SYMBOL_GPL(clk_divider_round_rate);
121 113
122static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate) 114static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
115 unsigned long parent_rate)
123{ 116{
124 struct clk_divider *divider = to_clk_divider(hw); 117 struct clk_divider *divider = to_clk_divider(hw);
125 unsigned int div; 118 unsigned int div;
126 unsigned long flags = 0; 119 unsigned long flags = 0;
127 u32 val; 120 u32 val;
128 121
129 div = __clk_get_rate(__clk_get_parent(hw->clk)) / rate; 122 div = parent_rate / rate;
130 123
131 if (!(divider->flags & CLK_DIVIDER_ONE_BASED)) 124 if (!(divider->flags & CLK_DIVIDER_ONE_BASED))
132 div--; 125 div--;
@@ -147,15 +140,26 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate)
147 140
148 return 0; 141 return 0;
149} 142}
150EXPORT_SYMBOL_GPL(clk_divider_set_rate);
151 143
152struct clk_ops clk_divider_ops = { 144const struct clk_ops clk_divider_ops = {
153 .recalc_rate = clk_divider_recalc_rate, 145 .recalc_rate = clk_divider_recalc_rate,
154 .round_rate = clk_divider_round_rate, 146 .round_rate = clk_divider_round_rate,
155 .set_rate = clk_divider_set_rate, 147 .set_rate = clk_divider_set_rate,
156}; 148};
157EXPORT_SYMBOL_GPL(clk_divider_ops); 149EXPORT_SYMBOL_GPL(clk_divider_ops);
158 150
151/**
152 * clk_register_divider - register a divider clock with the clock framework
153 * @dev: device registering this clock
154 * @name: name of this clock
155 * @parent_name: name of clock's parent
156 * @flags: framework-specific flags
157 * @reg: register address to adjust divider
158 * @shift: number of bits to shift the bitfield
159 * @width: width of the bitfield
160 * @clk_divider_flags: divider-specific flags for this clock
161 * @lock: shared register lock for this clock
162 */
159struct clk *clk_register_divider(struct device *dev, const char *name, 163struct clk *clk_register_divider(struct device *dev, const char *name,
160 const char *parent_name, unsigned long flags, 164 const char *parent_name, unsigned long flags,
161 void __iomem *reg, u8 shift, u8 width, 165 void __iomem *reg, u8 shift, u8 width,
@@ -163,38 +167,34 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
163{ 167{
164 struct clk_divider *div; 168 struct clk_divider *div;
165 struct clk *clk; 169 struct clk *clk;
170 struct clk_init_data init;
166 171
172 /* allocate the divider */
167 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); 173 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
168
169 if (!div) { 174 if (!div) {
170 pr_err("%s: could not allocate divider clk\n", __func__); 175 pr_err("%s: could not allocate divider clk\n", __func__);
171 return NULL; 176 return ERR_PTR(-ENOMEM);
172 } 177 }
173 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
174 /* struct clk_divider assignments */ 185 /* struct clk_divider assignments */
175 div->reg = reg; 186 div->reg = reg;
176 div->shift = shift; 187 div->shift = shift;
177 div->width = width; 188 div->width = width;
178 div->flags = clk_divider_flags; 189 div->flags = clk_divider_flags;
179 div->lock = lock; 190 div->lock = lock;
191 div->hw.init = &init;
180 192
181 if (parent_name) { 193 /* register the clock */
182 div->parent[0] = kstrdup(parent_name, GFP_KERNEL); 194 clk = clk_register(dev, &div->hw);
183 if (!div->parent[0])
184 goto out;
185 }
186
187 clk = clk_register(dev, name,
188 &clk_divider_ops, &div->hw,
189 div->parent,
190 (parent_name ? 1 : 0),
191 flags);
192 if (clk)
193 return clk;
194 195
195out: 196 if (IS_ERR(clk))
196 kfree(div->parent[0]); 197 kfree(div);
197 kfree(div);
198 198
199 return NULL; 199 return clk;
200} 200}
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
new file mode 100644
index 00000000000..c8c003e217a
--- /dev/null
+++ b/drivers/clk/clk-fixed-factor.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
3 *
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.
7 *
8 * Standard functionality for the common clock API.
9 */
10#include <linux/module.h>
11#include <linux/clk-provider.h>
12#include <linux/slab.h>
13#include <linux/err.h>
14
15/*
16 * DOC: basic fixed multiplier and divider clock that cannot gate
17 *
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
23 */
24
25#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
26
27static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
28 unsigned long parent_rate)
29{
30 struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
31
32 return parent_rate * fix->mult / fix->div;
33}
34
35static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
36 unsigned long *prate)
37{
38 struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
39
40 if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
41 unsigned long best_parent;
42
43 best_parent = (rate / fix->mult) * fix->div;
44 *prate = __clk_round_rate(__clk_get_parent(hw->clk),
45 best_parent);
46 }
47
48 return (*prate / fix->div) * fix->mult;
49}
50
51static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
52 unsigned long parent_rate)
53{
54 return 0;
55}
56
57struct clk_ops clk_fixed_factor_ops = {
58 .round_rate = clk_factor_round_rate,
59 .set_rate = clk_factor_set_rate,
60 .recalc_rate = clk_factor_recalc_rate,
61};
62EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
63
64struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
65 const char *parent_name, unsigned long flags,
66 unsigned int mult, unsigned int div)
67{
68 struct clk_fixed_factor *fix;
69 struct clk_init_data init;
70 struct clk *clk;
71
72 fix = kmalloc(sizeof(*fix), GFP_KERNEL);
73 if (!fix) {
74 pr_err("%s: could not allocate fixed factor clk\n", __func__);
75 return ERR_PTR(-ENOMEM);
76 }
77
78 /* struct clk_fixed_factor assignments */
79 fix->mult = mult;
80 fix->div = div;
81 fix->hw.init = &init;
82
83 init.name = name;
84 init.ops = &clk_fixed_factor_ops;
85 init.flags = flags;
86 init.parent_names = &parent_name;
87 init.num_parents = 1;
88
89 clk = clk_register(dev, &fix->hw);
90
91 if (IS_ERR(clk))
92 kfree(fix);
93
94 return clk;
95}
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 90c79fb5d1b..cbd24622978 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -32,51 +32,50 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
32{ 32{
33 return to_clk_fixed_rate(hw)->fixed_rate; 33 return to_clk_fixed_rate(hw)->fixed_rate;
34} 34}
35EXPORT_SYMBOL_GPL(clk_fixed_rate_recalc_rate);
36 35
37struct clk_ops clk_fixed_rate_ops = { 36const struct clk_ops clk_fixed_rate_ops = {
38 .recalc_rate = clk_fixed_rate_recalc_rate, 37 .recalc_rate = clk_fixed_rate_recalc_rate,
39}; 38};
40EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); 39EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
41 40
41/**
42 * clk_register_fixed_rate - register fixed-rate clock with the clock framework
43 * @dev: device that is registering this clock
44 * @name: name of this clock
45 * @parent_name: name of clock's parent
46 * @flags: framework-specific flags
47 * @fixed_rate: non-adjustable clock rate
48 */
42struct clk *clk_register_fixed_rate(struct device *dev, const char *name, 49struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
43 const char *parent_name, unsigned long flags, 50 const char *parent_name, unsigned long flags,
44 unsigned long fixed_rate) 51 unsigned long fixed_rate)
45{ 52{
46 struct clk_fixed_rate *fixed; 53 struct clk_fixed_rate *fixed;
47 char **parent_names = NULL; 54 struct clk *clk;
48 u8 len; 55 struct clk_init_data init;
49 56
57 /* allocate fixed-rate clock */
50 fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); 58 fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
51
52 if (!fixed) { 59 if (!fixed) {
53 pr_err("%s: could not allocate fixed clk\n", __func__); 60 pr_err("%s: could not allocate fixed clk\n", __func__);
54 return ERR_PTR(-ENOMEM); 61 return ERR_PTR(-ENOMEM);
55 } 62 }
56 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
57 /* struct clk_fixed_rate assignments */ 70 /* struct clk_fixed_rate assignments */
58 fixed->fixed_rate = fixed_rate; 71 fixed->fixed_rate = fixed_rate;
72 fixed->hw.init = &init;
59 73
60 if (parent_name) { 74 /* register the clock */
61 parent_names = kmalloc(sizeof(char *), GFP_KERNEL); 75 clk = clk_register(dev, &fixed->hw);
62
63 if (! parent_names)
64 goto out;
65 76
66 len = sizeof(char) * strlen(parent_name); 77 if (IS_ERR(clk))
67 78 kfree(fixed);
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 79
76out: 80 return clk;
77 return clk_register(dev, name,
78 &clk_fixed_rate_ops, &fixed->hw,
79 parent_names,
80 (parent_name ? 1 : 0),
81 flags);
82} 81}
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index b5902e2ef2f..578465e04be 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -28,32 +28,38 @@
28 28
29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) 29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
30 30
31static void clk_gate_set_bit(struct clk_gate *gate) 31/*
32 * It works on following logic:
33 *
34 * For enabling clock, enable = 1
35 * set2dis = 1 -> clear bit -> set = 0
36 * set2dis = 0 -> set bit -> set = 1
37 *
38 * For disabling clock, enable = 0
39 * set2dis = 1 -> set bit -> set = 1
40 * set2dis = 0 -> clear bit -> set = 0
41 *
42 * So, result is always: enable xor set2dis.
43 */
44static void clk_gate_endisable(struct clk_hw *hw, int enable)
32{ 45{
33 u32 reg; 46 struct clk_gate *gate = to_clk_gate(hw);
47 int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
34 unsigned long flags = 0; 48 unsigned long flags = 0;
49 u32 reg;
50
51 set ^= enable;
35 52
36 if (gate->lock) 53 if (gate->lock)
37 spin_lock_irqsave(gate->lock, flags); 54 spin_lock_irqsave(gate->lock, flags);
38 55
39 reg = readl(gate->reg); 56 reg = readl(gate->reg);
40 reg |= BIT(gate->bit_idx);
41 writel(reg, gate->reg);
42
43 if (gate->lock)
44 spin_unlock_irqrestore(gate->lock, flags);
45}
46
47static void clk_gate_clear_bit(struct clk_gate *gate)
48{
49 u32 reg;
50 unsigned long flags = 0;
51 57
52 if (gate->lock) 58 if (set)
53 spin_lock_irqsave(gate->lock, flags); 59 reg |= BIT(gate->bit_idx);
60 else
61 reg &= ~BIT(gate->bit_idx);
54 62
55 reg = readl(gate->reg);
56 reg &= ~BIT(gate->bit_idx);
57 writel(reg, gate->reg); 63 writel(reg, gate->reg);
58 64
59 if (gate->lock) 65 if (gate->lock)
@@ -62,27 +68,15 @@ static void clk_gate_clear_bit(struct clk_gate *gate)
62 68
63static int clk_gate_enable(struct clk_hw *hw) 69static int clk_gate_enable(struct clk_hw *hw)
64{ 70{
65 struct clk_gate *gate = to_clk_gate(hw); 71 clk_gate_endisable(hw, 1);
66
67 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
68 clk_gate_clear_bit(gate);
69 else
70 clk_gate_set_bit(gate);
71 72
72 return 0; 73 return 0;
73} 74}
74EXPORT_SYMBOL_GPL(clk_gate_enable);
75 75
76static void clk_gate_disable(struct clk_hw *hw) 76static void clk_gate_disable(struct clk_hw *hw)
77{ 77{
78 struct clk_gate *gate = to_clk_gate(hw); 78 clk_gate_endisable(hw, 0);
79
80 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
81 clk_gate_set_bit(gate);
82 else
83 clk_gate_clear_bit(gate);
84} 79}
85EXPORT_SYMBOL_GPL(clk_gate_disable);
86 80
87static int clk_gate_is_enabled(struct clk_hw *hw) 81static int clk_gate_is_enabled(struct clk_hw *hw)
88{ 82{
@@ -99,15 +93,25 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
99 93
100 return reg ? 1 : 0; 94 return reg ? 1 : 0;
101} 95}
102EXPORT_SYMBOL_GPL(clk_gate_is_enabled);
103 96
104struct clk_ops clk_gate_ops = { 97const struct clk_ops clk_gate_ops = {
105 .enable = clk_gate_enable, 98 .enable = clk_gate_enable,
106 .disable = clk_gate_disable, 99 .disable = clk_gate_disable,
107 .is_enabled = clk_gate_is_enabled, 100 .is_enabled = clk_gate_is_enabled,
108}; 101};
109EXPORT_SYMBOL_GPL(clk_gate_ops); 102EXPORT_SYMBOL_GPL(clk_gate_ops);
110 103
104/**
105 * clk_register_gate - register a gate clock with the clock framework
106 * @dev: device that is registering this clock
107 * @name: name of this clock
108 * @parent_name: name of this clock's parent
109 * @flags: framework-specific flags for this clock
110 * @reg: register address to control gating of this clock
111 * @bit_idx: which bit in the register controls gating of this clock
112 * @clk_gate_flags: gate-specific flags for this clock
113 * @lock: shared register lock for this clock
114 */
111struct clk *clk_register_gate(struct device *dev, const char *name, 115struct clk *clk_register_gate(struct device *dev, const char *name,
112 const char *parent_name, unsigned long flags, 116 const char *parent_name, unsigned long flags,
113 void __iomem *reg, u8 bit_idx, 117 void __iomem *reg, u8 bit_idx,
@@ -115,36 +119,32 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
115{ 119{
116 struct clk_gate *gate; 120 struct clk_gate *gate;
117 struct clk *clk; 121 struct clk *clk;
122 struct clk_init_data init;
118 123
124 /* allocate the gate */
119 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 125 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
120
121 if (!gate) { 126 if (!gate) {
122 pr_err("%s: could not allocate gated clk\n", __func__); 127 pr_err("%s: could not allocate gated clk\n", __func__);
123 return NULL; 128 return ERR_PTR(-ENOMEM);
124 } 129 }
125 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
126 /* struct clk_gate assignments */ 137 /* struct clk_gate assignments */
127 gate->reg = reg; 138 gate->reg = reg;
128 gate->bit_idx = bit_idx; 139 gate->bit_idx = bit_idx;
129 gate->flags = clk_gate_flags; 140 gate->flags = clk_gate_flags;
130 gate->lock = lock; 141 gate->lock = lock;
142 gate->hw.init = &init;
131 143
132 if (parent_name) { 144 clk = clk_register(dev, &gate->hw);
133 gate->parent[0] = kstrdup(parent_name, GFP_KERNEL); 145
134 if (!gate->parent[0]) 146 if (IS_ERR(clk))
135 goto out; 147 kfree(gate);
136 }
137 148
138 clk = clk_register(dev, name, 149 return clk;
139 &clk_gate_ops, &gate->hw,
140 gate->parent,
141 (parent_name ? 1 : 0),
142 flags);
143 if (clk)
144 return clk;
145out:
146 kfree(gate->parent[0]);
147 kfree(gate);
148
149 return NULL;
150} 150}
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index c71ad1f41a9..fd36a8ea73d 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -55,7 +55,6 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
55 55
56 return val; 56 return val;
57} 57}
58EXPORT_SYMBOL_GPL(clk_mux_get_parent);
59 58
60static int clk_mux_set_parent(struct clk_hw *hw, u8 index) 59static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
61{ 60{
@@ -82,35 +81,47 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
82 81
83 return 0; 82 return 0;
84} 83}
85EXPORT_SYMBOL_GPL(clk_mux_set_parent);
86 84
87struct clk_ops clk_mux_ops = { 85const struct clk_ops clk_mux_ops = {
88 .get_parent = clk_mux_get_parent, 86 .get_parent = clk_mux_get_parent,
89 .set_parent = clk_mux_set_parent, 87 .set_parent = clk_mux_set_parent,
90}; 88};
91EXPORT_SYMBOL_GPL(clk_mux_ops); 89EXPORT_SYMBOL_GPL(clk_mux_ops);
92 90
93struct clk *clk_register_mux(struct device *dev, const char *name, 91struct clk *clk_register_mux(struct device *dev, const char *name,
94 char **parent_names, u8 num_parents, unsigned long flags, 92 const char **parent_names, u8 num_parents, unsigned long flags,
95 void __iomem *reg, u8 shift, u8 width, 93 void __iomem *reg, u8 shift, u8 width,
96 u8 clk_mux_flags, spinlock_t *lock) 94 u8 clk_mux_flags, spinlock_t *lock)
97{ 95{
98 struct clk_mux *mux; 96 struct clk_mux *mux;
97 struct clk *clk;
98 struct clk_init_data init;
99 99
100 mux = kmalloc(sizeof(struct clk_mux), GFP_KERNEL); 100 /* allocate the mux */
101 101 mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
102 if (!mux) { 102 if (!mux) {
103 pr_err("%s: could not allocate mux clk\n", __func__); 103 pr_err("%s: could not allocate mux clk\n", __func__);
104 return ERR_PTR(-ENOMEM); 104 return ERR_PTR(-ENOMEM);
105 } 105 }
106 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
107 /* struct clk_mux assignments */ 113 /* struct clk_mux assignments */
108 mux->reg = reg; 114 mux->reg = reg;
109 mux->shift = shift; 115 mux->shift = shift;
110 mux->width = width; 116 mux->width = width;
111 mux->flags = clk_mux_flags; 117 mux->flags = clk_mux_flags;
112 mux->lock = lock; 118 mux->lock = lock;
119 mux->hw.init = &init;
120
121 clk = clk_register(dev, &mux->hw);
122
123 if (IS_ERR(clk))
124 kfree(mux);
113 125
114 return clk_register(dev, name, &clk_mux_ops, &mux->hw, 126 return clk;
115 parent_names, num_parents, flags);
116} 127}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9cf6f59e3e1..687b00d67c8 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -194,9 +194,8 @@ static int __init clk_debug_init(void)
194late_initcall(clk_debug_init); 194late_initcall(clk_debug_init);
195#else 195#else
196static inline int clk_debug_register(struct clk *clk) { return 0; } 196static inline int clk_debug_register(struct clk *clk) { return 0; }
197#endif /* CONFIG_COMMON_CLK_DEBUG */ 197#endif
198 198
199#ifdef CONFIG_COMMON_CLK_DISABLE_UNUSED
200/* caller must hold prepare_lock */ 199/* caller must hold prepare_lock */
201static void clk_disable_unused_subtree(struct clk *clk) 200static void clk_disable_unused_subtree(struct clk *clk)
202{ 201{
@@ -246,9 +245,6 @@ static int clk_disable_unused(void)
246 return 0; 245 return 0;
247} 246}
248late_initcall(clk_disable_unused); 247late_initcall(clk_disable_unused);
249#else
250static inline int clk_disable_unused(struct clk *clk) { return 0; }
251#endif /* CONFIG_COMMON_CLK_DISABLE_UNUSED */
252 248
253/*** helper functions ***/ 249/*** helper functions ***/
254 250
@@ -287,7 +283,7 @@ unsigned long __clk_get_rate(struct clk *clk)
287 unsigned long ret; 283 unsigned long ret;
288 284
289 if (!clk) { 285 if (!clk) {
290 ret = -EINVAL; 286 ret = 0;
291 goto out; 287 goto out;
292 } 288 }
293 289
@@ -297,7 +293,7 @@ unsigned long __clk_get_rate(struct clk *clk)
297 goto out; 293 goto out;
298 294
299 if (!clk->parent) 295 if (!clk->parent)
300 ret = -ENODEV; 296 ret = 0;
301 297
302out: 298out:
303 return ret; 299 return ret;
@@ -562,7 +558,7 @@ EXPORT_SYMBOL_GPL(clk_enable);
562 * @clk: the clk whose rate is being returned 558 * @clk: the clk whose rate is being returned
563 * 559 *
564 * Simply returns the cached rate of the clk. Does not query the hardware. If 560 * Simply returns the cached rate of the clk. Does not query the hardware. If
565 * clk is NULL then returns -EINVAL. 561 * clk is NULL then returns 0.
566 */ 562 */
567unsigned long clk_get_rate(struct clk *clk) 563unsigned long clk_get_rate(struct clk *clk)
568{ 564{
@@ -584,18 +580,22 @@ EXPORT_SYMBOL_GPL(clk_get_rate);
584 */ 580 */
585unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) 581unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
586{ 582{
587 unsigned long unused; 583 unsigned long parent_rate = 0;
588 584
589 if (!clk) 585 if (!clk)
590 return -EINVAL; 586 return -EINVAL;
591 587
592 if (!clk->ops->round_rate) 588 if (!clk->ops->round_rate) {
593 return clk->rate; 589 if (clk->flags & CLK_SET_RATE_PARENT)
590 return __clk_round_rate(clk->parent, rate);
591 else
592 return clk->rate;
593 }
594 594
595 if (clk->flags & CLK_SET_RATE_PARENT) 595 if (clk->parent)
596 return clk->ops->round_rate(clk->hw, rate, &unused); 596 parent_rate = clk->parent->rate;
597 else 597
598 return clk->ops->round_rate(clk->hw, rate, NULL); 598 return clk->ops->round_rate(clk->hw, rate, &parent_rate);
599} 599}
600 600
601/** 601/**
@@ -765,25 +765,41 @@ static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
765static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate) 765static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
766{ 766{
767 struct clk *top = clk; 767 struct clk *top = clk;
768 unsigned long best_parent_rate = clk->parent->rate; 768 unsigned long best_parent_rate = 0;
769 unsigned long new_rate; 769 unsigned long new_rate;
770 770
771 if (!clk->ops->round_rate && !(clk->flags & CLK_SET_RATE_PARENT)) { 771 /* sanity */
772 clk->new_rate = clk->rate; 772 if (IS_ERR_OR_NULL(clk))
773 return NULL;
774
775 /* save parent rate, if it exists */
776 if (clk->parent)
777 best_parent_rate = clk->parent->rate;
778
779 /* never propagate up to the parent */
780 if (!(clk->flags & CLK_SET_RATE_PARENT)) {
781 if (!clk->ops->round_rate) {
782 clk->new_rate = clk->rate;
783 return NULL;
784 }
785 new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
786 goto out;
787 }
788
789 /* need clk->parent from here on out */
790 if (!clk->parent) {
791 pr_debug("%s: %s has NULL parent\n", __func__, clk->name);
773 return NULL; 792 return NULL;
774 } 793 }
775 794
776 if (!clk->ops->round_rate && (clk->flags & CLK_SET_RATE_PARENT)) { 795 if (!clk->ops->round_rate) {
777 top = clk_calc_new_rates(clk->parent, rate); 796 top = clk_calc_new_rates(clk->parent, rate);
778 new_rate = clk->new_rate = clk->parent->new_rate; 797 new_rate = clk->parent->new_rate;
779 798
780 goto out; 799 goto out;
781 } 800 }
782 801
783 if (clk->flags & CLK_SET_RATE_PARENT) 802 new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
784 new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
785 else
786 new_rate = clk->ops->round_rate(clk->hw, rate, NULL);
787 803
788 if (best_parent_rate != clk->parent->rate) { 804 if (best_parent_rate != clk->parent->rate) {
789 top = clk_calc_new_rates(clk->parent, best_parent_rate); 805 top = clk_calc_new_rates(clk->parent, best_parent_rate);
@@ -839,7 +855,7 @@ static void clk_change_rate(struct clk *clk)
839 old_rate = clk->rate; 855 old_rate = clk->rate;
840 856
841 if (clk->ops->set_rate) 857 if (clk->ops->set_rate)
842 clk->ops->set_rate(clk->hw, clk->new_rate); 858 clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate);
843 859
844 if (clk->ops->recalc_rate) 860 if (clk->ops->recalc_rate)
845 clk->rate = clk->ops->recalc_rate(clk->hw, 861 clk->rate = clk->ops->recalc_rate(clk->hw,
@@ -859,38 +875,19 @@ static void clk_change_rate(struct clk *clk)
859 * @clk: the clk whose rate is being changed 875 * @clk: the clk whose rate is being changed
860 * @rate: the new rate for clk 876 * @rate: the new rate for clk
861 * 877 *
862 * In the simplest case clk_set_rate will only change the rate of clk. 878 * In the simplest case clk_set_rate will only adjust the rate of clk.
863 *
864 * If clk has the CLK_SET_RATE_GATE flag set and it is enabled this call
865 * will fail; only when the clk is disabled will it be able to change
866 * its rate.
867 * 879 *
868 * Setting the CLK_SET_RATE_PARENT flag allows clk_set_rate to 880 * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
869 * recursively propagate up to clk's parent; whether or not this happens 881 * propagate up to clk's parent; whether or not this happens depends on the
870 * depends on the outcome of clk's .round_rate implementation. If 882 * outcome of clk's .round_rate implementation. If *parent_rate is unchanged
871 * *parent_rate is 0 after calling .round_rate then upstream parent 883 * after calling .round_rate then upstream parent propagation is ignored. If
872 * propagation is ignored. If *parent_rate comes back with a new rate 884 * *parent_rate comes back with a new rate for clk's parent then we propagate
873 * for clk's parent then we propagate up to clk's parent and set it's 885 * up to clk's parent and set it's rate. Upward propagation will continue
874 * rate. Upward propagation will continue until either a clk does not 886 * until either a clk does not support the CLK_SET_RATE_PARENT flag or
875 * support the CLK_SET_RATE_PARENT flag or .round_rate stops requesting 887 * .round_rate stops requesting changes to clk's parent_rate.
876 * changes to clk's parent_rate. If there is a failure during upstream
877 * propagation then clk_set_rate will unwind and restore each clk's rate
878 * that had been successfully changed. Afterwards a rate change abort
879 * notification will be propagated downstream, starting from the clk
880 * that failed.
881 * 888 *
882 * At the end of all of the rate setting, clk_set_rate internally calls 889 * Rate changes are accomplished via tree traversal that also recalculates the
883 * __clk_recalc_rates and propagates the rate changes downstream, 890 * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
884 * starting from the highest clk whose rate was changed. This has the
885 * added benefit of propagating post-rate change notifiers.
886 *
887 * Note that while post-rate change and rate change abort notifications
888 * are guaranteed to be sent to a clk only once per call to
889 * clk_set_rate, pre-change notifications will be sent for every clk
890 * whose rate is changed. Stacking pre-change notifications is noisy
891 * for the drivers subscribed to them, but this allows drivers to react
892 * to intermediate clk rate changes up until the point where the final
893 * rate is achieved at the end of upstream propagation.
894 * 891 *
895 * Returns 0 on success, -EERROR otherwise. 892 * Returns 0 on success, -EERROR otherwise.
896 */ 893 */
@@ -906,6 +903,11 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
906 if (rate == clk->rate) 903 if (rate == clk->rate)
907 goto out; 904 goto out;
908 905
906 if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
907 ret = -EBUSY;
908 goto out;
909 }
910
909 /* calculate new rates and get the topmost changed clock */ 911 /* calculate new rates and get the topmost changed clock */
910 top = clk_calc_new_rates(clk, rate); 912 top = clk_calc_new_rates(clk, rate);
911 if (!top) { 913 if (!top) {
@@ -1175,40 +1177,41 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
1175 * 1177 *
1176 * Initializes the lists in struct clk, queries the hardware for the 1178 * Initializes the lists in struct clk, queries the hardware for the
1177 * parent and rate and sets them both. 1179 * parent and rate and sets them both.
1178 *
1179 * Any struct clk passed into __clk_init must have the following members
1180 * populated:
1181 * .name
1182 * .ops
1183 * .hw
1184 * .parent_names
1185 * .num_parents
1186 * .flags
1187 *
1188 * Essentially, everything that would normally be passed into clk_register is
1189 * assumed to be initialized already in __clk_init. The other members may be
1190 * populated, but are optional.
1191 *
1192 * __clk_init is only exposed via clk-private.h and is intended for use with
1193 * very large numbers of clocks that need to be statically initialized. It is
1194 * a layering violation to include clk-private.h from any code which implements
1195 * a clock's .ops; as such any statically initialized clock data MUST be in a
1196 * separate C file from the logic that implements it's operations.
1197 */ 1180 */
1198void __clk_init(struct device *dev, struct clk *clk) 1181int __clk_init(struct device *dev, struct clk *clk)
1199{ 1182{
1200 int i; 1183 int i, ret = 0;
1201 struct clk *orphan; 1184 struct clk *orphan;
1202 struct hlist_node *tmp, *tmp2; 1185 struct hlist_node *tmp, *tmp2;
1203 1186
1204 if (!clk) 1187 if (!clk)
1205 return; 1188 return -EINVAL;
1206 1189
1207 mutex_lock(&prepare_lock); 1190 mutex_lock(&prepare_lock);
1208 1191
1209 /* check to see if a clock with this name is already registered */ 1192 /* check to see if a clock with this name is already registered */
1210 if (__clk_lookup(clk->name)) 1193 if (__clk_lookup(clk->name)) {
1194 pr_debug("%s: clk %s already initialized\n",
1195 __func__, clk->name);
1196 ret = -EEXIST;
1197 goto out;
1198 }
1199
1200 /* check that clk_ops are sane. See Documentation/clk.txt */
1201 if (clk->ops->set_rate &&
1202 !(clk->ops->round_rate && clk->ops->recalc_rate)) {
1203 pr_warning("%s: %s must implement .round_rate & .recalc_rate\n",
1204 __func__, clk->name);
1205 ret = -EINVAL;
1206 goto out;
1207 }
1208
1209 if (clk->ops->set_parent && !clk->ops->get_parent) {
1210 pr_warning("%s: %s must implement .get_parent & .set_parent\n",
1211 __func__, clk->name);
1212 ret = -EINVAL;
1211 goto out; 1213 goto out;
1214 }
1212 1215
1213 /* throw a WARN if any entries in parent_names are NULL */ 1216 /* throw a WARN if any entries in parent_names are NULL */
1214 for (i = 0; i < clk->num_parents; i++) 1217 for (i = 0; i < clk->num_parents; i++)
@@ -1302,48 +1305,130 @@ void __clk_init(struct device *dev, struct clk *clk)
1302out: 1305out:
1303 mutex_unlock(&prepare_lock); 1306 mutex_unlock(&prepare_lock);
1304 1307
1305 return; 1308 return ret;
1306} 1309}
1307 1310
1308/** 1311/**
1312 * __clk_register - register a clock and return a cookie.
1313 *
1314 * Same as clk_register, except that the .clk field inside hw shall point to a
1315 * preallocated (generally statically allocated) struct clk. None of the fields
1316 * of the struct clk need to be initialized.
1317 *
1318 * The data pointed to by .init and .clk field shall NOT be marked as init
1319 * data.
1320 *
1321 * __clk_register is only exposed via clk-private.h and is intended for use with
1322 * very large numbers of clocks that need to be statically initialized. It is
1323 * a layering violation to include clk-private.h from any code which implements
1324 * a clock's .ops; as such any statically initialized clock data MUST be in a
1325 * separate C file from the logic that implements it's operations. Returns 0
1326 * on success, otherwise an error code.
1327 */
1328struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
1329{
1330 int ret;
1331 struct clk *clk;
1332
1333 clk = hw->clk;
1334 clk->name = hw->init->name;
1335 clk->ops = hw->init->ops;
1336 clk->hw = hw;
1337 clk->flags = hw->init->flags;
1338 clk->parent_names = hw->init->parent_names;
1339 clk->num_parents = hw->init->num_parents;
1340
1341 ret = __clk_init(dev, clk);
1342 if (ret)
1343 return ERR_PTR(ret);
1344
1345 return clk;
1346}
1347EXPORT_SYMBOL_GPL(__clk_register);
1348
1349/**
1309 * clk_register - allocate a new clock, register it and return an opaque cookie 1350 * clk_register - allocate a new clock, register it and return an opaque cookie
1310 * @dev: device that is registering this clock 1351 * @dev: device that is registering this clock
1311 * @name: clock name
1312 * @ops: operations this clock supports
1313 * @hw: link to hardware-specific clock data 1352 * @hw: link to hardware-specific clock data
1314 * @parent_names: array of string names for all possible parents
1315 * @num_parents: number of possible parents
1316 * @flags: framework-level hints and quirks
1317 * 1353 *
1318 * clk_register is the primary interface for populating the clock tree with new 1354 * clk_register is the primary interface for populating the clock tree with new
1319 * clock nodes. It returns a pointer to the newly allocated struct clk which 1355 * clock nodes. It returns a pointer to the newly allocated struct clk which
1320 * cannot be dereferenced by driver code but may be used in conjuction with the 1356 * cannot be dereferenced by driver code but may be used in conjuction with the
1321 * rest of the clock API. 1357 * rest of the clock API. In the event of an error clk_register will return an
1358 * error code; drivers must test for an error code after calling clk_register.
1322 */ 1359 */
1323struct clk *clk_register(struct device *dev, const char *name, 1360struct clk *clk_register(struct device *dev, struct clk_hw *hw)
1324 const struct clk_ops *ops, struct clk_hw *hw,
1325 char **parent_names, u8 num_parents, unsigned long flags)
1326{ 1361{
1362 int i, ret;
1327 struct clk *clk; 1363 struct clk *clk;
1328 1364
1329 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 1365 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
1330 if (!clk) 1366 if (!clk) {
1331 return NULL; 1367 pr_err("%s: could not allocate clk\n", __func__);
1368 ret = -ENOMEM;
1369 goto fail_out;
1370 }
1332 1371
1333 clk->name = name; 1372 clk->name = kstrdup(hw->init->name, GFP_KERNEL);
1334 clk->ops = ops; 1373 if (!clk->name) {
1374 pr_err("%s: could not allocate clk->name\n", __func__);
1375 ret = -ENOMEM;
1376 goto fail_name;
1377 }
1378 clk->ops = hw->init->ops;
1335 clk->hw = hw; 1379 clk->hw = hw;
1336 clk->flags = flags; 1380 clk->flags = hw->init->flags;
1337 clk->parent_names = parent_names; 1381 clk->num_parents = hw->init->num_parents;
1338 clk->num_parents = num_parents;
1339 hw->clk = clk; 1382 hw->clk = clk;
1340 1383
1341 __clk_init(dev, clk); 1384 /* allocate local copy in case parent_names is __initdata */
1385 clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents),
1386 GFP_KERNEL);
1342 1387
1343 return clk; 1388 if (!clk->parent_names) {
1389 pr_err("%s: could not allocate clk->parent_names\n", __func__);
1390 ret = -ENOMEM;
1391 goto fail_parent_names;
1392 }
1393
1394
1395 /* copy each string name in case parent_names is __initdata */
1396 for (i = 0; i < clk->num_parents; i++) {
1397 clk->parent_names[i] = kstrdup(hw->init->parent_names[i],
1398 GFP_KERNEL);
1399 if (!clk->parent_names[i]) {
1400 pr_err("%s: could not copy parent_names\n", __func__);
1401 ret = -ENOMEM;
1402 goto fail_parent_names_copy;
1403 }
1404 }
1405
1406 ret = __clk_init(dev, clk);
1407 if (!ret)
1408 return clk;
1409
1410fail_parent_names_copy:
1411 while (--i >= 0)
1412 kfree(clk->parent_names[i]);
1413 kfree(clk->parent_names);
1414fail_parent_names:
1415 kfree(clk->name);
1416fail_name:
1417 kfree(clk);
1418fail_out:
1419 return ERR_PTR(ret);
1344} 1420}
1345EXPORT_SYMBOL_GPL(clk_register); 1421EXPORT_SYMBOL_GPL(clk_register);
1346 1422
1423/**
1424 * clk_unregister - unregister a currently registered clock
1425 * @clk: clock to unregister
1426 *
1427 * Currently unimplemented.
1428 */
1429void clk_unregister(struct clk *clk) {}
1430EXPORT_SYMBOL_GPL(clk_unregister);
1431
1347/*** clk rate change notifiers ***/ 1432/*** clk rate change notifiers ***/
1348 1433
1349/** 1434/**
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
new file mode 100644
index 00000000000..7bedeec0852
--- /dev/null
+++ b/drivers/clk/mxs/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for mxs specific clk
3#
4
5obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o
6
7obj-$(CONFIG_SOC_IMX23) += clk-imx23.o
8obj-$(CONFIG_SOC_IMX28) += clk-imx28.o
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
new file mode 100644
index 00000000000..90e1da93877
--- /dev/null
+++ b/drivers/clk/mxs/clk-div.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/slab.h>
16#include "clk.h"
17
18/**
19 * struct clk_div - mxs integer divider clock
20 * @divider: the parent class
21 * @ops: pointer to clk_ops of parent class
22 * @reg: register address
23 * @busy: busy bit shift
24 *
25 * The mxs divider clock is a subclass of basic clk_divider with an
26 * addtional busy bit.
27 */
28struct clk_div {
29 struct clk_divider divider;
30 const struct clk_ops *ops;
31 void __iomem *reg;
32 u8 busy;
33};
34
35static inline struct clk_div *to_clk_div(struct clk_hw *hw)
36{
37 struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
38
39 return container_of(divider, struct clk_div, divider);
40}
41
42static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
43 unsigned long parent_rate)
44{
45 struct clk_div *div = to_clk_div(hw);
46
47 return div->ops->recalc_rate(&div->divider.hw, parent_rate);
48}
49
50static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
51 unsigned long *prate)
52{
53 struct clk_div *div = to_clk_div(hw);
54
55 return div->ops->round_rate(&div->divider.hw, rate, prate);
56}
57
58static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long parent_rate)
60{
61 struct clk_div *div = to_clk_div(hw);
62 int ret;
63
64 ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate);
65 if (!ret)
66 ret = mxs_clk_wait(div->reg, div->busy);
67
68 return ret;
69}
70
71static struct clk_ops clk_div_ops = {
72 .recalc_rate = clk_div_recalc_rate,
73 .round_rate = clk_div_round_rate,
74 .set_rate = clk_div_set_rate,
75};
76
77struct clk *mxs_clk_div(const char *name, const char *parent_name,
78 void __iomem *reg, u8 shift, u8 width, u8 busy)
79{
80 struct clk_div *div;
81 struct clk *clk;
82 struct clk_init_data init;
83
84 div = kzalloc(sizeof(*div), GFP_KERNEL);
85 if (!div)
86 return ERR_PTR(-ENOMEM);
87
88 init.name = name;
89 init.ops = &clk_div_ops;
90 init.flags = CLK_SET_RATE_PARENT;
91 init.parent_names = (parent_name ? &parent_name: NULL);
92 init.num_parents = (parent_name ? 1 : 0);
93
94 div->reg = reg;
95 div->busy = busy;
96
97 div->divider.reg = reg;
98 div->divider.shift = shift;
99 div->divider.width = width;
100 div->divider.flags = CLK_DIVIDER_ONE_BASED;
101 div->divider.lock = &mxs_lock;
102 div->divider.hw.init = &init;
103 div->ops = &clk_divider_ops;
104
105 clk = clk_register(NULL, &div->divider.hw);
106 if (IS_ERR(clk))
107 kfree(div);
108
109 return clk;
110}
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
new file mode 100644
index 00000000000..e6aa6b567d6
--- /dev/null
+++ b/drivers/clk/mxs/clk-frac.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_frac - mxs fractional divider clock
21 * @hw: clk_hw for the fractional divider clock
22 * @reg: register address
23 * @shift: the divider bit shift
24 * @width: the divider bit width
25 * @busy: busy bit shift
26 *
27 * The clock is an adjustable fractional divider with a busy bit to wait
28 * when the divider is adjusted.
29 */
30struct clk_frac {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 shift;
34 u8 width;
35 u8 busy;
36};
37
38#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
39
40static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
41 unsigned long parent_rate)
42{
43 struct clk_frac *frac = to_clk_frac(hw);
44 u32 div;
45
46 div = readl_relaxed(frac->reg) >> frac->shift;
47 div &= (1 << frac->width) - 1;
48
49 return (parent_rate >> frac->width) * div;
50}
51
52static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
53 unsigned long *prate)
54{
55 struct clk_frac *frac = to_clk_frac(hw);
56 unsigned long parent_rate = *prate;
57 u32 div;
58 u64 tmp;
59
60 if (rate > parent_rate)
61 return -EINVAL;
62
63 tmp = rate;
64 tmp <<= frac->width;
65 do_div(tmp, parent_rate);
66 div = tmp;
67
68 if (!div)
69 return -EINVAL;
70
71 return (parent_rate >> frac->width) * div;
72}
73
74static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
75 unsigned long parent_rate)
76{
77 struct clk_frac *frac = to_clk_frac(hw);
78 unsigned long flags;
79 u32 div, val;
80 u64 tmp;
81
82 if (rate > parent_rate)
83 return -EINVAL;
84
85 tmp = rate;
86 tmp <<= frac->width;
87 do_div(tmp, parent_rate);
88 div = tmp;
89
90 if (!div)
91 return -EINVAL;
92
93 spin_lock_irqsave(&mxs_lock, flags);
94
95 val = readl_relaxed(frac->reg);
96 val &= ~(((1 << frac->width) - 1) << frac->shift);
97 val |= div << frac->shift;
98 writel_relaxed(val, frac->reg);
99
100 spin_unlock_irqrestore(&mxs_lock, flags);
101
102 return mxs_clk_wait(frac->reg, frac->busy);
103}
104
105static struct clk_ops clk_frac_ops = {
106 .recalc_rate = clk_frac_recalc_rate,
107 .round_rate = clk_frac_round_rate,
108 .set_rate = clk_frac_set_rate,
109};
110
111struct clk *mxs_clk_frac(const char *name, const char *parent_name,
112 void __iomem *reg, u8 shift, u8 width, u8 busy)
113{
114 struct clk_frac *frac;
115 struct clk *clk;
116 struct clk_init_data init;
117
118 frac = kzalloc(sizeof(*frac), GFP_KERNEL);
119 if (!frac)
120 return ERR_PTR(-ENOMEM);
121
122 init.name = name;
123 init.ops = &clk_frac_ops;
124 init.flags = CLK_SET_RATE_PARENT;
125 init.parent_names = (parent_name ? &parent_name: NULL);
126 init.num_parents = (parent_name ? 1 : 0);
127
128 frac->reg = reg;
129 frac->shift = shift;
130 frac->width = width;
131 frac->busy = busy;
132 frac->hw.init = &init;
133
134 clk = clk_register(NULL, &frac->hw);
135 if (IS_ERR(clk))
136 kfree(frac);
137
138 return clk;
139}
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
new file mode 100644
index 00000000000..dcae1128571
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -0,0 +1,204 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx23.h>
19#include "clk.h"
20
21#define DIGCTRL MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
22#define CLKCTRL MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
23#define PLLCTRL0 (CLKCTRL + 0x0000)
24#define CPU (CLKCTRL + 0x0020)
25#define HBUS (CLKCTRL + 0x0030)
26#define XBUS (CLKCTRL + 0x0040)
27#define XTAL (CLKCTRL + 0x0050)
28#define PIX (CLKCTRL + 0x0060)
29#define SSP (CLKCTRL + 0x0070)
30#define GPMI (CLKCTRL + 0x0080)
31#define SPDIF (CLKCTRL + 0x0090)
32#define EMI (CLKCTRL + 0x00a0)
33#define SAIF (CLKCTRL + 0x00c0)
34#define TV (CLKCTRL + 0x00d0)
35#define ETM (CLKCTRL + 0x00e0)
36#define FRAC (CLKCTRL + 0x00f0)
37#define CLKSEQ (CLKCTRL + 0x0110)
38
39#define BP_CPU_INTERRUPT_WAIT 12
40#define BP_CLKSEQ_BYPASS_SAIF 0
41#define BP_CLKSEQ_BYPASS_SSP 5
42#define BP_SAIF_DIV_FRAC_EN 16
43#define BP_FRAC_IOFRAC 24
44
45static void __init clk_misc_init(void)
46{
47 u32 val;
48
49 /* Gate off cpu clock in WFI for power saving */
50 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
51
52 /* Clear BYPASS for SAIF */
53 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
54
55 /* SAIF has to use frac div for functional operation */
56 val = readl_relaxed(SAIF);
57 val |= 1 << BP_SAIF_DIV_FRAC_EN;
58 writel_relaxed(val, SAIF);
59
60 /*
61 * Source ssp clock from ref_io than ref_xtal,
62 * as ref_xtal only provides 24 MHz as maximum.
63 */
64 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ);
65
66 /*
67 * 480 MHz seems too high to be ssp clock source directly,
68 * so set frac to get a 288 MHz ref_io.
69 */
70 __mxs_clrl(0x3f << BP_FRAC_IOFRAC, FRAC);
71 __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
72}
73
74static struct clk_lookup uart_lookups[] __initdata = {
75 { .dev_id = "duart", },
76 { .dev_id = "mxs-auart.0", },
77 { .dev_id = "mxs-auart.1", },
78 { .dev_id = "8006c000.serial", },
79 { .dev_id = "8006e000.serial", },
80 { .dev_id = "80070000.serial", },
81};
82
83static struct clk_lookup hbus_lookups[] __initdata = {
84 { .dev_id = "mxs-dma-apbh", },
85 { .dev_id = "80004000.dma-apbh", },
86};
87
88static struct clk_lookup xbus_lookups[] __initdata = {
89 { .dev_id = "duart", .con_id = "apb_pclk"},
90 { .dev_id = "mxs-dma-apbx", },
91 { .dev_id = "80024000.dma-apbx", },
92};
93
94static struct clk_lookup ssp_lookups[] __initdata = {
95 { .dev_id = "mxs-mmc.0", },
96 { .dev_id = "mxs-mmc.1", },
97 { .dev_id = "80010000.ssp", },
98 { .dev_id = "80034000.ssp", },
99};
100
101static struct clk_lookup lcdif_lookups[] __initdata = {
102 { .dev_id = "imx23-fb", },
103 { .dev_id = "80030000.lcdif", },
104};
105
106static struct clk_lookup gpmi_lookups[] __initdata = {
107 { .dev_id = "imx23-gpmi-nand", },
108 { .dev_id = "8000c000.gpmi", },
109};
110
111static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
112static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
113static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
114static const char *sel_io[] __initconst = { "ref_io", "ref_xtal", };
115static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
116static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
117
118enum imx23_clk {
119 ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
120 lcdif_sel, gpmi_sel, ssp_sel, emi_sel, cpu, etm_sel, cpu_pll,
121 cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
122 emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
123 clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
124 lcdif, etm, usb, usb_pwr,
125 clk_max
126};
127
128static struct clk *clks[clk_max];
129
130static enum imx23_clk clks_init_on[] __initdata = {
131 cpu, hbus, xbus, emi, uart,
132};
133
134int __init mx23_clocks_init(void)
135{
136 int i;
137
138 clk_misc_init();
139
140 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
141 clks[pll] = mxs_clk_pll("pll", "ref_xtal", PLLCTRL0, 16, 480000000);
142 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll", FRAC, 0);
143 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll", FRAC, 1);
144 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll", FRAC, 2);
145 clks[ref_io] = mxs_clk_ref("ref_io", "pll", FRAC, 3);
146 clks[saif_sel] = mxs_clk_mux("saif_sel", CLKSEQ, 0, 1, sel_pll, ARRAY_SIZE(sel_pll));
147 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 1, 1, sel_pix, ARRAY_SIZE(sel_pix));
148 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 4, 1, sel_io, ARRAY_SIZE(sel_io));
149 clks[ssp_sel] = mxs_clk_mux("ssp_sel", CLKSEQ, 5, 1, sel_io, ARRAY_SIZE(sel_io));
150 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 6, 1, emi_sels, ARRAY_SIZE(emi_sels));
151 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 7, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
152 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
153 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
154 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
155 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 29);
156 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
157 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", PIX, 0, 12, 29);
158 clks[ssp_div] = mxs_clk_div("ssp_div", "ssp_sel", SSP, 0, 9, 29);
159 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
160 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
161 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
162 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 6, 29);
163 clks[saif_div] = mxs_clk_frac("saif_div", "saif_sel", SAIF, 0, 16, 29);
164 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
165 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
166 clks[adc] = mxs_clk_fixed_factor("adc", "clk32k", 1, 16);
167 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll", 1, 4);
168 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
169 clks[dri] = mxs_clk_gate("dri", "ref_xtal", XTAL, 28);
170 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
171 clks[filt] = mxs_clk_gate("filt", "ref_xtal", XTAL, 30);
172 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
173 clks[ssp] = mxs_clk_gate("ssp", "ssp_div", SSP, 31);
174 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
175 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
176 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
177 clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
178 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
179 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
180 clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2);
181 clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
182
183 for (i = 0; i < ARRAY_SIZE(clks); i++)
184 if (IS_ERR(clks[i])) {
185 pr_err("i.MX23 clk %d: register failed with %ld\n",
186 i, PTR_ERR(clks[i]));
187 return PTR_ERR(clks[i]);
188 }
189
190 clk_register_clkdev(clks[clk32k], NULL, "timrot");
191 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
192 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
193 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
194 clk_register_clkdevs(clks[ssp], ssp_lookups, ARRAY_SIZE(ssp_lookups));
195 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
196 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
197
198 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
199 clk_prepare_enable(clks[clks_init_on[i]]);
200
201 mxs_timer_init(MX23_INT_TIMER0);
202
203 return 0;
204}
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
new file mode 100644
index 00000000000..b2a3257d4f6
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -0,0 +1,337 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx28.h>
19#include "clk.h"
20
21#define CLKCTRL MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
22#define PLL0CTRL0 (CLKCTRL + 0x0000)
23#define PLL1CTRL0 (CLKCTRL + 0x0020)
24#define PLL2CTRL0 (CLKCTRL + 0x0040)
25#define CPU (CLKCTRL + 0x0050)
26#define HBUS (CLKCTRL + 0x0060)
27#define XBUS (CLKCTRL + 0x0070)
28#define XTAL (CLKCTRL + 0x0080)
29#define SSP0 (CLKCTRL + 0x0090)
30#define SSP1 (CLKCTRL + 0x00a0)
31#define SSP2 (CLKCTRL + 0x00b0)
32#define SSP3 (CLKCTRL + 0x00c0)
33#define GPMI (CLKCTRL + 0x00d0)
34#define SPDIF (CLKCTRL + 0x00e0)
35#define EMI (CLKCTRL + 0x00f0)
36#define SAIF0 (CLKCTRL + 0x0100)
37#define SAIF1 (CLKCTRL + 0x0110)
38#define LCDIF (CLKCTRL + 0x0120)
39#define ETM (CLKCTRL + 0x0130)
40#define ENET (CLKCTRL + 0x0140)
41#define FLEXCAN (CLKCTRL + 0x0160)
42#define FRAC0 (CLKCTRL + 0x01b0)
43#define FRAC1 (CLKCTRL + 0x01c0)
44#define CLKSEQ (CLKCTRL + 0x01d0)
45
46#define BP_CPU_INTERRUPT_WAIT 12
47#define BP_SAIF_DIV_FRAC_EN 16
48#define BP_ENET_DIV_TIME 21
49#define BP_ENET_SLEEP 31
50#define BP_CLKSEQ_BYPASS_SAIF0 0
51#define BP_CLKSEQ_BYPASS_SSP0 3
52#define BP_FRAC0_IO1FRAC 16
53#define BP_FRAC0_IO0FRAC 24
54
55#define DIGCTRL MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
56#define BP_SAIF_CLKMUX 10
57
58/*
59 * HW_SAIF_CLKMUX_SEL:
60 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
61 * clock pins selected for SAIF1 input clocks.
62 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
63 * SAIF0 clock inputs selected for SAIF1 input clocks.
64 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
65 * clocks.
66 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
67 * clocks.
68 */
69int mxs_saif_clkmux_select(unsigned int clkmux)
70{
71 if (clkmux > 0x3)
72 return -EINVAL;
73
74 __mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
75 __mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
76
77 return 0;
78}
79
80static void __init clk_misc_init(void)
81{
82 u32 val;
83
84 /* Gate off cpu clock in WFI for power saving */
85 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
86
87 /* 0 is a bad default value for a divider */
88 __mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
89
90 /* Clear BYPASS for SAIF */
91 __mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
92
93 /* SAIF has to use frac div for functional operation */
94 val = readl_relaxed(SAIF0);
95 val |= 1 << BP_SAIF_DIV_FRAC_EN;
96 writel_relaxed(val, SAIF0);
97
98 val = readl_relaxed(SAIF1);
99 val |= 1 << BP_SAIF_DIV_FRAC_EN;
100 writel_relaxed(val, SAIF1);
101
102 /* Extra fec clock setting */
103 val = readl_relaxed(ENET);
104 val &= ~(1 << BP_ENET_SLEEP);
105 writel_relaxed(val, ENET);
106
107 /*
108 * Source ssp clock from ref_io than ref_xtal,
109 * as ref_xtal only provides 24 MHz as maximum.
110 */
111 __mxs_clrl(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ);
112
113 /*
114 * 480 MHz seems too high to be ssp clock source directly,
115 * so set frac0 to get a 288 MHz ref_io0.
116 */
117 val = readl_relaxed(FRAC0);
118 val &= ~(0x3f << BP_FRAC0_IO0FRAC);
119 val |= 30 << BP_FRAC0_IO0FRAC;
120 writel_relaxed(val, FRAC0);
121}
122
123static struct clk_lookup uart_lookups[] __initdata = {
124 { .dev_id = "duart", },
125 { .dev_id = "mxs-auart.0", },
126 { .dev_id = "mxs-auart.1", },
127 { .dev_id = "mxs-auart.2", },
128 { .dev_id = "mxs-auart.3", },
129 { .dev_id = "mxs-auart.4", },
130 { .dev_id = "8006a000.serial", },
131 { .dev_id = "8006c000.serial", },
132 { .dev_id = "8006e000.serial", },
133 { .dev_id = "80070000.serial", },
134 { .dev_id = "80072000.serial", },
135 { .dev_id = "80074000.serial", },
136};
137
138static struct clk_lookup hbus_lookups[] __initdata = {
139 { .dev_id = "mxs-dma-apbh", },
140 { .dev_id = "80004000.dma-apbh", },
141};
142
143static struct clk_lookup xbus_lookups[] __initdata = {
144 { .dev_id = "duart", .con_id = "apb_pclk"},
145 { .dev_id = "mxs-dma-apbx", },
146 { .dev_id = "80024000.dma-apbx", },
147};
148
149static struct clk_lookup ssp0_lookups[] __initdata = {
150 { .dev_id = "mxs-mmc.0", },
151 { .dev_id = "80010000.ssp", },
152};
153
154static struct clk_lookup ssp1_lookups[] __initdata = {
155 { .dev_id = "mxs-mmc.1", },
156 { .dev_id = "80012000.ssp", },
157};
158
159static struct clk_lookup ssp2_lookups[] __initdata = {
160 { .dev_id = "mxs-mmc.2", },
161 { .dev_id = "80014000.ssp", },
162};
163
164static struct clk_lookup ssp3_lookups[] __initdata = {
165 { .dev_id = "mxs-mmc.3", },
166 { .dev_id = "80016000.ssp", },
167};
168
169static struct clk_lookup lcdif_lookups[] __initdata = {
170 { .dev_id = "imx28-fb", },
171 { .dev_id = "80030000.lcdif", },
172};
173
174static struct clk_lookup gpmi_lookups[] __initdata = {
175 { .dev_id = "imx28-gpmi-nand", },
176 { .dev_id = "8000c000.gpmi", },
177};
178
179static struct clk_lookup fec_lookups[] __initdata = {
180 { .dev_id = "imx28-fec.0", },
181 { .dev_id = "imx28-fec.1", },
182 { .dev_id = "800f0000.ethernet", },
183 { .dev_id = "800f4000.ethernet", },
184};
185
186static struct clk_lookup can0_lookups[] __initdata = {
187 { .dev_id = "flexcan.0", },
188 { .dev_id = "80032000.can", },
189};
190
191static struct clk_lookup can1_lookups[] __initdata = {
192 { .dev_id = "flexcan.1", },
193 { .dev_id = "80034000.can", },
194};
195
196static struct clk_lookup saif0_lookups[] __initdata = {
197 { .dev_id = "mxs-saif.0", },
198 { .dev_id = "80042000.saif", },
199};
200
201static struct clk_lookup saif1_lookups[] __initdata = {
202 { .dev_id = "mxs-saif.1", },
203 { .dev_id = "80046000.saif", },
204};
205
206static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
207static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
208static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
209static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
210static const char *sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
211static const char *sel_pll0[] __initconst = { "pll0", "ref_xtal", };
212static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
213static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
214static const char *ptp_sels[] __initconst = { "ref_xtal", "pll0", };
215
216enum imx28_clk {
217 ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
218 ref_pix, ref_hsadc, ref_gpmi, saif0_sel, saif1_sel, gpmi_sel,
219 ssp0_sel, ssp1_sel, ssp2_sel, ssp3_sel, emi_sel, etm_sel,
220 lcdif_sel, cpu, ptp_sel, cpu_pll, cpu_xtal, hbus, xbus,
221 ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
222 emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
223 clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
224 ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
225 fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
226 clk_max
227};
228
229static struct clk *clks[clk_max];
230
231static enum imx28_clk clks_init_on[] __initdata = {
232 cpu, hbus, xbus, emi, uart,
233};
234
235int __init mx28_clocks_init(void)
236{
237 int i;
238
239 clk_misc_init();
240
241 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
242 clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000);
243 clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000);
244 clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
245 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
246 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
247 clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2);
248 clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3);
249 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
250 clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
251 clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
252 clks[saif0_sel] = mxs_clk_mux("saif0_sel", CLKSEQ, 0, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
253 clks[saif1_sel] = mxs_clk_mux("saif1_sel", CLKSEQ, 1, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
254 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 2, 1, sel_gpmi, ARRAY_SIZE(sel_gpmi));
255 clks[ssp0_sel] = mxs_clk_mux("ssp0_sel", CLKSEQ, 3, 1, sel_io0, ARRAY_SIZE(sel_io0));
256 clks[ssp1_sel] = mxs_clk_mux("ssp1_sel", CLKSEQ, 4, 1, sel_io0, ARRAY_SIZE(sel_io0));
257 clks[ssp2_sel] = mxs_clk_mux("ssp2_sel", CLKSEQ, 5, 1, sel_io1, ARRAY_SIZE(sel_io1));
258 clks[ssp3_sel] = mxs_clk_mux("ssp3_sel", CLKSEQ, 6, 1, sel_io1, ARRAY_SIZE(sel_io1));
259 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 7, 1, emi_sels, ARRAY_SIZE(emi_sels));
260 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
261 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 14, 1, sel_pix, ARRAY_SIZE(sel_pix));
262 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 18, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
263 clks[ptp_sel] = mxs_clk_mux("ptp_sel", ENET, 19, 1, ptp_sels, ARRAY_SIZE(ptp_sels));
264 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
265 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
266 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 31);
267 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
268 clks[ssp0_div] = mxs_clk_div("ssp0_div", "ssp0_sel", SSP0, 0, 9, 29);
269 clks[ssp1_div] = mxs_clk_div("ssp1_div", "ssp1_sel", SSP1, 0, 9, 29);
270 clks[ssp2_div] = mxs_clk_div("ssp2_div", "ssp2_sel", SSP2, 0, 9, 29);
271 clks[ssp3_div] = mxs_clk_div("ssp3_div", "ssp3_sel", SSP3, 0, 9, 29);
272 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
273 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
274 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
275 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", LCDIF, 0, 13, 29);
276 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 7, 29);
277 clks[ptp] = mxs_clk_div("ptp", "ptp_sel", ENET, 21, 6, 27);
278 clks[saif0_div] = mxs_clk_frac("saif0_div", "saif0_sel", SAIF0, 0, 16, 29);
279 clks[saif1_div] = mxs_clk_frac("saif1_div", "saif1_sel", SAIF1, 0, 16, 29);
280 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
281 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
282 clks[lradc] = mxs_clk_fixed_factor("lradc", "clk32k", 1, 16);
283 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll0", 1, 4);
284 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
285 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
286 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
287 clks[ssp0] = mxs_clk_gate("ssp0", "ssp0_div", SSP0, 31);
288 clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
289 clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
290 clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
291 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
292 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
293 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
294 clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
295 clks[saif1] = mxs_clk_gate("saif1", "saif1_div", SAIF1, 31);
296 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", LCDIF, 31);
297 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
298 clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
299 clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30);
300 clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28);
301 clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2);
302 clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16);
303 clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
304 clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
305 clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock);
306
307 for (i = 0; i < ARRAY_SIZE(clks); i++)
308 if (IS_ERR(clks[i])) {
309 pr_err("i.MX28 clk %d: register failed with %ld\n",
310 i, PTR_ERR(clks[i]));
311 return PTR_ERR(clks[i]);
312 }
313
314 clk_register_clkdev(clks[clk32k], NULL, "timrot");
315 clk_register_clkdev(clks[enet_out], NULL, "enet_out");
316 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
317 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
318 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
319 clk_register_clkdevs(clks[ssp0], ssp0_lookups, ARRAY_SIZE(ssp0_lookups));
320 clk_register_clkdevs(clks[ssp1], ssp1_lookups, ARRAY_SIZE(ssp1_lookups));
321 clk_register_clkdevs(clks[ssp2], ssp2_lookups, ARRAY_SIZE(ssp2_lookups));
322 clk_register_clkdevs(clks[ssp3], ssp3_lookups, ARRAY_SIZE(ssp3_lookups));
323 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
324 clk_register_clkdevs(clks[saif0], saif0_lookups, ARRAY_SIZE(saif0_lookups));
325 clk_register_clkdevs(clks[saif1], saif1_lookups, ARRAY_SIZE(saif1_lookups));
326 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
327 clk_register_clkdevs(clks[fec], fec_lookups, ARRAY_SIZE(fec_lookups));
328 clk_register_clkdevs(clks[can0], can0_lookups, ARRAY_SIZE(can0_lookups));
329 clk_register_clkdevs(clks[can1], can1_lookups, ARRAY_SIZE(can1_lookups));
330
331 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
332 clk_prepare_enable(clks[clks_init_on[i]]);
333
334 mxs_timer_init(MX28_INT_TIMER0);
335
336 return 0;
337}
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
new file mode 100644
index 00000000000..fadae41833e
--- /dev/null
+++ b/drivers/clk/mxs/clk-pll.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include "clk.h"
19
20/**
21 * struct clk_pll - mxs pll clock
22 * @hw: clk_hw for the pll
23 * @base: base address of the pll
24 * @power: the shift of power bit
25 * @rate: the clock rate of the pll
26 *
27 * The mxs pll is a fixed rate clock with power and gate control,
28 * and the shift of gate bit is always 31.
29 */
30struct clk_pll {
31 struct clk_hw hw;
32 void __iomem *base;
33 u8 power;
34 unsigned long rate;
35};
36
37#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
38
39static int clk_pll_prepare(struct clk_hw *hw)
40{
41 struct clk_pll *pll = to_clk_pll(hw);
42
43 writel_relaxed(1 << pll->power, pll->base + SET);
44
45 udelay(10);
46
47 return 0;
48}
49
50static void clk_pll_unprepare(struct clk_hw *hw)
51{
52 struct clk_pll *pll = to_clk_pll(hw);
53
54 writel_relaxed(1 << pll->power, pll->base + CLR);
55}
56
57static int clk_pll_enable(struct clk_hw *hw)
58{
59 struct clk_pll *pll = to_clk_pll(hw);
60
61 writel_relaxed(1 << 31, pll->base + CLR);
62
63 return 0;
64}
65
66static void clk_pll_disable(struct clk_hw *hw)
67{
68 struct clk_pll *pll = to_clk_pll(hw);
69
70 writel_relaxed(1 << 31, pll->base + SET);
71}
72
73static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct clk_pll *pll = to_clk_pll(hw);
77
78 return pll->rate;
79}
80
81static const struct clk_ops clk_pll_ops = {
82 .prepare = clk_pll_prepare,
83 .unprepare = clk_pll_unprepare,
84 .enable = clk_pll_enable,
85 .disable = clk_pll_disable,
86 .recalc_rate = clk_pll_recalc_rate,
87};
88
89struct clk *mxs_clk_pll(const char *name, const char *parent_name,
90 void __iomem *base, u8 power, unsigned long rate)
91{
92 struct clk_pll *pll;
93 struct clk *clk;
94 struct clk_init_data init;
95
96 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
97 if (!pll)
98 return ERR_PTR(-ENOMEM);
99
100 init.name = name;
101 init.ops = &clk_pll_ops;
102 init.flags = 0;
103 init.parent_names = (parent_name ? &parent_name: NULL);
104 init.num_parents = (parent_name ? 1 : 0);
105
106 pll->base = base;
107 pll->rate = rate;
108 pll->power = power;
109 pll->hw.init = &init;
110
111 clk = clk_register(NULL, &pll->hw);
112 if (IS_ERR(clk))
113 kfree(pll);
114
115 return clk;
116}
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
new file mode 100644
index 00000000000..4adeed6c2f9
--- /dev/null
+++ b/drivers/clk/mxs/clk-ref.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_ref - mxs reference clock
21 * @hw: clk_hw for the reference clock
22 * @reg: register address
23 * @idx: the index of the reference clock within the same register
24 *
25 * The mxs reference clock sources from pll. Every 4 reference clocks share
26 * one register space, and @idx is used to identify them. Each reference
27 * clock has a gate control and a fractional * divider. The rate is calculated
28 * as pll rate * (18 / FRAC), where FRAC = 18 ~ 35.
29 */
30struct clk_ref {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 idx;
34};
35
36#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, hw)
37
38static int clk_ref_enable(struct clk_hw *hw)
39{
40 struct clk_ref *ref = to_clk_ref(hw);
41
42 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
43
44 return 0;
45}
46
47static void clk_ref_disable(struct clk_hw *hw)
48{
49 struct clk_ref *ref = to_clk_ref(hw);
50
51 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
52}
53
54static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
55 unsigned long parent_rate)
56{
57 struct clk_ref *ref = to_clk_ref(hw);
58 u64 tmp = parent_rate;
59 u8 frac = (readl_relaxed(ref->reg) >> (ref->idx * 8)) & 0x3f;
60
61 tmp *= 18;
62 do_div(tmp, frac);
63
64 return tmp;
65}
66
67static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
68 unsigned long *prate)
69{
70 unsigned long parent_rate = *prate;
71 u64 tmp = parent_rate;
72 u8 frac;
73
74 tmp = tmp * 18 + rate / 2;
75 do_div(tmp, rate);
76 frac = tmp;
77
78 if (frac < 18)
79 frac = 18;
80 else if (frac > 35)
81 frac = 35;
82
83 tmp = parent_rate;
84 tmp *= 18;
85 do_div(tmp, frac);
86
87 return tmp;
88}
89
90static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
91 unsigned long parent_rate)
92{
93 struct clk_ref *ref = to_clk_ref(hw);
94 unsigned long flags;
95 u64 tmp = parent_rate;
96 u32 val;
97 u8 frac, shift = ref->idx * 8;
98
99 tmp = tmp * 18 + rate / 2;
100 do_div(tmp, rate);
101 frac = tmp;
102
103 if (frac < 18)
104 frac = 18;
105 else if (frac > 35)
106 frac = 35;
107
108 spin_lock_irqsave(&mxs_lock, flags);
109
110 val = readl_relaxed(ref->reg);
111 val &= ~(0x3f << shift);
112 val |= frac << shift;
113 writel_relaxed(val, ref->reg);
114
115 spin_unlock_irqrestore(&mxs_lock, flags);
116
117 return 0;
118}
119
120static const struct clk_ops clk_ref_ops = {
121 .enable = clk_ref_enable,
122 .disable = clk_ref_disable,
123 .recalc_rate = clk_ref_recalc_rate,
124 .round_rate = clk_ref_round_rate,
125 .set_rate = clk_ref_set_rate,
126};
127
128struct clk *mxs_clk_ref(const char *name, const char *parent_name,
129 void __iomem *reg, u8 idx)
130{
131 struct clk_ref *ref;
132 struct clk *clk;
133 struct clk_init_data init;
134
135 ref = kzalloc(sizeof(*ref), GFP_KERNEL);
136 if (!ref)
137 return ERR_PTR(-ENOMEM);
138
139 init.name = name;
140 init.ops = &clk_ref_ops;
141 init.flags = 0;
142 init.parent_names = (parent_name ? &parent_name: NULL);
143 init.num_parents = (parent_name ? 1 : 0);
144
145 ref->reg = reg;
146 ref->idx = idx;
147 ref->hw.init = &init;
148
149 clk = clk_register(NULL, &ref->hw);
150 if (IS_ERR(clk))
151 kfree(ref);
152
153 return clk;
154}
diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c
new file mode 100644
index 00000000000..b24d56067c8
--- /dev/null
+++ b/drivers/clk/mxs/clk.c
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/jiffies.h>
15#include <linux/spinlock.h>
16
17DEFINE_SPINLOCK(mxs_lock);
18
19int mxs_clk_wait(void __iomem *reg, u8 shift)
20{
21 unsigned long timeout = jiffies + msecs_to_jiffies(10);
22
23 while (readl_relaxed(reg) & (1 << shift))
24 if (time_after(jiffies, timeout))
25 return -ETIMEDOUT;
26
27 return 0;
28}
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
new file mode 100644
index 00000000000..81421e28e69
--- /dev/null
+++ b/drivers/clk/mxs/clk.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#ifndef __MXS_CLK_H
13#define __MXS_CLK_H
14
15#include <linux/clk.h>
16#include <linux/clk-provider.h>
17#include <linux/spinlock.h>
18
19#define SET 0x4
20#define CLR 0x8
21
22extern spinlock_t mxs_lock;
23
24int mxs_clk_wait(void __iomem *reg, u8 shift);
25
26struct clk *mxs_clk_pll(const char *name, const char *parent_name,
27 void __iomem *base, u8 power, unsigned long rate);
28
29struct clk *mxs_clk_ref(const char *name, const char *parent_name,
30 void __iomem *reg, u8 idx);
31
32struct clk *mxs_clk_div(const char *name, const char *parent_name,
33 void __iomem *reg, u8 shift, u8 width, u8 busy);
34
35struct clk *mxs_clk_frac(const char *name, const char *parent_name,
36 void __iomem *reg, u8 shift, u8 width, u8 busy);
37
38static inline struct clk *mxs_clk_fixed(const char *name, int rate)
39{
40 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
41}
42
43static inline struct clk *mxs_clk_gate(const char *name,
44 const char *parent_name, void __iomem *reg, u8 shift)
45{
46 return clk_register_gate(NULL, name, parent_name, CLK_SET_RATE_PARENT,
47 reg, shift, CLK_GATE_SET_TO_DISABLE,
48 &mxs_lock);
49}
50
51static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
52 u8 shift, u8 width, const char **parent_names, int num_parents)
53{
54 return clk_register_mux(NULL, name, parent_names, num_parents,
55 CLK_SET_RATE_PARENT, reg, shift, width,
56 0, &mxs_lock);
57}
58
59static inline struct clk *mxs_clk_fixed_factor(const char *name,
60 const char *parent_name, unsigned int mult, unsigned int div)
61{
62 return clk_register_fixed_factor(NULL, name, parent_name,
63 CLK_SET_RATE_PARENT, mult, div);
64}
65
66#endif /* __MXS_CLK_H */
diff --git a/drivers/clk/spear/Makefile b/drivers/clk/spear/Makefile
new file mode 100644
index 00000000000..335886049c8
--- /dev/null
+++ b/drivers/clk/spear/Makefile
@@ -0,0 +1,8 @@
1#
2# SPEAr Clock specific Makefile
3#
4
5obj-y += clk.o clk-aux-synth.o clk-frac-synth.o clk-gpt-synth.o clk-vco-pll.o
6
7obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx_clock.o
8obj-$(CONFIG_ARCH_SPEAR6XX) += spear6xx_clock.o
diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
new file mode 100644
index 00000000000..af34074e702
--- /dev/null
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -0,0 +1,198 @@
1/*
2 * Copyright (C) 2012 ST Microelectronics
3 * Viresh Kumar <viresh.kumar@st.com>
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * Auxiliary Synthesizer clock implementation
10 */
11
12#define pr_fmt(fmt) "clk-aux-synth: " fmt
13
14#include <linux/clk-provider.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include "clk.h"
19
20/*
21 * DOC: Auxiliary Synthesizer clock
22 *
23 * Aux synth gives rate for different values of eq, x and y
24 *
25 * Fout from synthesizer can be given from two equations:
26 * Fout1 = (Fin * X/Y)/2 EQ1
27 * Fout2 = Fin * X/Y EQ2
28 */
29
30#define to_clk_aux(_hw) container_of(_hw, struct clk_aux, hw)
31
32static struct aux_clk_masks default_aux_masks = {
33 .eq_sel_mask = AUX_EQ_SEL_MASK,
34 .eq_sel_shift = AUX_EQ_SEL_SHIFT,
35 .eq1_mask = AUX_EQ1_SEL,
36 .eq2_mask = AUX_EQ2_SEL,
37 .xscale_sel_mask = AUX_XSCALE_MASK,
38 .xscale_sel_shift = AUX_XSCALE_SHIFT,
39 .yscale_sel_mask = AUX_YSCALE_MASK,
40 .yscale_sel_shift = AUX_YSCALE_SHIFT,
41 .enable_bit = AUX_SYNT_ENB,
42};
43
44static unsigned long aux_calc_rate(struct clk_hw *hw, unsigned long prate,
45 int index)
46{
47 struct clk_aux *aux = to_clk_aux(hw);
48 struct aux_rate_tbl *rtbl = aux->rtbl;
49 u8 eq = rtbl[index].eq ? 1 : 2;
50
51 return (((prate / 10000) * rtbl[index].xscale) /
52 (rtbl[index].yscale * eq)) * 10000;
53}
54
55static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate,
56 unsigned long *prate)
57{
58 struct clk_aux *aux = to_clk_aux(hw);
59 int unused;
60
61 return clk_round_rate_index(hw, drate, *prate, aux_calc_rate,
62 aux->rtbl_cnt, &unused);
63}
64
65static unsigned long clk_aux_recalc_rate(struct clk_hw *hw,
66 unsigned long parent_rate)
67{
68 struct clk_aux *aux = to_clk_aux(hw);
69 unsigned int num = 1, den = 1, val, eqn;
70 unsigned long flags = 0;
71
72 if (aux->lock)
73 spin_lock_irqsave(aux->lock, flags);
74
75 val = readl_relaxed(aux->reg);
76
77 if (aux->lock)
78 spin_unlock_irqrestore(aux->lock, flags);
79
80 eqn = (val >> aux->masks->eq_sel_shift) & aux->masks->eq_sel_mask;
81 if (eqn == aux->masks->eq1_mask)
82 den = 2;
83
84 /* calculate numerator */
85 num = (val >> aux->masks->xscale_sel_shift) &
86 aux->masks->xscale_sel_mask;
87
88 /* calculate denominator */
89 den *= (val >> aux->masks->yscale_sel_shift) &
90 aux->masks->yscale_sel_mask;
91
92 if (!den)
93 return 0;
94
95 return (((parent_rate / 10000) * num) / den) * 10000;
96}
97
98/* Configures new clock rate of aux */
99static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate,
100 unsigned long prate)
101{
102 struct clk_aux *aux = to_clk_aux(hw);
103 struct aux_rate_tbl *rtbl = aux->rtbl;
104 unsigned long val, flags = 0;
105 int i;
106
107 clk_round_rate_index(hw, drate, prate, aux_calc_rate, aux->rtbl_cnt,
108 &i);
109
110 if (aux->lock)
111 spin_lock_irqsave(aux->lock, flags);
112
113 val = readl_relaxed(aux->reg) &
114 ~(aux->masks->eq_sel_mask << aux->masks->eq_sel_shift);
115 val |= (rtbl[i].eq & aux->masks->eq_sel_mask) <<
116 aux->masks->eq_sel_shift;
117 val &= ~(aux->masks->xscale_sel_mask << aux->masks->xscale_sel_shift);
118 val |= (rtbl[i].xscale & aux->masks->xscale_sel_mask) <<
119 aux->masks->xscale_sel_shift;
120 val &= ~(aux->masks->yscale_sel_mask << aux->masks->yscale_sel_shift);
121 val |= (rtbl[i].yscale & aux->masks->yscale_sel_mask) <<
122 aux->masks->yscale_sel_shift;
123 writel_relaxed(val, aux->reg);
124
125 if (aux->lock)
126 spin_unlock_irqrestore(aux->lock, flags);
127
128 return 0;
129}
130
131static struct clk_ops clk_aux_ops = {
132 .recalc_rate = clk_aux_recalc_rate,
133 .round_rate = clk_aux_round_rate,
134 .set_rate = clk_aux_set_rate,
135};
136
137struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
138 const char *parent_name, unsigned long flags, void __iomem *reg,
139 struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
140 u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk)
141{
142 struct clk_aux *aux;
143 struct clk_init_data init;
144 struct clk *clk;
145
146 if (!aux_name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
147 pr_err("Invalid arguments passed");
148 return ERR_PTR(-EINVAL);
149 }
150
151 aux = kzalloc(sizeof(*aux), GFP_KERNEL);
152 if (!aux) {
153 pr_err("could not allocate aux clk\n");
154 return ERR_PTR(-ENOMEM);
155 }
156
157 /* struct clk_aux assignments */
158 if (!masks)
159 aux->masks = &default_aux_masks;
160 else
161 aux->masks = masks;
162
163 aux->reg = reg;
164 aux->rtbl = rtbl;
165 aux->rtbl_cnt = rtbl_cnt;
166 aux->lock = lock;
167 aux->hw.init = &init;
168
169 init.name = aux_name;
170 init.ops = &clk_aux_ops;
171 init.flags = flags;
172 init.parent_names = &parent_name;
173 init.num_parents = 1;
174
175 clk = clk_register(NULL, &aux->hw);
176 if (IS_ERR_OR_NULL(clk))
177 goto free_aux;
178
179 if (gate_name) {
180 struct clk *tgate_clk;
181
182 tgate_clk = clk_register_gate(NULL, gate_name, aux_name, 0, reg,
183 aux->masks->enable_bit, 0, lock);
184 if (IS_ERR_OR_NULL(tgate_clk))
185 goto free_aux;
186
187 if (gate_clk)
188 *gate_clk = tgate_clk;
189 }
190
191 return clk;
192
193free_aux:
194 kfree(aux);
195 pr_err("clk register failed\n");
196
197 return NULL;
198}
diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
new file mode 100644
index 00000000000..4dbdb3fe18e
--- /dev/null
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright (C) 2012 ST Microelectronics
3 * Viresh Kumar <viresh.kumar@st.com>
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * Fractional Synthesizer clock implementation
10 */
11
12#define pr_fmt(fmt) "clk-frac-synth: " fmt
13
14#include <linux/clk-provider.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include "clk.h"
19
20#define DIV_FACTOR_MASK 0x1FFFF
21
22/*
23 * DOC: Fractional Synthesizer clock
24 *
25 * Fout from synthesizer can be given from below equation:
26 *
27 * Fout= Fin/2*div (division factor)
28 * div is 17 bits:-
29 * 0-13 (fractional part)
30 * 14-16 (integer part)
31 * div is (16-14 bits).(13-0 bits) (in binary)
32 *
33 * Fout = Fin/(2 * div)
34 * Fout = ((Fin / 10000)/(2 * div)) * 10000
35 * Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
36 * Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000
37 *
38 * div << 14 simply 17 bit value written at register.
39 * Max error due to scaling down by 10000 is 10 KHz
40 */
41
42#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
43
44static unsigned long frac_calc_rate(struct clk_hw *hw, unsigned long prate,
45 int index)
46{
47 struct clk_frac *frac = to_clk_frac(hw);
48 struct frac_rate_tbl *rtbl = frac->rtbl;
49
50 prate /= 10000;
51 prate <<= 14;
52 prate /= (2 * rtbl[index].div);
53 prate *= 10000;
54
55 return prate;
56}
57
58static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate,
59 unsigned long *prate)
60{
61 struct clk_frac *frac = to_clk_frac(hw);
62 int unused;
63
64 return clk_round_rate_index(hw, drate, *prate, frac_calc_rate,
65 frac->rtbl_cnt, &unused);
66}
67
68static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
69 unsigned long parent_rate)
70{
71 struct clk_frac *frac = to_clk_frac(hw);
72 unsigned long flags = 0;
73 unsigned int div = 1, val;
74
75 if (frac->lock)
76 spin_lock_irqsave(frac->lock, flags);
77
78 val = readl_relaxed(frac->reg);
79
80 if (frac->lock)
81 spin_unlock_irqrestore(frac->lock, flags);
82
83 div = val & DIV_FACTOR_MASK;
84
85 if (!div)
86 return 0;
87
88 parent_rate = parent_rate / 10000;
89
90 parent_rate = (parent_rate << 14) / (2 * div);
91 return parent_rate * 10000;
92}
93
94/* Configures new clock rate of frac */
95static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate,
96 unsigned long prate)
97{
98 struct clk_frac *frac = to_clk_frac(hw);
99 struct frac_rate_tbl *rtbl = frac->rtbl;
100 unsigned long flags = 0, val;
101 int i;
102
103 clk_round_rate_index(hw, drate, prate, frac_calc_rate, frac->rtbl_cnt,
104 &i);
105
106 if (frac->lock)
107 spin_lock_irqsave(frac->lock, flags);
108
109 val = readl_relaxed(frac->reg) & ~DIV_FACTOR_MASK;
110 val |= rtbl[i].div & DIV_FACTOR_MASK;
111 writel_relaxed(val, frac->reg);
112
113 if (frac->lock)
114 spin_unlock_irqrestore(frac->lock, flags);
115
116 return 0;
117}
118
119struct clk_ops clk_frac_ops = {
120 .recalc_rate = clk_frac_recalc_rate,
121 .round_rate = clk_frac_round_rate,
122 .set_rate = clk_frac_set_rate,
123};
124
125struct clk *clk_register_frac(const char *name, const char *parent_name,
126 unsigned long flags, void __iomem *reg,
127 struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock)
128{
129 struct clk_init_data init;
130 struct clk_frac *frac;
131 struct clk *clk;
132
133 if (!name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
134 pr_err("Invalid arguments passed");
135 return ERR_PTR(-EINVAL);
136 }
137
138 frac = kzalloc(sizeof(*frac), GFP_KERNEL);
139 if (!frac) {
140 pr_err("could not allocate frac clk\n");
141 return ERR_PTR(-ENOMEM);
142 }
143
144 /* struct clk_frac assignments */
145 frac->reg = reg;
146 frac->rtbl = rtbl;
147 frac->rtbl_cnt = rtbl_cnt;
148 frac->lock = lock;
149 frac->hw.init = &init;
150
151 init.name = name;
152 init.ops = &clk_frac_ops;
153 init.flags = flags;
154 init.parent_names = &parent_name;
155 init.num_parents = 1;
156
157 clk = clk_register(NULL, &frac->hw);
158 if (!IS_ERR_OR_NULL(clk))
159 return clk;
160
161 pr_err("clk register failed\n");
162 kfree(frac);
163
164 return NULL;
165}
diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
new file mode 100644
index 00000000000..b471c9762a9
--- /dev/null
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright (C) 2012 ST Microelectronics
3 * Viresh Kumar <viresh.kumar@st.com>
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * General Purpose Timer Synthesizer clock implementation
10 */
11
12#define pr_fmt(fmt) "clk-gpt-synth: " fmt
13
14#include <linux/clk-provider.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include "clk.h"
19
20#define GPT_MSCALE_MASK 0xFFF
21#define GPT_NSCALE_SHIFT 12
22#define GPT_NSCALE_MASK 0xF
23
24/*
25 * DOC: General Purpose Timer Synthesizer clock
26 *
27 * Calculates gpt synth clk rate for different values of mscale and nscale
28 *
29 * Fout= Fin/((2 ^ (N+1)) * (M+1))
30 */
31
32#define to_clk_gpt(_hw) container_of(_hw, struct clk_gpt, hw)
33
34static unsigned long gpt_calc_rate(struct clk_hw *hw, unsigned long prate,
35 int index)
36{
37 struct clk_gpt *gpt = to_clk_gpt(hw);
38 struct gpt_rate_tbl *rtbl = gpt->rtbl;
39
40 prate /= ((1 << (rtbl[index].nscale + 1)) * (rtbl[index].mscale + 1));
41
42 return prate;
43}
44
45static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
46 unsigned long *prate)
47{
48 struct clk_gpt *gpt = to_clk_gpt(hw);
49 int unused;
50
51 return clk_round_rate_index(hw, drate, *prate, gpt_calc_rate,
52 gpt->rtbl_cnt, &unused);
53}
54
55static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
56 unsigned long parent_rate)
57{
58 struct clk_gpt *gpt = to_clk_gpt(hw);
59 unsigned long flags = 0;
60 unsigned int div = 1, val;
61
62 if (gpt->lock)
63 spin_lock_irqsave(gpt->lock, flags);
64
65 val = readl_relaxed(gpt->reg);
66
67 if (gpt->lock)
68 spin_unlock_irqrestore(gpt->lock, flags);
69
70 div += val & GPT_MSCALE_MASK;
71 div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
72
73 if (!div)
74 return 0;
75
76 return parent_rate / div;
77}
78
79/* Configures new clock rate of gpt */
80static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate,
81 unsigned long prate)
82{
83 struct clk_gpt *gpt = to_clk_gpt(hw);
84 struct gpt_rate_tbl *rtbl = gpt->rtbl;
85 unsigned long flags = 0, val;
86 int i;
87
88 clk_round_rate_index(hw, drate, prate, gpt_calc_rate, gpt->rtbl_cnt,
89 &i);
90
91 if (gpt->lock)
92 spin_lock_irqsave(gpt->lock, flags);
93
94 val = readl(gpt->reg) & ~GPT_MSCALE_MASK;
95 val &= ~(GPT_NSCALE_MASK << GPT_NSCALE_SHIFT);
96
97 val |= rtbl[i].mscale & GPT_MSCALE_MASK;
98 val |= (rtbl[i].nscale & GPT_NSCALE_MASK) << GPT_NSCALE_SHIFT;
99
100 writel_relaxed(val, gpt->reg);
101
102 if (gpt->lock)
103 spin_unlock_irqrestore(gpt->lock, flags);
104
105 return 0;
106}
107
108static struct clk_ops clk_gpt_ops = {
109 .recalc_rate = clk_gpt_recalc_rate,
110 .round_rate = clk_gpt_round_rate,
111 .set_rate = clk_gpt_set_rate,
112};
113
114struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
115 long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
116 rtbl_cnt, spinlock_t *lock)
117{
118 struct clk_init_data init;
119 struct clk_gpt *gpt;
120 struct clk *clk;
121
122 if (!name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
123 pr_err("Invalid arguments passed");
124 return ERR_PTR(-EINVAL);
125 }
126
127 gpt = kzalloc(sizeof(*gpt), GFP_KERNEL);
128 if (!gpt) {
129 pr_err("could not allocate gpt clk\n");
130 return ERR_PTR(-ENOMEM);
131 }
132
133 /* struct clk_gpt assignments */
134 gpt->reg = reg;
135 gpt->rtbl = rtbl;
136 gpt->rtbl_cnt = rtbl_cnt;
137 gpt->lock = lock;
138 gpt->hw.init = &init;
139
140 init.name = name;
141 init.ops = &clk_gpt_ops;
142 init.flags = flags;
143 init.parent_names = &parent_name;
144 init.num_parents = 1;
145
146 clk = clk_register(NULL, &gpt->hw);
147 if (!IS_ERR_OR_NULL(clk))
148 return clk;
149
150 pr_err("clk register failed\n");
151 kfree(gpt);
152
153 return NULL;
154}
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
new file mode 100644
index 00000000000..dcd4bdf4b0d
--- /dev/null
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -0,0 +1,363 @@
1/*
2 * Copyright (C) 2012 ST Microelectronics
3 * Viresh Kumar <viresh.kumar@st.com>
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * VCO-PLL clock implementation
10 */
11
12#define pr_fmt(fmt) "clk-vco-pll: " fmt
13
14#include <linux/clk-provider.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include "clk.h"
19
20/*
21 * DOC: VCO-PLL clock
22 *
23 * VCO and PLL rate are derived from following equations:
24 *
25 * In normal mode
26 * vco = (2 * M[15:8] * Fin)/N
27 *
28 * In Dithered mode
29 * vco = (2 * M[15:0] * Fin)/(256 * N)
30 *
31 * pll_rate = pll/2^p
32 *
33 * vco and pll are very closely bound to each other, "vco needs to program:
34 * mode, m & n" and "pll needs to program p", both share common enable/disable
35 * logic.
36 *
37 * clk_register_vco_pll() registers instances of both vco & pll.
38 * CLK_SET_RATE_PARENT flag is forced for pll, as it will always pass its
39 * set_rate to vco. A single rate table exists for both the clocks, which
40 * configures m, n and p.
41 */
42
43/* PLL_CTR register masks */
44#define PLL_MODE_NORMAL 0
45#define PLL_MODE_FRACTION 1
46#define PLL_MODE_DITH_DSM 2
47#define PLL_MODE_DITH_SSM 3
48#define PLL_MODE_MASK 3
49#define PLL_MODE_SHIFT 3
50#define PLL_ENABLE 2
51
52#define PLL_LOCK_SHIFT 0
53#define PLL_LOCK_MASK 1
54
55/* PLL FRQ register masks */
56#define PLL_NORM_FDBK_M_MASK 0xFF
57#define PLL_NORM_FDBK_M_SHIFT 24
58#define PLL_DITH_FDBK_M_MASK 0xFFFF
59#define PLL_DITH_FDBK_M_SHIFT 16
60#define PLL_DIV_P_MASK 0x7
61#define PLL_DIV_P_SHIFT 8
62#define PLL_DIV_N_MASK 0xFF
63#define PLL_DIV_N_SHIFT 0
64
65#define to_clk_vco(_hw) container_of(_hw, struct clk_vco, hw)
66#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
67
68/* Calculates pll clk rate for specific value of mode, m, n and p */
69static unsigned long pll_calc_rate(struct pll_rate_tbl *rtbl,
70 unsigned long prate, int index, unsigned long *pll_rate)
71{
72 unsigned long rate = prate;
73 unsigned int mode;
74
75 mode = rtbl[index].mode ? 256 : 1;
76 rate = (((2 * rate / 10000) * rtbl[index].m) / (mode * rtbl[index].n));
77
78 if (pll_rate)
79 *pll_rate = (rate / (1 << rtbl[index].p)) * 10000;
80
81 return rate * 10000;
82}
83
84static long clk_pll_round_rate_index(struct clk_hw *hw, unsigned long drate,
85 unsigned long *prate, int *index)
86{
87 struct clk_pll *pll = to_clk_pll(hw);
88 unsigned long prev_rate, vco_prev_rate, rate = 0;
89 unsigned long vco_parent_rate =
90 __clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk)));
91
92 if (!prate) {
93 pr_err("%s: prate is must for pll clk\n", __func__);
94 return -EINVAL;
95 }
96
97 for (*index = 0; *index < pll->vco->rtbl_cnt; (*index)++) {
98 prev_rate = rate;
99 vco_prev_rate = *prate;
100 *prate = pll_calc_rate(pll->vco->rtbl, vco_parent_rate, *index,
101 &rate);
102 if (drate < rate) {
103 /* previous clock was best */
104 if (*index) {
105 rate = prev_rate;
106 *prate = vco_prev_rate;
107 (*index)--;
108 }
109 break;
110 }
111 }
112
113 return rate;
114}
115
116static long clk_pll_round_rate(struct clk_hw *hw, unsigned long drate,
117 unsigned long *prate)
118{
119 int unused;
120
121 return clk_pll_round_rate_index(hw, drate, prate, &unused);
122}
123
124static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long
125 parent_rate)
126{
127 struct clk_pll *pll = to_clk_pll(hw);
128 unsigned long flags = 0;
129 unsigned int p;
130
131 if (pll->vco->lock)
132 spin_lock_irqsave(pll->vco->lock, flags);
133
134 p = readl_relaxed(pll->vco->cfg_reg);
135
136 if (pll->vco->lock)
137 spin_unlock_irqrestore(pll->vco->lock, flags);
138
139 p = (p >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
140
141 return parent_rate / (1 << p);
142}
143
144static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate,
145 unsigned long prate)
146{
147 struct clk_pll *pll = to_clk_pll(hw);
148 struct pll_rate_tbl *rtbl = pll->vco->rtbl;
149 unsigned long flags = 0, val;
150 int i;
151
152 clk_pll_round_rate_index(hw, drate, NULL, &i);
153
154 if (pll->vco->lock)
155 spin_lock_irqsave(pll->vco->lock, flags);
156
157 val = readl_relaxed(pll->vco->cfg_reg);
158 val &= ~(PLL_DIV_P_MASK << PLL_DIV_P_SHIFT);
159 val |= (rtbl[i].p & PLL_DIV_P_MASK) << PLL_DIV_P_SHIFT;
160 writel_relaxed(val, pll->vco->cfg_reg);
161
162 if (pll->vco->lock)
163 spin_unlock_irqrestore(pll->vco->lock, flags);
164
165 return 0;
166}
167
168static struct clk_ops clk_pll_ops = {
169 .recalc_rate = clk_pll_recalc_rate,
170 .round_rate = clk_pll_round_rate,
171 .set_rate = clk_pll_set_rate,
172};
173
174static inline unsigned long vco_calc_rate(struct clk_hw *hw,
175 unsigned long prate, int index)
176{
177 struct clk_vco *vco = to_clk_vco(hw);
178
179 return pll_calc_rate(vco->rtbl, prate, index, NULL);
180}
181
182static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate,
183 unsigned long *prate)
184{
185 struct clk_vco *vco = to_clk_vco(hw);
186 int unused;
187
188 return clk_round_rate_index(hw, drate, *prate, vco_calc_rate,
189 vco->rtbl_cnt, &unused);
190}
191
192static unsigned long clk_vco_recalc_rate(struct clk_hw *hw,
193 unsigned long parent_rate)
194{
195 struct clk_vco *vco = to_clk_vco(hw);
196 unsigned long flags = 0;
197 unsigned int num = 2, den = 0, val, mode = 0;
198
199 if (vco->lock)
200 spin_lock_irqsave(vco->lock, flags);
201
202 mode = (readl_relaxed(vco->mode_reg) >> PLL_MODE_SHIFT) & PLL_MODE_MASK;
203
204 val = readl_relaxed(vco->cfg_reg);
205
206 if (vco->lock)
207 spin_unlock_irqrestore(vco->lock, flags);
208
209 den = (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
210
211 /* calculate numerator & denominator */
212 if (!mode) {
213 /* Normal mode */
214 num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
215 } else {
216 /* Dithered mode */
217 num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
218 den *= 256;
219 }
220
221 if (!den) {
222 WARN(1, "%s: denominator can't be zero\n", __func__);
223 return 0;
224 }
225
226 return (((parent_rate / 10000) * num) / den) * 10000;
227}
228
229/* Configures new clock rate of vco */
230static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate,
231 unsigned long prate)
232{
233 struct clk_vco *vco = to_clk_vco(hw);
234 struct pll_rate_tbl *rtbl = vco->rtbl;
235 unsigned long flags = 0, val;
236 int i;
237
238 clk_round_rate_index(hw, drate, prate, vco_calc_rate, vco->rtbl_cnt,
239 &i);
240
241 if (vco->lock)
242 spin_lock_irqsave(vco->lock, flags);
243
244 val = readl_relaxed(vco->mode_reg);
245 val &= ~(PLL_MODE_MASK << PLL_MODE_SHIFT);
246 val |= (rtbl[i].mode & PLL_MODE_MASK) << PLL_MODE_SHIFT;
247 writel_relaxed(val, vco->mode_reg);
248
249 val = readl_relaxed(vco->cfg_reg);
250 val &= ~(PLL_DIV_N_MASK << PLL_DIV_N_SHIFT);
251 val |= (rtbl[i].n & PLL_DIV_N_MASK) << PLL_DIV_N_SHIFT;
252
253 val &= ~(PLL_DITH_FDBK_M_MASK << PLL_DITH_FDBK_M_SHIFT);
254 if (rtbl[i].mode)
255 val |= (rtbl[i].m & PLL_DITH_FDBK_M_MASK) <<
256 PLL_DITH_FDBK_M_SHIFT;
257 else
258 val |= (rtbl[i].m & PLL_NORM_FDBK_M_MASK) <<
259 PLL_NORM_FDBK_M_SHIFT;
260
261 writel_relaxed(val, vco->cfg_reg);
262
263 if (vco->lock)
264 spin_unlock_irqrestore(vco->lock, flags);
265
266 return 0;
267}
268
269static struct clk_ops clk_vco_ops = {
270 .recalc_rate = clk_vco_recalc_rate,
271 .round_rate = clk_vco_round_rate,
272 .set_rate = clk_vco_set_rate,
273};
274
275struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
276 const char *vco_gate_name, const char *parent_name,
277 unsigned long flags, void __iomem *mode_reg, void __iomem
278 *cfg_reg, struct pll_rate_tbl *rtbl, u8 rtbl_cnt,
279 spinlock_t *lock, struct clk **pll_clk,
280 struct clk **vco_gate_clk)
281{
282 struct clk_vco *vco;
283 struct clk_pll *pll;
284 struct clk *vco_clk, *tpll_clk, *tvco_gate_clk;
285 struct clk_init_data vco_init, pll_init;
286 const char **vco_parent_name;
287
288 if (!vco_name || !pll_name || !parent_name || !mode_reg || !cfg_reg ||
289 !rtbl || !rtbl_cnt) {
290 pr_err("Invalid arguments passed");
291 return ERR_PTR(-EINVAL);
292 }
293
294 vco = kzalloc(sizeof(*vco), GFP_KERNEL);
295 if (!vco) {
296 pr_err("could not allocate vco clk\n");
297 return ERR_PTR(-ENOMEM);
298 }
299
300 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
301 if (!pll) {
302 pr_err("could not allocate pll clk\n");
303 goto free_vco;
304 }
305
306 /* struct clk_vco assignments */
307 vco->mode_reg = mode_reg;
308 vco->cfg_reg = cfg_reg;
309 vco->rtbl = rtbl;
310 vco->rtbl_cnt = rtbl_cnt;
311 vco->lock = lock;
312 vco->hw.init = &vco_init;
313
314 pll->vco = vco;
315 pll->hw.init = &pll_init;
316
317 if (vco_gate_name) {
318 tvco_gate_clk = clk_register_gate(NULL, vco_gate_name,
319 parent_name, 0, mode_reg, PLL_ENABLE, 0, lock);
320 if (IS_ERR_OR_NULL(tvco_gate_clk))
321 goto free_pll;
322
323 if (vco_gate_clk)
324 *vco_gate_clk = tvco_gate_clk;
325 vco_parent_name = &vco_gate_name;
326 } else {
327 vco_parent_name = &parent_name;
328 }
329
330 vco_init.name = vco_name;
331 vco_init.ops = &clk_vco_ops;
332 vco_init.flags = flags;
333 vco_init.parent_names = vco_parent_name;
334 vco_init.num_parents = 1;
335
336 pll_init.name = pll_name;
337 pll_init.ops = &clk_pll_ops;
338 pll_init.flags = CLK_SET_RATE_PARENT;
339 pll_init.parent_names = &vco_name;
340 pll_init.num_parents = 1;
341
342 vco_clk = clk_register(NULL, &vco->hw);
343 if (IS_ERR_OR_NULL(vco_clk))
344 goto free_pll;
345
346 tpll_clk = clk_register(NULL, &pll->hw);
347 if (IS_ERR_OR_NULL(tpll_clk))
348 goto free_pll;
349
350 if (pll_clk)
351 *pll_clk = tpll_clk;
352
353 return vco_clk;
354
355free_pll:
356 kfree(pll);
357free_vco:
358 kfree(vco);
359
360 pr_err("Failed to register vco pll clock\n");
361
362 return ERR_PTR(-ENOMEM);
363}
diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c
new file mode 100644
index 00000000000..376d4e5ff32
--- /dev/null
+++ b/drivers/clk/spear/clk.c
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2012 ST Microelectronics
3 * Viresh Kumar <viresh.kumar@st.com>
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * SPEAr clk - Common routines
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/types.h>
14#include "clk.h"
15
16long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
17 unsigned long parent_rate, clk_calc_rate calc_rate, u8 rtbl_cnt,
18 int *index)
19{
20 unsigned long prev_rate, rate = 0;
21
22 for (*index = 0; *index < rtbl_cnt; (*index)++) {
23 prev_rate = rate;
24 rate = calc_rate(hw, parent_rate, *index);
25 if (drate < rate) {
26 /* previous clock was best */
27 if (*index) {
28 rate = prev_rate;
29 (*index)--;
30 }
31 break;
32 }
33 }
34
35 return rate;
36}
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
new file mode 100644
index 00000000000..3321c46a071
--- /dev/null
+++ b/drivers/clk/spear/clk.h
@@ -0,0 +1,134 @@
1/*
2 * Clock framework definitions for SPEAr platform
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Viresh Kumar <viresh.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#ifndef __SPEAR_CLK_H
13#define __SPEAR_CLK_H
14
15#include <linux/clk-provider.h>
16#include <linux/spinlock_types.h>
17#include <linux/types.h>
18
19/* Auxiliary Synth clk */
20/* Default masks */
21#define AUX_EQ_SEL_SHIFT 30
22#define AUX_EQ_SEL_MASK 1
23#define AUX_EQ1_SEL 0
24#define AUX_EQ2_SEL 1
25#define AUX_XSCALE_SHIFT 16
26#define AUX_XSCALE_MASK 0xFFF
27#define AUX_YSCALE_SHIFT 0
28#define AUX_YSCALE_MASK 0xFFF
29#define AUX_SYNT_ENB 31
30
31struct aux_clk_masks {
32 u32 eq_sel_mask;
33 u32 eq_sel_shift;
34 u32 eq1_mask;
35 u32 eq2_mask;
36 u32 xscale_sel_mask;
37 u32 xscale_sel_shift;
38 u32 yscale_sel_mask;
39 u32 yscale_sel_shift;
40 u32 enable_bit;
41};
42
43struct aux_rate_tbl {
44 u16 xscale;
45 u16 yscale;
46 u8 eq;
47};
48
49struct clk_aux {
50 struct clk_hw hw;
51 void __iomem *reg;
52 struct aux_clk_masks *masks;
53 struct aux_rate_tbl *rtbl;
54 u8 rtbl_cnt;
55 spinlock_t *lock;
56};
57
58/* Fractional Synth clk */
59struct frac_rate_tbl {
60 u32 div;
61};
62
63struct clk_frac {
64 struct clk_hw hw;
65 void __iomem *reg;
66 struct frac_rate_tbl *rtbl;
67 u8 rtbl_cnt;
68 spinlock_t *lock;
69};
70
71/* GPT clk */
72struct gpt_rate_tbl {
73 u16 mscale;
74 u16 nscale;
75};
76
77struct clk_gpt {
78 struct clk_hw hw;
79 void __iomem *reg;
80 struct gpt_rate_tbl *rtbl;
81 u8 rtbl_cnt;
82 spinlock_t *lock;
83};
84
85/* VCO-PLL clk */
86struct pll_rate_tbl {
87 u8 mode;
88 u16 m;
89 u8 n;
90 u8 p;
91};
92
93struct clk_vco {
94 struct clk_hw hw;
95 void __iomem *mode_reg;
96 void __iomem *cfg_reg;
97 struct pll_rate_tbl *rtbl;
98 u8 rtbl_cnt;
99 spinlock_t *lock;
100};
101
102struct clk_pll {
103 struct clk_hw hw;
104 struct clk_vco *vco;
105 const char *parent[1];
106 spinlock_t *lock;
107};
108
109typedef unsigned long (*clk_calc_rate)(struct clk_hw *hw, unsigned long prate,
110 int index);
111
112/* clk register routines */
113struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
114 const char *parent_name, unsigned long flags, void __iomem *reg,
115 struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
116 u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk);
117struct clk *clk_register_frac(const char *name, const char *parent_name,
118 unsigned long flags, void __iomem *reg,
119 struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock);
120struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
121 long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
122 rtbl_cnt, spinlock_t *lock);
123struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
124 const char *vco_gate_name, const char *parent_name,
125 unsigned long flags, void __iomem *mode_reg, void __iomem
126 *cfg_reg, struct pll_rate_tbl *rtbl, u8 rtbl_cnt,
127 spinlock_t *lock, struct clk **pll_clk,
128 struct clk **vco_gate_clk);
129
130long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
131 unsigned long parent_rate, clk_calc_rate calc_rate, u8 rtbl_cnt,
132 int *index);
133
134#endif /* __SPEAR_CLK_H */
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c
new file mode 100644
index 00000000000..440bb3e4c97
--- /dev/null
+++ b/drivers/clk/spear/spear3xx_clock.c
@@ -0,0 +1,612 @@
1/*
2 * SPEAr3xx machines clock framework source file
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Viresh Kumar <viresh.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/of_platform.h>
17#include <linux/spinlock_types.h>
18#include <mach/misc_regs.h>
19#include "clk.h"
20
21static DEFINE_SPINLOCK(_lock);
22
23#define PLL1_CTR (MISC_BASE + 0x008)
24#define PLL1_FRQ (MISC_BASE + 0x00C)
25#define PLL2_CTR (MISC_BASE + 0x014)
26#define PLL2_FRQ (MISC_BASE + 0x018)
27#define PLL_CLK_CFG (MISC_BASE + 0x020)
28 /* PLL_CLK_CFG register masks */
29 #define MCTR_CLK_SHIFT 28
30 #define MCTR_CLK_MASK 3
31
32#define CORE_CLK_CFG (MISC_BASE + 0x024)
33 /* CORE CLK CFG register masks */
34 #define GEN_SYNTH2_3_CLK_SHIFT 18
35 #define GEN_SYNTH2_3_CLK_MASK 1
36
37 #define HCLK_RATIO_SHIFT 10
38 #define HCLK_RATIO_MASK 2
39 #define PCLK_RATIO_SHIFT 8
40 #define PCLK_RATIO_MASK 2
41
42#define PERIP_CLK_CFG (MISC_BASE + 0x028)
43 /* PERIP_CLK_CFG register masks */
44 #define UART_CLK_SHIFT 4
45 #define UART_CLK_MASK 1
46 #define FIRDA_CLK_SHIFT 5
47 #define FIRDA_CLK_MASK 2
48 #define GPT0_CLK_SHIFT 8
49 #define GPT1_CLK_SHIFT 11
50 #define GPT2_CLK_SHIFT 12
51 #define GPT_CLK_MASK 1
52
53#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
54 /* PERIP1_CLK_ENB register masks */
55 #define UART_CLK_ENB 3
56 #define SSP_CLK_ENB 5
57 #define I2C_CLK_ENB 7
58 #define JPEG_CLK_ENB 8
59 #define FIRDA_CLK_ENB 10
60 #define GPT1_CLK_ENB 11
61 #define GPT2_CLK_ENB 12
62 #define ADC_CLK_ENB 15
63 #define RTC_CLK_ENB 17
64 #define GPIO_CLK_ENB 18
65 #define DMA_CLK_ENB 19
66 #define SMI_CLK_ENB 21
67 #define GMAC_CLK_ENB 23
68 #define USBD_CLK_ENB 24
69 #define USBH_CLK_ENB 25
70 #define C3_CLK_ENB 31
71
72#define RAS_CLK_ENB (MISC_BASE + 0x034)
73 #define RAS_AHB_CLK_ENB 0
74 #define RAS_PLL1_CLK_ENB 1
75 #define RAS_APB_CLK_ENB 2
76 #define RAS_32K_CLK_ENB 3
77 #define RAS_24M_CLK_ENB 4
78 #define RAS_48M_CLK_ENB 5
79 #define RAS_PLL2_CLK_ENB 7
80 #define RAS_SYNT0_CLK_ENB 8
81 #define RAS_SYNT1_CLK_ENB 9
82 #define RAS_SYNT2_CLK_ENB 10
83 #define RAS_SYNT3_CLK_ENB 11
84
85#define PRSC0_CLK_CFG (MISC_BASE + 0x044)
86#define PRSC1_CLK_CFG (MISC_BASE + 0x048)
87#define PRSC2_CLK_CFG (MISC_BASE + 0x04C)
88#define AMEM_CLK_CFG (MISC_BASE + 0x050)
89 #define AMEM_CLK_ENB 0
90
91#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
92#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
93#define UART_CLK_SYNT (MISC_BASE + 0x064)
94#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
95#define GEN0_CLK_SYNT (MISC_BASE + 0x06C)
96#define GEN1_CLK_SYNT (MISC_BASE + 0x070)
97#define GEN2_CLK_SYNT (MISC_BASE + 0x074)
98#define GEN3_CLK_SYNT (MISC_BASE + 0x078)
99
100/* pll rate configuration table, in ascending order of rates */
101static struct pll_rate_tbl pll_rtbl[] = {
102 {.mode = 0, .m = 0x53, .n = 0x0C, .p = 0x1}, /* vco 332 & pll 166 MHz */
103 {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* vco 532 & pll 266 MHz */
104 {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* vco 664 & pll 332 MHz */
105};
106
107/* aux rate configuration table, in ascending order of rates */
108static struct aux_rate_tbl aux_rtbl[] = {
109 /* For PLL1 = 332 MHz */
110 {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */
111 {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */
112 {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */
113 {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
114};
115
116/* gpt rate configuration table, in ascending order of rates */
117static struct gpt_rate_tbl gpt_rtbl[] = {
118 /* For pll1 = 332 MHz */
119 {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
120 {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
121 {.mscale = 1, .nscale = 0}, /* 83 MHz */
122};
123
124/* clock parents */
125static const char *uart0_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", };
126static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk",
127};
128static const char *gpt0_parents[] = { "pll3_48m_clk", "gpt0_synth_clk", };
129static const char *gpt1_parents[] = { "pll3_48m_clk", "gpt1_synth_clk", };
130static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", };
131static const char *gen2_3_parents[] = { "pll1_clk", "pll2_clk", };
132static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none",
133 "pll2_clk", };
134
135#ifdef CONFIG_MACH_SPEAR300
136static void __init spear300_clk_init(void)
137{
138 struct clk *clk;
139
140 clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0,
141 1, 1);
142 clk_register_clkdev(clk, NULL, "60000000.clcd");
143
144 clk = clk_register_fixed_factor(NULL, "fsmc_clk", "ras_ahb_clk", 0, 1,
145 1);
146 clk_register_clkdev(clk, NULL, "94000000.flash");
147
148 clk = clk_register_fixed_factor(NULL, "sdhci_clk", "ras_ahb_clk", 0, 1,
149 1);
150 clk_register_clkdev(clk, NULL, "70000000.sdhci");
151
152 clk = clk_register_fixed_factor(NULL, "gpio1_clk", "ras_apb_clk", 0, 1,
153 1);
154 clk_register_clkdev(clk, NULL, "a9000000.gpio");
155
156 clk = clk_register_fixed_factor(NULL, "kbd_clk", "ras_apb_clk", 0, 1,
157 1);
158 clk_register_clkdev(clk, NULL, "a0000000.kbd");
159}
160#endif
161
162/* array of all spear 310 clock lookups */
163#ifdef CONFIG_MACH_SPEAR310
164static void __init spear310_clk_init(void)
165{
166 struct clk *clk;
167
168 clk = clk_register_fixed_factor(NULL, "emi_clk", "ras_ahb_clk", 0, 1,
169 1);
170 clk_register_clkdev(clk, "emi", NULL);
171
172 clk = clk_register_fixed_factor(NULL, "fsmc_clk", "ras_ahb_clk", 0, 1,
173 1);
174 clk_register_clkdev(clk, NULL, "44000000.flash");
175
176 clk = clk_register_fixed_factor(NULL, "tdm_clk", "ras_ahb_clk", 0, 1,
177 1);
178 clk_register_clkdev(clk, NULL, "tdm");
179
180 clk = clk_register_fixed_factor(NULL, "uart1_clk", "ras_apb_clk", 0, 1,
181 1);
182 clk_register_clkdev(clk, NULL, "b2000000.serial");
183
184 clk = clk_register_fixed_factor(NULL, "uart2_clk", "ras_apb_clk", 0, 1,
185 1);
186 clk_register_clkdev(clk, NULL, "b2080000.serial");
187
188 clk = clk_register_fixed_factor(NULL, "uart3_clk", "ras_apb_clk", 0, 1,
189 1);
190 clk_register_clkdev(clk, NULL, "b2100000.serial");
191
192 clk = clk_register_fixed_factor(NULL, "uart4_clk", "ras_apb_clk", 0, 1,
193 1);
194 clk_register_clkdev(clk, NULL, "b2180000.serial");
195
196 clk = clk_register_fixed_factor(NULL, "uart5_clk", "ras_apb_clk", 0, 1,
197 1);
198 clk_register_clkdev(clk, NULL, "b2200000.serial");
199}
200#endif
201
202/* array of all spear 320 clock lookups */
203#ifdef CONFIG_MACH_SPEAR320
204 #define SMII_PCLK_SHIFT 18
205 #define SMII_PCLK_MASK 2
206 #define SMII_PCLK_VAL_PAD 0x0
207 #define SMII_PCLK_VAL_PLL2 0x1
208 #define SMII_PCLK_VAL_SYNTH0 0x2
209 #define SDHCI_PCLK_SHIFT 15
210 #define SDHCI_PCLK_MASK 1
211 #define SDHCI_PCLK_VAL_48M 0x0
212 #define SDHCI_PCLK_VAL_SYNTH3 0x1
213 #define I2S_REF_PCLK_SHIFT 8
214 #define I2S_REF_PCLK_MASK 1
215 #define I2S_REF_PCLK_SYNTH_VAL 0x1
216 #define I2S_REF_PCLK_PLL2_VAL 0x0
217 #define UART1_PCLK_SHIFT 6
218 #define UART1_PCLK_MASK 1
219 #define SPEAR320_UARTX_PCLK_VAL_SYNTH1 0x0
220 #define SPEAR320_UARTX_PCLK_VAL_APB 0x1
221
222static const char *i2s_ref_parents[] = { "ras_pll2_clk",
223 "ras_gen2_synth_gate_clk", };
224static const char *sdhci_parents[] = { "ras_pll3_48m_clk",
225 "ras_gen3_synth_gate_clk",
226};
227static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk",
228 "ras_gen0_synth_gate_clk", };
229static const char *uartx_parents[] = { "ras_gen1_synth_gate_clk", "ras_apb_clk",
230};
231
232static void __init spear320_clk_init(void)
233{
234 struct clk *clk;
235
236 clk = clk_register_fixed_rate(NULL, "smii_125m_pad_clk", NULL,
237 CLK_IS_ROOT, 125000000);
238 clk_register_clkdev(clk, "smii_125m_pad", NULL);
239
240 clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0,
241 1, 1);
242 clk_register_clkdev(clk, NULL, "90000000.clcd");
243
244 clk = clk_register_fixed_factor(NULL, "emi_clk", "ras_ahb_clk", 0, 1,
245 1);
246 clk_register_clkdev(clk, "emi", NULL);
247
248 clk = clk_register_fixed_factor(NULL, "fsmc_clk", "ras_ahb_clk", 0, 1,
249 1);
250 clk_register_clkdev(clk, NULL, "4c000000.flash");
251
252 clk = clk_register_fixed_factor(NULL, "i2c1_clk", "ras_ahb_clk", 0, 1,
253 1);
254 clk_register_clkdev(clk, NULL, "a7000000.i2c");
255
256 clk = clk_register_fixed_factor(NULL, "pwm_clk", "ras_ahb_clk", 0, 1,
257 1);
258 clk_register_clkdev(clk, "pwm", NULL);
259
260 clk = clk_register_fixed_factor(NULL, "ssp1_clk", "ras_ahb_clk", 0, 1,
261 1);
262 clk_register_clkdev(clk, NULL, "a5000000.spi");
263
264 clk = clk_register_fixed_factor(NULL, "ssp2_clk", "ras_ahb_clk", 0, 1,
265 1);
266 clk_register_clkdev(clk, NULL, "a6000000.spi");
267
268 clk = clk_register_fixed_factor(NULL, "can0_clk", "ras_apb_clk", 0, 1,
269 1);
270 clk_register_clkdev(clk, NULL, "c_can_platform.0");
271
272 clk = clk_register_fixed_factor(NULL, "can1_clk", "ras_apb_clk", 0, 1,
273 1);
274 clk_register_clkdev(clk, NULL, "c_can_platform.1");
275
276 clk = clk_register_fixed_factor(NULL, "i2s_clk", "ras_apb_clk", 0, 1,
277 1);
278 clk_register_clkdev(clk, NULL, "i2s");
279
280 clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents,
281 ARRAY_SIZE(i2s_ref_parents), 0, SPEAR320_CONTROL_REG,
282 I2S_REF_PCLK_SHIFT, I2S_REF_PCLK_MASK, 0, &_lock);
283 clk_register_clkdev(clk, "i2s_ref_clk", NULL);
284
285 clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", 0, 1,
286 4);
287 clk_register_clkdev(clk, "i2s_sclk", NULL);
288
289 clk = clk_register_mux(NULL, "rs485_clk", uartx_parents,
290 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
291 SPEAR320_RS485_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
292 &_lock);
293 clk_register_clkdev(clk, NULL, "a9300000.serial");
294
295 clk = clk_register_mux(NULL, "sdhci_clk", sdhci_parents,
296 ARRAY_SIZE(sdhci_parents), 0, SPEAR320_CONTROL_REG,
297 SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, 0, &_lock);
298 clk_register_clkdev(clk, NULL, "70000000.sdhci");
299
300 clk = clk_register_mux(NULL, "smii_pclk", smii0_parents,
301 ARRAY_SIZE(smii0_parents), 0, SPEAR320_CONTROL_REG,
302 SMII_PCLK_SHIFT, SMII_PCLK_MASK, 0, &_lock);
303 clk_register_clkdev(clk, NULL, "smii_pclk");
304
305 clk = clk_register_fixed_factor(NULL, "smii_clk", "smii_pclk", 0, 1, 1);
306 clk_register_clkdev(clk, NULL, "smii");
307
308 clk = clk_register_mux(NULL, "uart1_clk", uartx_parents,
309 ARRAY_SIZE(uartx_parents), 0, SPEAR320_CONTROL_REG,
310 UART1_PCLK_SHIFT, UART1_PCLK_MASK, 0, &_lock);
311 clk_register_clkdev(clk, NULL, "a3000000.serial");
312
313 clk = clk_register_mux(NULL, "uart2_clk", uartx_parents,
314 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
315 SPEAR320_UART2_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
316 &_lock);
317 clk_register_clkdev(clk, NULL, "a4000000.serial");
318
319 clk = clk_register_mux(NULL, "uart3_clk", uartx_parents,
320 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
321 SPEAR320_UART3_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
322 &_lock);
323 clk_register_clkdev(clk, NULL, "a9100000.serial");
324
325 clk = clk_register_mux(NULL, "uart4_clk", uartx_parents,
326 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
327 SPEAR320_UART4_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
328 &_lock);
329 clk_register_clkdev(clk, NULL, "a9200000.serial");
330
331 clk = clk_register_mux(NULL, "uart5_clk", uartx_parents,
332 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
333 SPEAR320_UART5_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
334 &_lock);
335 clk_register_clkdev(clk, NULL, "60000000.serial");
336
337 clk = clk_register_mux(NULL, "uart6_clk", uartx_parents,
338 ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG,
339 SPEAR320_UART6_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0,
340 &_lock);
341 clk_register_clkdev(clk, NULL, "60100000.serial");
342}
343#endif
344
345void __init spear3xx_clk_init(void)
346{
347 struct clk *clk, *clk1;
348
349 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
350 clk_register_clkdev(clk, "apb_pclk", NULL);
351
352 clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
353 32000);
354 clk_register_clkdev(clk, "osc_32k_clk", NULL);
355
356 clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT,
357 24000000);
358 clk_register_clkdev(clk, "osc_24m_clk", NULL);
359
360 /* clock derived from 32 KHz osc clk */
361 clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0,
362 PERIP1_CLK_ENB, RTC_CLK_ENB, 0, &_lock);
363 clk_register_clkdev(clk, NULL, "fc900000.rtc");
364
365 /* clock derived from 24 MHz osc clk */
366 clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0,
367 48000000);
368 clk_register_clkdev(clk, "pll3_48m_clk", NULL);
369
370 clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_24m_clk", 0, 1,
371 1);
372 clk_register_clkdev(clk, NULL, "fc880000.wdt");
373
374 clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL,
375 "osc_24m_clk", 0, PLL1_CTR, PLL1_FRQ, pll_rtbl,
376 ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL);
377 clk_register_clkdev(clk, "vco1_clk", NULL);
378 clk_register_clkdev(clk1, "pll1_clk", NULL);
379
380 clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL,
381 "osc_24m_clk", 0, PLL2_CTR, PLL2_FRQ, pll_rtbl,
382 ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL);
383 clk_register_clkdev(clk, "vco2_clk", NULL);
384 clk_register_clkdev(clk1, "pll2_clk", NULL);
385
386 /* clock derived from pll1 clk */
387 clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1);
388 clk_register_clkdev(clk, "cpu_clk", NULL);
389
390 clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk",
391 CLK_SET_RATE_PARENT, CORE_CLK_CFG, HCLK_RATIO_SHIFT,
392 HCLK_RATIO_MASK, 0, &_lock);
393 clk_register_clkdev(clk, "ahb_clk", NULL);
394
395 clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk",
396 "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl,
397 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
398 clk_register_clkdev(clk, "uart_synth_clk", NULL);
399 clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL);
400
401 clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents,
402 ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG,
403 UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock);
404 clk_register_clkdev(clk, "uart0_mux_clk", NULL);
405
406 clk = clk_register_gate(NULL, "uart0", "uart0_mux_clk", 0,
407 PERIP1_CLK_ENB, UART_CLK_ENB, 0, &_lock);
408 clk_register_clkdev(clk, NULL, "d0000000.serial");
409
410 clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk",
411 "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl,
412 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
413 clk_register_clkdev(clk, "firda_synth_clk", NULL);
414 clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL);
415
416 clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents,
417 ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG,
418 FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock);
419 clk_register_clkdev(clk, "firda_mux_clk", NULL);
420
421 clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0,
422 PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock);
423 clk_register_clkdev(clk, NULL, "firda");
424
425 /* gpt clocks */
426 clk_register_gpt("gpt0_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG,
427 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
428 clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents,
429 ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG,
430 GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
431 clk_register_clkdev(clk, NULL, "gpt0");
432
433 clk_register_gpt("gpt1_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG,
434 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
435 clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt1_parents,
436 ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG,
437 GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
438 clk_register_clkdev(clk, "gpt1_mux_clk", NULL);
439 clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0,
440 PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock);
441 clk_register_clkdev(clk, NULL, "gpt1");
442
443 clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG,
444 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
445 clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents,
446 ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG,
447 GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
448 clk_register_clkdev(clk, "gpt2_mux_clk", NULL);
449 clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0,
450 PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock);
451 clk_register_clkdev(clk, NULL, "gpt2");
452
453 /* general synths clocks */
454 clk = clk_register_aux("gen0_synth_clk", "gen0_synth_gate_clk",
455 "pll1_clk", 0, GEN0_CLK_SYNT, NULL, aux_rtbl,
456 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
457 clk_register_clkdev(clk, "gen0_synth_clk", NULL);
458 clk_register_clkdev(clk1, "gen0_synth_gate_clk", NULL);
459
460 clk = clk_register_aux("gen1_synth_clk", "gen1_synth_gate_clk",
461 "pll1_clk", 0, GEN1_CLK_SYNT, NULL, aux_rtbl,
462 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
463 clk_register_clkdev(clk, "gen1_synth_clk", NULL);
464 clk_register_clkdev(clk1, "gen1_synth_gate_clk", NULL);
465
466 clk = clk_register_mux(NULL, "gen2_3_parent_clk", gen2_3_parents,
467 ARRAY_SIZE(gen2_3_parents), 0, CORE_CLK_CFG,
468 GEN_SYNTH2_3_CLK_SHIFT, GEN_SYNTH2_3_CLK_MASK, 0,
469 &_lock);
470 clk_register_clkdev(clk, "gen2_3_parent_clk", NULL);
471
472 clk = clk_register_aux("gen2_synth_clk", "gen2_synth_gate_clk",
473 "gen2_3_parent_clk", 0, GEN2_CLK_SYNT, NULL, aux_rtbl,
474 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
475 clk_register_clkdev(clk, "gen2_synth_clk", NULL);
476 clk_register_clkdev(clk1, "gen2_synth_gate_clk", NULL);
477
478 clk = clk_register_aux("gen3_synth_clk", "gen3_synth_gate_clk",
479 "gen2_3_parent_clk", 0, GEN3_CLK_SYNT, NULL, aux_rtbl,
480 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
481 clk_register_clkdev(clk, "gen3_synth_clk", NULL);
482 clk_register_clkdev(clk1, "gen3_synth_gate_clk", NULL);
483
484 /* clock derived from pll3 clk */
485 clk = clk_register_gate(NULL, "usbh_clk", "pll3_48m_clk", 0,
486 PERIP1_CLK_ENB, USBH_CLK_ENB, 0, &_lock);
487 clk_register_clkdev(clk, "usbh_clk", NULL);
488
489 clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1,
490 1);
491 clk_register_clkdev(clk, "usbh.0_clk", NULL);
492
493 clk = clk_register_fixed_factor(NULL, "usbh.1_clk", "usbh_clk", 0, 1,
494 1);
495 clk_register_clkdev(clk, "usbh.1_clk", NULL);
496
497 clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0,
498 PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock);
499 clk_register_clkdev(clk, NULL, "designware_udc");
500
501 /* clock derived from ahb clk */
502 clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2,
503 1);
504 clk_register_clkdev(clk, "ahbmult2_clk", NULL);
505
506 clk = clk_register_mux(NULL, "ddr_clk", ddr_parents,
507 ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT,
508 MCTR_CLK_MASK, 0, &_lock);
509 clk_register_clkdev(clk, "ddr_clk", NULL);
510
511 clk = clk_register_divider(NULL, "apb_clk", "ahb_clk",
512 CLK_SET_RATE_PARENT, CORE_CLK_CFG, PCLK_RATIO_SHIFT,
513 PCLK_RATIO_MASK, 0, &_lock);
514 clk_register_clkdev(clk, "apb_clk", NULL);
515
516 clk = clk_register_gate(NULL, "amem_clk", "ahb_clk", 0, AMEM_CLK_CFG,
517 AMEM_CLK_ENB, 0, &_lock);
518 clk_register_clkdev(clk, "amem_clk", NULL);
519
520 clk = clk_register_gate(NULL, "c3_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
521 C3_CLK_ENB, 0, &_lock);
522 clk_register_clkdev(clk, NULL, "c3_clk");
523
524 clk = clk_register_gate(NULL, "dma_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
525 DMA_CLK_ENB, 0, &_lock);
526 clk_register_clkdev(clk, NULL, "fc400000.dma");
527
528 clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
529 GMAC_CLK_ENB, 0, &_lock);
530 clk_register_clkdev(clk, NULL, "e0800000.eth");
531
532 clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
533 I2C_CLK_ENB, 0, &_lock);
534 clk_register_clkdev(clk, NULL, "d0180000.i2c");
535
536 clk = clk_register_gate(NULL, "jpeg_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
537 JPEG_CLK_ENB, 0, &_lock);
538 clk_register_clkdev(clk, NULL, "jpeg");
539
540 clk = clk_register_gate(NULL, "smi_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
541 SMI_CLK_ENB, 0, &_lock);
542 clk_register_clkdev(clk, NULL, "fc000000.flash");
543
544 /* clock derived from apb clk */
545 clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB,
546 ADC_CLK_ENB, 0, &_lock);
547 clk_register_clkdev(clk, NULL, "adc");
548
549 clk = clk_register_gate(NULL, "gpio0_clk", "apb_clk", 0, PERIP1_CLK_ENB,
550 GPIO_CLK_ENB, 0, &_lock);
551 clk_register_clkdev(clk, NULL, "fc980000.gpio");
552
553 clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0, PERIP1_CLK_ENB,
554 SSP_CLK_ENB, 0, &_lock);
555 clk_register_clkdev(clk, NULL, "d0100000.spi");
556
557 /* RAS clk enable */
558 clk = clk_register_gate(NULL, "ras_ahb_clk", "ahb_clk", 0, RAS_CLK_ENB,
559 RAS_AHB_CLK_ENB, 0, &_lock);
560 clk_register_clkdev(clk, "ras_ahb_clk", NULL);
561
562 clk = clk_register_gate(NULL, "ras_apb_clk", "apb_clk", 0, RAS_CLK_ENB,
563 RAS_APB_CLK_ENB, 0, &_lock);
564 clk_register_clkdev(clk, "ras_apb_clk", NULL);
565
566 clk = clk_register_gate(NULL, "ras_32k_clk", "osc_32k_clk", 0,
567 RAS_CLK_ENB, RAS_32K_CLK_ENB, 0, &_lock);
568 clk_register_clkdev(clk, "ras_32k_clk", NULL);
569
570 clk = clk_register_gate(NULL, "ras_24m_clk", "osc_24m_clk", 0,
571 RAS_CLK_ENB, RAS_24M_CLK_ENB, 0, &_lock);
572 clk_register_clkdev(clk, "ras_24m_clk", NULL);
573
574 clk = clk_register_gate(NULL, "ras_pll1_clk", "pll1_clk", 0,
575 RAS_CLK_ENB, RAS_PLL1_CLK_ENB, 0, &_lock);
576 clk_register_clkdev(clk, "ras_pll1_clk", NULL);
577
578 clk = clk_register_gate(NULL, "ras_pll2_clk", "pll2_clk", 0,
579 RAS_CLK_ENB, RAS_PLL2_CLK_ENB, 0, &_lock);
580 clk_register_clkdev(clk, "ras_pll2_clk", NULL);
581
582 clk = clk_register_gate(NULL, "ras_pll3_48m_clk", "pll3_48m_clk", 0,
583 RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock);
584 clk_register_clkdev(clk, "ras_pll3_48m_clk", NULL);
585
586 clk = clk_register_gate(NULL, "ras_gen0_synth_gate_clk",
587 "gen0_synth_gate_clk", 0, RAS_CLK_ENB,
588 RAS_SYNT0_CLK_ENB, 0, &_lock);
589 clk_register_clkdev(clk, "ras_gen0_synth_gate_clk", NULL);
590
591 clk = clk_register_gate(NULL, "ras_gen1_synth_gate_clk",
592 "gen1_synth_gate_clk", 0, RAS_CLK_ENB,
593 RAS_SYNT1_CLK_ENB, 0, &_lock);
594 clk_register_clkdev(clk, "ras_gen1_synth_gate_clk", NULL);
595
596 clk = clk_register_gate(NULL, "ras_gen2_synth_gate_clk",
597 "gen2_synth_gate_clk", 0, RAS_CLK_ENB,
598 RAS_SYNT2_CLK_ENB, 0, &_lock);
599 clk_register_clkdev(clk, "ras_gen2_synth_gate_clk", NULL);
600
601 clk = clk_register_gate(NULL, "ras_gen3_synth_gate_clk",
602 "gen3_synth_gate_clk", 0, RAS_CLK_ENB,
603 RAS_SYNT3_CLK_ENB, 0, &_lock);
604 clk_register_clkdev(clk, "ras_gen3_synth_gate_clk", NULL);
605
606 if (of_machine_is_compatible("st,spear300"))
607 spear300_clk_init();
608 else if (of_machine_is_compatible("st,spear310"))
609 spear310_clk_init();
610 else if (of_machine_is_compatible("st,spear320"))
611 spear320_clk_init();
612}
diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c
new file mode 100644
index 00000000000..f9a20b38230
--- /dev/null
+++ b/drivers/clk/spear/spear6xx_clock.c
@@ -0,0 +1,342 @@
1/*
2 * SPEAr6xx machines clock framework source file
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Viresh Kumar <viresh.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/io.h>
15#include <linux/spinlock_types.h>
16#include <mach/misc_regs.h>
17#include "clk.h"
18
19static DEFINE_SPINLOCK(_lock);
20
21#define PLL1_CTR (MISC_BASE + 0x008)
22#define PLL1_FRQ (MISC_BASE + 0x00C)
23#define PLL2_CTR (MISC_BASE + 0x014)
24#define PLL2_FRQ (MISC_BASE + 0x018)
25#define PLL_CLK_CFG (MISC_BASE + 0x020)
26 /* PLL_CLK_CFG register masks */
27 #define MCTR_CLK_SHIFT 28
28 #define MCTR_CLK_MASK 3
29
30#define CORE_CLK_CFG (MISC_BASE + 0x024)
31 /* CORE CLK CFG register masks */
32 #define HCLK_RATIO_SHIFT 10
33 #define HCLK_RATIO_MASK 2
34 #define PCLK_RATIO_SHIFT 8
35 #define PCLK_RATIO_MASK 2
36
37#define PERIP_CLK_CFG (MISC_BASE + 0x028)
38 /* PERIP_CLK_CFG register masks */
39 #define CLCD_CLK_SHIFT 2
40 #define CLCD_CLK_MASK 2
41 #define UART_CLK_SHIFT 4
42 #define UART_CLK_MASK 1
43 #define FIRDA_CLK_SHIFT 5
44 #define FIRDA_CLK_MASK 2
45 #define GPT0_CLK_SHIFT 8
46 #define GPT1_CLK_SHIFT 10
47 #define GPT2_CLK_SHIFT 11
48 #define GPT3_CLK_SHIFT 12
49 #define GPT_CLK_MASK 1
50
51#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
52 /* PERIP1_CLK_ENB register masks */
53 #define UART0_CLK_ENB 3
54 #define UART1_CLK_ENB 4
55 #define SSP0_CLK_ENB 5
56 #define SSP1_CLK_ENB 6
57 #define I2C_CLK_ENB 7
58 #define JPEG_CLK_ENB 8
59 #define FSMC_CLK_ENB 9
60 #define FIRDA_CLK_ENB 10
61 #define GPT2_CLK_ENB 11
62 #define GPT3_CLK_ENB 12
63 #define GPIO2_CLK_ENB 13
64 #define SSP2_CLK_ENB 14
65 #define ADC_CLK_ENB 15
66 #define GPT1_CLK_ENB 11
67 #define RTC_CLK_ENB 17
68 #define GPIO1_CLK_ENB 18
69 #define DMA_CLK_ENB 19
70 #define SMI_CLK_ENB 21
71 #define CLCD_CLK_ENB 22
72 #define GMAC_CLK_ENB 23
73 #define USBD_CLK_ENB 24
74 #define USBH0_CLK_ENB 25
75 #define USBH1_CLK_ENB 26
76
77#define PRSC0_CLK_CFG (MISC_BASE + 0x044)
78#define PRSC1_CLK_CFG (MISC_BASE + 0x048)
79#define PRSC2_CLK_CFG (MISC_BASE + 0x04C)
80
81#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
82#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
83#define UART_CLK_SYNT (MISC_BASE + 0x064)
84
85/* vco rate configuration table, in ascending order of rates */
86static struct pll_rate_tbl pll_rtbl[] = {
87 {.mode = 0, .m = 0x53, .n = 0x0F, .p = 0x1}, /* vco 332 & pll 166 MHz */
88 {.mode = 0, .m = 0x85, .n = 0x0F, .p = 0x1}, /* vco 532 & pll 266 MHz */
89 {.mode = 0, .m = 0xA6, .n = 0x0F, .p = 0x1}, /* vco 664 & pll 332 MHz */
90};
91
92/* aux rate configuration table, in ascending order of rates */
93static struct aux_rate_tbl aux_rtbl[] = {
94 /* For PLL1 = 332 MHz */
95 {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */
96 {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */
97 {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
98};
99
100static const char *clcd_parents[] = { "pll3_48m_clk", "clcd_synth_gate_clk", };
101static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk",
102};
103static const char *uart_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", };
104static const char *gpt0_1_parents[] = { "pll3_48m_clk", "gpt0_1_synth_clk", };
105static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", };
106static const char *gpt3_parents[] = { "pll3_48m_clk", "gpt3_synth_clk", };
107static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none",
108 "pll2_clk", };
109
110/* gpt rate configuration table, in ascending order of rates */
111static struct gpt_rate_tbl gpt_rtbl[] = {
112 /* For pll1 = 332 MHz */
113 {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
114 {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
115 {.mscale = 1, .nscale = 0}, /* 83 MHz */
116};
117
118void __init spear6xx_clk_init(void)
119{
120 struct clk *clk, *clk1;
121
122 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
123 clk_register_clkdev(clk, "apb_pclk", NULL);
124
125 clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
126 32000);
127 clk_register_clkdev(clk, "osc_32k_clk", NULL);
128
129 clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, CLK_IS_ROOT,
130 30000000);
131 clk_register_clkdev(clk, "osc_30m_clk", NULL);
132
133 /* clock derived from 32 KHz osc clk */
134 clk = clk_register_gate(NULL, "rtc_spear", "osc_32k_clk", 0,
135 PERIP1_CLK_ENB, RTC_CLK_ENB, 0, &_lock);
136 clk_register_clkdev(clk, NULL, "rtc-spear");
137
138 /* clock derived from 30 MHz osc clk */
139 clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0,
140 48000000);
141 clk_register_clkdev(clk, "pll3_48m_clk", NULL);
142
143 clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "osc_30m_clk",
144 0, PLL1_CTR, PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl),
145 &_lock, &clk1, NULL);
146 clk_register_clkdev(clk, "vco1_clk", NULL);
147 clk_register_clkdev(clk1, "pll1_clk", NULL);
148
149 clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL,
150 "osc_30m_clk", 0, PLL2_CTR, PLL2_FRQ, pll_rtbl,
151 ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL);
152 clk_register_clkdev(clk, "vco2_clk", NULL);
153 clk_register_clkdev(clk1, "pll2_clk", NULL);
154
155 clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_30m_clk", 0, 1,
156 1);
157 clk_register_clkdev(clk, NULL, "wdt");
158
159 /* clock derived from pll1 clk */
160 clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1);
161 clk_register_clkdev(clk, "cpu_clk", NULL);
162
163 clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk",
164 CLK_SET_RATE_PARENT, CORE_CLK_CFG, HCLK_RATIO_SHIFT,
165 HCLK_RATIO_MASK, 0, &_lock);
166 clk_register_clkdev(clk, "ahb_clk", NULL);
167
168 clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk",
169 "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl,
170 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
171 clk_register_clkdev(clk, "uart_synth_clk", NULL);
172 clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL);
173
174 clk = clk_register_mux(NULL, "uart_mux_clk", uart_parents,
175 ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG,
176 UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock);
177 clk_register_clkdev(clk, "uart_mux_clk", NULL);
178
179 clk = clk_register_gate(NULL, "uart0", "uart_mux_clk", 0,
180 PERIP1_CLK_ENB, UART0_CLK_ENB, 0, &_lock);
181 clk_register_clkdev(clk, NULL, "d0000000.serial");
182
183 clk = clk_register_gate(NULL, "uart1", "uart_mux_clk", 0,
184 PERIP1_CLK_ENB, UART1_CLK_ENB, 0, &_lock);
185 clk_register_clkdev(clk, NULL, "d0080000.serial");
186
187 clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk",
188 "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl,
189 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
190 clk_register_clkdev(clk, "firda_synth_clk", NULL);
191 clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL);
192
193 clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents,
194 ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG,
195 FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock);
196 clk_register_clkdev(clk, "firda_mux_clk", NULL);
197
198 clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0,
199 PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock);
200 clk_register_clkdev(clk, NULL, "firda");
201
202 clk = clk_register_aux("clcd_synth_clk", "clcd_synth_gate_clk",
203 "pll1_clk", 0, CLCD_CLK_SYNT, NULL, aux_rtbl,
204 ARRAY_SIZE(aux_rtbl), &_lock, &clk1);
205 clk_register_clkdev(clk, "clcd_synth_clk", NULL);
206 clk_register_clkdev(clk1, "clcd_synth_gate_clk", NULL);
207
208 clk = clk_register_mux(NULL, "clcd_mux_clk", clcd_parents,
209 ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG,
210 CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock);
211 clk_register_clkdev(clk, "clcd_mux_clk", NULL);
212
213 clk = clk_register_gate(NULL, "clcd_clk", "clcd_mux_clk", 0,
214 PERIP1_CLK_ENB, CLCD_CLK_ENB, 0, &_lock);
215 clk_register_clkdev(clk, NULL, "clcd");
216
217 /* gpt clocks */
218 clk = clk_register_gpt("gpt0_1_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG,
219 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
220 clk_register_clkdev(clk, "gpt0_1_synth_clk", NULL);
221
222 clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt0_1_parents,
223 ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
224 GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
225 clk_register_clkdev(clk, NULL, "gpt0");
226
227 clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt0_1_parents,
228 ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
229 GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
230 clk_register_clkdev(clk, "gpt1_mux_clk", NULL);
231
232 clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0,
233 PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock);
234 clk_register_clkdev(clk, NULL, "gpt1");
235
236 clk = clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG,
237 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
238 clk_register_clkdev(clk, "gpt2_synth_clk", NULL);
239
240 clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents,
241 ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG,
242 GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
243 clk_register_clkdev(clk, "gpt2_mux_clk", NULL);
244
245 clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0,
246 PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock);
247 clk_register_clkdev(clk, NULL, "gpt2");
248
249 clk = clk_register_gpt("gpt3_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG,
250 gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
251 clk_register_clkdev(clk, "gpt3_synth_clk", NULL);
252
253 clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt3_parents,
254 ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG,
255 GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
256 clk_register_clkdev(clk, "gpt3_mux_clk", NULL);
257
258 clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0,
259 PERIP1_CLK_ENB, GPT3_CLK_ENB, 0, &_lock);
260 clk_register_clkdev(clk, NULL, "gpt3");
261
262 /* clock derived from pll3 clk */
263 clk = clk_register_gate(NULL, "usbh0_clk", "pll3_48m_clk", 0,
264 PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock);
265 clk_register_clkdev(clk, NULL, "usbh.0_clk");
266
267 clk = clk_register_gate(NULL, "usbh1_clk", "pll3_48m_clk", 0,
268 PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock);
269 clk_register_clkdev(clk, NULL, "usbh.1_clk");
270
271 clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0,
272 PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock);
273 clk_register_clkdev(clk, NULL, "designware_udc");
274
275 /* clock derived from ahb clk */
276 clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2,
277 1);
278 clk_register_clkdev(clk, "ahbmult2_clk", NULL);
279
280 clk = clk_register_mux(NULL, "ddr_clk", ddr_parents,
281 ARRAY_SIZE(ddr_parents),
282 0, PLL_CLK_CFG, MCTR_CLK_SHIFT, MCTR_CLK_MASK, 0,
283 &_lock);
284 clk_register_clkdev(clk, "ddr_clk", NULL);
285
286 clk = clk_register_divider(NULL, "apb_clk", "ahb_clk",
287 CLK_SET_RATE_PARENT, CORE_CLK_CFG, PCLK_RATIO_SHIFT,
288 PCLK_RATIO_MASK, 0, &_lock);
289 clk_register_clkdev(clk, "apb_clk", NULL);
290
291 clk = clk_register_gate(NULL, "dma_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
292 DMA_CLK_ENB, 0, &_lock);
293 clk_register_clkdev(clk, NULL, "fc400000.dma");
294
295 clk = clk_register_gate(NULL, "fsmc_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
296 FSMC_CLK_ENB, 0, &_lock);
297 clk_register_clkdev(clk, NULL, "d1800000.flash");
298
299 clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
300 GMAC_CLK_ENB, 0, &_lock);
301 clk_register_clkdev(clk, NULL, "gmac");
302
303 clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
304 I2C_CLK_ENB, 0, &_lock);
305 clk_register_clkdev(clk, NULL, "d0200000.i2c");
306
307 clk = clk_register_gate(NULL, "jpeg_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
308 JPEG_CLK_ENB, 0, &_lock);
309 clk_register_clkdev(clk, NULL, "jpeg");
310
311 clk = clk_register_gate(NULL, "smi_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
312 SMI_CLK_ENB, 0, &_lock);
313 clk_register_clkdev(clk, NULL, "fc000000.flash");
314
315 /* clock derived from apb clk */
316 clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB,
317 ADC_CLK_ENB, 0, &_lock);
318 clk_register_clkdev(clk, NULL, "adc");
319
320 clk = clk_register_fixed_factor(NULL, "gpio0_clk", "apb_clk", 0, 1, 1);
321 clk_register_clkdev(clk, NULL, "f0100000.gpio");
322
323 clk = clk_register_gate(NULL, "gpio1_clk", "apb_clk", 0, PERIP1_CLK_ENB,
324 GPIO1_CLK_ENB, 0, &_lock);
325 clk_register_clkdev(clk, NULL, "fc980000.gpio");
326
327 clk = clk_register_gate(NULL, "gpio2_clk", "apb_clk", 0, PERIP1_CLK_ENB,
328 GPIO2_CLK_ENB, 0, &_lock);
329 clk_register_clkdev(clk, NULL, "d8100000.gpio");
330
331 clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0, PERIP1_CLK_ENB,
332 SSP0_CLK_ENB, 0, &_lock);
333 clk_register_clkdev(clk, NULL, "ssp-pl022.0");
334
335 clk = clk_register_gate(NULL, "ssp1_clk", "apb_clk", 0, PERIP1_CLK_ENB,
336 SSP1_CLK_ENB, 0, &_lock);
337 clk_register_clkdev(clk, NULL, "ssp-pl022.1");
338
339 clk = clk_register_gate(NULL, "ssp2_clk", "apb_clk", 0, PERIP1_CLK_ENB,
340 SSP2_CLK_ENB, 0, &_lock);
341 clk_register_clkdev(clk, NULL, "ssp-pl022.2");
342}
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index e6ecc5f2394..1cc6b3f3e26 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -16,6 +16,7 @@
16#include <linux/scatterlist.h> 16#include <linux/scatterlist.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/clk.h>
19#include <crypto/internal/hash.h> 20#include <crypto/internal/hash.h>
20#include <crypto/sha.h> 21#include <crypto/sha.h>
21 22
@@ -79,6 +80,7 @@ struct crypto_priv {
79 void __iomem *reg; 80 void __iomem *reg;
80 void __iomem *sram; 81 void __iomem *sram;
81 int irq; 82 int irq;
83 struct clk *clk;
82 struct task_struct *queue_th; 84 struct task_struct *queue_th;
83 85
84 /* the lock protects queue and eng_st */ 86 /* the lock protects queue and eng_st */
@@ -1053,6 +1055,12 @@ static int mv_probe(struct platform_device *pdev)
1053 if (ret) 1055 if (ret)
1054 goto err_thread; 1056 goto err_thread;
1055 1057
1058 /* Not all platforms can gate the clock, so it is not
1059 an error if the clock does not exists. */
1060 cp->clk = clk_get(&pdev->dev, NULL);
1061 if (!IS_ERR(cp->clk))
1062 clk_prepare_enable(cp->clk);
1063
1056 writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK); 1064 writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK);
1057 writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG); 1065 writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG);
1058 writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); 1066 writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0);
@@ -1118,6 +1126,12 @@ static int mv_remove(struct platform_device *pdev)
1118 memset(cp->sram, 0, cp->sram_size); 1126 memset(cp->sram, 0, cp->sram_size);
1119 iounmap(cp->sram); 1127 iounmap(cp->sram);
1120 iounmap(cp->reg); 1128 iounmap(cp->reg);
1129
1130 if (!IS_ERR(cp->clk)) {
1131 clk_disable_unprepare(cp->clk);
1132 clk_put(cp->clk);
1133 }
1134
1121 kfree(cp); 1135 kfree(cp);
1122 cpg = NULL; 1136 cpg = NULL;
1123 return 0; 1137 return 0;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index a472a29d849..fb4f4990f5e 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -323,7 +323,8 @@ struct sdma_engine {
323 struct sdma_context_data *context; 323 struct sdma_context_data *context;
324 dma_addr_t context_phys; 324 dma_addr_t context_phys;
325 struct dma_device dma_device; 325 struct dma_device dma_device;
326 struct clk *clk; 326 struct clk *clk_ipg;
327 struct clk *clk_ahb;
327 spinlock_t channel_0_lock; 328 spinlock_t channel_0_lock;
328 struct sdma_script_start_addrs *script_addrs; 329 struct sdma_script_start_addrs *script_addrs;
329}; 330};
@@ -867,7 +868,8 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
867 sdmac->peripheral_type = data->peripheral_type; 868 sdmac->peripheral_type = data->peripheral_type;
868 sdmac->event_id0 = data->dma_request; 869 sdmac->event_id0 = data->dma_request;
869 870
870 clk_enable(sdmac->sdma->clk); 871 clk_enable(sdmac->sdma->clk_ipg);
872 clk_enable(sdmac->sdma->clk_ahb);
871 873
872 ret = sdma_request_channel(sdmac); 874 ret = sdma_request_channel(sdmac);
873 if (ret) 875 if (ret)
@@ -904,7 +906,8 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
904 906
905 dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys); 907 dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
906 908
907 clk_disable(sdma->clk); 909 clk_disable(sdma->clk_ipg);
910 clk_disable(sdma->clk_ahb);
908} 911}
909 912
910static struct dma_async_tx_descriptor *sdma_prep_slave_sg( 913static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
@@ -1177,12 +1180,14 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
1177 addr = (void *)header + header->script_addrs_start; 1180 addr = (void *)header + header->script_addrs_start;
1178 ram_code = (void *)header + header->ram_code_start; 1181 ram_code = (void *)header + header->ram_code_start;
1179 1182
1180 clk_enable(sdma->clk); 1183 clk_enable(sdma->clk_ipg);
1184 clk_enable(sdma->clk_ahb);
1181 /* download the RAM image for SDMA */ 1185 /* download the RAM image for SDMA */
1182 sdma_load_script(sdma, ram_code, 1186 sdma_load_script(sdma, ram_code,
1183 header->ram_code_size, 1187 header->ram_code_size,
1184 addr->ram_code_start_addr); 1188 addr->ram_code_start_addr);
1185 clk_disable(sdma->clk); 1189 clk_disable(sdma->clk_ipg);
1190 clk_disable(sdma->clk_ahb);
1186 1191
1187 sdma_add_scripts(sdma, addr); 1192 sdma_add_scripts(sdma, addr);
1188 1193
@@ -1224,7 +1229,8 @@ static int __init sdma_init(struct sdma_engine *sdma)
1224 return -ENODEV; 1229 return -ENODEV;
1225 } 1230 }
1226 1231
1227 clk_enable(sdma->clk); 1232 clk_enable(sdma->clk_ipg);
1233 clk_enable(sdma->clk_ahb);
1228 1234
1229 /* Be sure SDMA has not started yet */ 1235 /* Be sure SDMA has not started yet */
1230 writel_relaxed(0, sdma->regs + SDMA_H_C0PTR); 1236 writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
@@ -1277,12 +1283,14 @@ static int __init sdma_init(struct sdma_engine *sdma)
1277 /* Initializes channel's priorities */ 1283 /* Initializes channel's priorities */
1278 sdma_set_channel_priority(&sdma->channel[0], 7); 1284 sdma_set_channel_priority(&sdma->channel[0], 7);
1279 1285
1280 clk_disable(sdma->clk); 1286 clk_disable(sdma->clk_ipg);
1287 clk_disable(sdma->clk_ahb);
1281 1288
1282 return 0; 1289 return 0;
1283 1290
1284err_dma_alloc: 1291err_dma_alloc:
1285 clk_disable(sdma->clk); 1292 clk_disable(sdma->clk_ipg);
1293 clk_disable(sdma->clk_ahb);
1286 dev_err(sdma->dev, "initialisation failed with %d\n", ret); 1294 dev_err(sdma->dev, "initialisation failed with %d\n", ret);
1287 return ret; 1295 return ret;
1288} 1296}
@@ -1321,12 +1329,21 @@ static int __init sdma_probe(struct platform_device *pdev)
1321 goto err_request_region; 1329 goto err_request_region;
1322 } 1330 }
1323 1331
1324 sdma->clk = clk_get(&pdev->dev, NULL); 1332 sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1325 if (IS_ERR(sdma->clk)) { 1333 if (IS_ERR(sdma->clk_ipg)) {
1326 ret = PTR_ERR(sdma->clk); 1334 ret = PTR_ERR(sdma->clk_ipg);
1327 goto err_clk; 1335 goto err_clk;
1328 } 1336 }
1329 1337
1338 sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
1339 if (IS_ERR(sdma->clk_ahb)) {
1340 ret = PTR_ERR(sdma->clk_ahb);
1341 goto err_clk;
1342 }
1343
1344 clk_prepare(sdma->clk_ipg);
1345 clk_prepare(sdma->clk_ahb);
1346
1330 sdma->regs = ioremap(iores->start, resource_size(iores)); 1347 sdma->regs = ioremap(iores->start, resource_size(iores));
1331 if (!sdma->regs) { 1348 if (!sdma->regs) {
1332 ret = -ENOMEM; 1349 ret = -ENOMEM;
@@ -1436,7 +1453,6 @@ err_alloc:
1436err_request_irq: 1453err_request_irq:
1437 iounmap(sdma->regs); 1454 iounmap(sdma->regs);
1438err_ioremap: 1455err_ioremap:
1439 clk_put(sdma->clk);
1440err_clk: 1456err_clk:
1441 release_mem_region(iores->start, resource_size(iores)); 1457 release_mem_region(iores->start, resource_size(iores));
1442err_request_region: 1458err_request_region:
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 62e3f8ec246..5ec72044ea4 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1715,7 +1715,7 @@ static int __init ipu_probe(struct platform_device *pdev)
1715 } 1715 }
1716 1716
1717 /* Make sure IPU HSP clock is running */ 1717 /* Make sure IPU HSP clock is running */
1718 clk_enable(ipu_data.ipu_clk); 1718 clk_prepare_enable(ipu_data.ipu_clk);
1719 1719
1720 /* Disable all interrupts */ 1720 /* Disable all interrupts */
1721 idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1); 1721 idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
@@ -1747,7 +1747,7 @@ static int __init ipu_probe(struct platform_device *pdev)
1747err_idmac_init: 1747err_idmac_init:
1748err_attach_irq: 1748err_attach_irq:
1749 ipu_irq_detach_irq(&ipu_data, pdev); 1749 ipu_irq_detach_irq(&ipu_data, pdev);
1750 clk_disable(ipu_data.ipu_clk); 1750 clk_disable_unprepare(ipu_data.ipu_clk);
1751 clk_put(ipu_data.ipu_clk); 1751 clk_put(ipu_data.ipu_clk);
1752err_clk_get: 1752err_clk_get:
1753 iounmap(ipu_data.reg_ic); 1753 iounmap(ipu_data.reg_ic);
@@ -1765,7 +1765,7 @@ static int __exit ipu_remove(struct platform_device *pdev)
1765 1765
1766 ipu_idmac_exit(ipu); 1766 ipu_idmac_exit(ipu);
1767 ipu_irq_detach_irq(ipu, pdev); 1767 ipu_irq_detach_irq(ipu, pdev);
1768 clk_disable(ipu->ipu_clk); 1768 clk_disable_unprepare(ipu->ipu_clk);
1769 clk_put(ipu->ipu_clk); 1769 clk_put(ipu->ipu_clk);
1770 iounmap(ipu->reg_ic); 1770 iounmap(ipu->reg_ic);
1771 iounmap(ipu->reg_ipu); 1771 iounmap(ipu->reg_ipu);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index fa5d55fea46..0b12e68bf79 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -25,6 +25,7 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/memory.h> 27#include <linux/memory.h>
28#include <linux/clk.h>
28#include <plat/mv_xor.h> 29#include <plat/mv_xor.h>
29 30
30#include "dmaengine.h" 31#include "dmaengine.h"
@@ -1307,11 +1308,25 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
1307 if (dram) 1308 if (dram)
1308 mv_xor_conf_mbus_windows(msp, dram); 1309 mv_xor_conf_mbus_windows(msp, dram);
1309 1310
1311 /* Not all platforms can gate the clock, so it is not
1312 * an error if the clock does not exists.
1313 */
1314 msp->clk = clk_get(&pdev->dev, NULL);
1315 if (!IS_ERR(msp->clk))
1316 clk_prepare_enable(msp->clk);
1317
1310 return 0; 1318 return 0;
1311} 1319}
1312 1320
1313static int mv_xor_shared_remove(struct platform_device *pdev) 1321static int mv_xor_shared_remove(struct platform_device *pdev)
1314{ 1322{
1323 struct mv_xor_shared_private *msp = platform_get_drvdata(pdev);
1324
1325 if (!IS_ERR(msp->clk)) {
1326 clk_disable_unprepare(msp->clk);
1327 clk_put(msp->clk);
1328 }
1329
1315 return 0; 1330 return 0;
1316} 1331}
1317 1332
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index 654876b7ba1..a5b422f5a8a 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -55,6 +55,7 @@
55struct mv_xor_shared_private { 55struct mv_xor_shared_private {
56 void __iomem *xor_base; 56 void __iomem *xor_base;
57 void __iomem *xor_high_base; 57 void __iomem *xor_high_base;
58 struct clk *clk;
58}; 59};
59 60
60 61
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 02d54a057b6..f13643d3135 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -511,7 +511,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
511 /* ipu_csi_init_interface() */ 511 /* ipu_csi_init_interface() */
512 csi_reg_write(mx3_cam, conf, CSI_SENS_CONF); 512 csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
513 513
514 clk_enable(mx3_cam->clk); 514 clk_prepare_enable(mx3_cam->clk);
515 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk); 515 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
516 dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate); 516 dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
517 if (rate) 517 if (rate)
@@ -552,7 +552,7 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
552 *ichan = NULL; 552 *ichan = NULL;
553 } 553 }
554 554
555 clk_disable(mx3_cam->clk); 555 clk_disable_unprepare(mx3_cam->clk);
556 556
557 mx3_cam->icd = NULL; 557 mx3_cam->icd = NULL;
558 558
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index eeb8cd125b0..3b9136c1a47 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -19,6 +19,7 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/scatterlist.h> 20#include <linux/scatterlist.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/clk.h>
22#include <linux/gpio.h> 23#include <linux/gpio.h>
23#include <linux/mmc/host.h> 24#include <linux/mmc/host.h>
24 25
@@ -51,6 +52,7 @@ struct mvsd_host {
51 struct device *dev; 52 struct device *dev;
52 struct resource *res; 53 struct resource *res;
53 int irq; 54 int irq;
55 struct clk *clk;
54 int gpio_card_detect; 56 int gpio_card_detect;
55 int gpio_write_protect; 57 int gpio_write_protect;
56}; 58};
@@ -770,6 +772,13 @@ static int __init mvsd_probe(struct platform_device *pdev)
770 } else 772 } else
771 host->irq = irq; 773 host->irq = irq;
772 774
775 /* Not all platforms can gate the clock, so it is not
776 an error if the clock does not exists. */
777 host->clk = clk_get(&pdev->dev, NULL);
778 if (!IS_ERR(host->clk)) {
779 clk_prepare_enable(host->clk);
780 }
781
773 if (mvsd_data->gpio_card_detect) { 782 if (mvsd_data->gpio_card_detect) {
774 ret = gpio_request(mvsd_data->gpio_card_detect, 783 ret = gpio_request(mvsd_data->gpio_card_detect,
775 DRIVER_NAME " cd"); 784 DRIVER_NAME " cd");
@@ -854,6 +863,11 @@ static int __exit mvsd_remove(struct platform_device *pdev)
854 mvsd_power_down(host); 863 mvsd_power_down(host);
855 iounmap(host->base); 864 iounmap(host->base);
856 release_resource(host->res); 865 release_resource(host->res);
866
867 if (!IS_ERR(host->clk)) {
868 clk_disable_unprepare(host->clk);
869 clk_put(host->clk);
870 }
857 mmc_free_host(mmc); 871 mmc_free_host(mmc);
858 } 872 }
859 platform_set_drvdata(pdev, NULL); 873 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index b2058b43232..28ed52d58f7 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -136,7 +136,8 @@ struct mxcmci_host {
136 u16 rev_no; 136 u16 rev_no;
137 unsigned int cmdat; 137 unsigned int cmdat;
138 138
139 struct clk *clk; 139 struct clk *clk_ipg;
140 struct clk *clk_per;
140 141
141 int clock; 142 int clock;
142 143
@@ -672,7 +673,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
672{ 673{
673 unsigned int divider; 674 unsigned int divider;
674 int prescaler = 0; 675 int prescaler = 0;
675 unsigned int clk_in = clk_get_rate(host->clk); 676 unsigned int clk_in = clk_get_rate(host->clk_per);
676 677
677 while (prescaler <= 0x800) { 678 while (prescaler <= 0x800) {
678 for (divider = 1; divider <= 0xF; divider++) { 679 for (divider = 1; divider <= 0xF; divider++) {
@@ -900,12 +901,20 @@ static int mxcmci_probe(struct platform_device *pdev)
900 host->res = r; 901 host->res = r;
901 host->irq = irq; 902 host->irq = irq;
902 903
903 host->clk = clk_get(&pdev->dev, NULL); 904 host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
904 if (IS_ERR(host->clk)) { 905 if (IS_ERR(host->clk_ipg)) {
905 ret = PTR_ERR(host->clk); 906 ret = PTR_ERR(host->clk_ipg);
906 goto out_iounmap; 907 goto out_iounmap;
907 } 908 }
908 clk_enable(host->clk); 909
910 host->clk_per = devm_clk_get(&pdev->dev, "per");
911 if (IS_ERR(host->clk_per)) {
912 ret = PTR_ERR(host->clk_per);
913 goto out_iounmap;
914 }
915
916 clk_prepare_enable(host->clk_per);
917 clk_prepare_enable(host->clk_ipg);
909 918
910 mxcmci_softreset(host); 919 mxcmci_softreset(host);
911 920
@@ -917,8 +926,8 @@ static int mxcmci_probe(struct platform_device *pdev)
917 goto out_clk_put; 926 goto out_clk_put;
918 } 927 }
919 928
920 mmc->f_min = clk_get_rate(host->clk) >> 16; 929 mmc->f_min = clk_get_rate(host->clk_per) >> 16;
921 mmc->f_max = clk_get_rate(host->clk) >> 1; 930 mmc->f_max = clk_get_rate(host->clk_per) >> 1;
922 931
923 /* recommended in data sheet */ 932 /* recommended in data sheet */
924 writew(0x2db4, host->base + MMC_REG_READ_TO); 933 writew(0x2db4, host->base + MMC_REG_READ_TO);
@@ -967,8 +976,8 @@ out_free_dma:
967 if (host->dma) 976 if (host->dma)
968 dma_release_channel(host->dma); 977 dma_release_channel(host->dma);
969out_clk_put: 978out_clk_put:
970 clk_disable(host->clk); 979 clk_disable_unprepare(host->clk_per);
971 clk_put(host->clk); 980 clk_disable_unprepare(host->clk_ipg);
972out_iounmap: 981out_iounmap:
973 iounmap(host->base); 982 iounmap(host->base);
974out_free: 983out_free:
@@ -999,8 +1008,8 @@ static int mxcmci_remove(struct platform_device *pdev)
999 if (host->dma) 1008 if (host->dma)
1000 dma_release_channel(host->dma); 1009 dma_release_channel(host->dma);
1001 1010
1002 clk_disable(host->clk); 1011 clk_disable_unprepare(host->clk_per);
1003 clk_put(host->clk); 1012 clk_disable_unprepare(host->clk_ipg);
1004 1013
1005 release_mem_region(host->res->start, resource_size(host->res)); 1014 release_mem_region(host->res->start, resource_size(host->res));
1006 1015
@@ -1018,7 +1027,8 @@ static int mxcmci_suspend(struct device *dev)
1018 1027
1019 if (mmc) 1028 if (mmc)
1020 ret = mmc_suspend_host(mmc); 1029 ret = mmc_suspend_host(mmc);
1021 clk_disable(host->clk); 1030 clk_disable_unprepare(host->clk_per);
1031 clk_disable_unprepare(host->clk_ipg);
1022 1032
1023 return ret; 1033 return ret;
1024} 1034}
@@ -1029,7 +1039,8 @@ static int mxcmci_resume(struct device *dev)
1029 struct mxcmci_host *host = mmc_priv(mmc); 1039 struct mxcmci_host *host = mmc_priv(mmc);
1030 int ret = 0; 1040 int ret = 0;
1031 1041
1032 clk_enable(host->clk); 1042 clk_prepare_enable(host->clk_per);
1043 clk_prepare_enable(host->clk_ipg);
1033 if (mmc) 1044 if (mmc)
1034 ret = mmc_resume_host(mmc); 1045 ret = mmc_resume_host(mmc);
1035 1046
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 365b16c230f..ebbe984e5d0 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -71,6 +71,9 @@ struct pltfm_imx_data {
71 enum imx_esdhc_type devtype; 71 enum imx_esdhc_type devtype;
72 struct pinctrl *pinctrl; 72 struct pinctrl *pinctrl;
73 struct esdhc_platform_data boarddata; 73 struct esdhc_platform_data boarddata;
74 struct clk *clk_ipg;
75 struct clk *clk_ahb;
76 struct clk *clk_per;
74}; 77};
75 78
76static struct platform_device_id imx_esdhc_devtype[] = { 79static struct platform_device_id imx_esdhc_devtype[] = {
@@ -439,7 +442,6 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
439 struct sdhci_pltfm_host *pltfm_host; 442 struct sdhci_pltfm_host *pltfm_host;
440 struct sdhci_host *host; 443 struct sdhci_host *host;
441 struct esdhc_platform_data *boarddata; 444 struct esdhc_platform_data *boarddata;
442 struct clk *clk;
443 int err; 445 int err;
444 struct pltfm_imx_data *imx_data; 446 struct pltfm_imx_data *imx_data;
445 447
@@ -460,14 +462,29 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
460 imx_data->devtype = pdev->id_entry->driver_data; 462 imx_data->devtype = pdev->id_entry->driver_data;
461 pltfm_host->priv = imx_data; 463 pltfm_host->priv = imx_data;
462 464
463 clk = clk_get(mmc_dev(host->mmc), NULL); 465 imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
464 if (IS_ERR(clk)) { 466 if (IS_ERR(imx_data->clk_ipg)) {
465 dev_err(mmc_dev(host->mmc), "clk err\n"); 467 err = PTR_ERR(imx_data->clk_ipg);
466 err = PTR_ERR(clk);
467 goto err_clk_get; 468 goto err_clk_get;
468 } 469 }
469 clk_prepare_enable(clk); 470
470 pltfm_host->clk = clk; 471 imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
472 if (IS_ERR(imx_data->clk_ahb)) {
473 err = PTR_ERR(imx_data->clk_ahb);
474 goto err_clk_get;
475 }
476
477 imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
478 if (IS_ERR(imx_data->clk_per)) {
479 err = PTR_ERR(imx_data->clk_per);
480 goto err_clk_get;
481 }
482
483 pltfm_host->clk = imx_data->clk_per;
484
485 clk_prepare_enable(imx_data->clk_per);
486 clk_prepare_enable(imx_data->clk_ipg);
487 clk_prepare_enable(imx_data->clk_ahb);
471 488
472 imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 489 imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
473 if (IS_ERR(imx_data->pinctrl)) { 490 if (IS_ERR(imx_data->pinctrl)) {
@@ -567,8 +584,9 @@ no_card_detect_irq:
567no_card_detect_pin: 584no_card_detect_pin:
568no_board_data: 585no_board_data:
569pin_err: 586pin_err:
570 clk_disable_unprepare(pltfm_host->clk); 587 clk_disable_unprepare(imx_data->clk_per);
571 clk_put(pltfm_host->clk); 588 clk_disable_unprepare(imx_data->clk_ipg);
589 clk_disable_unprepare(imx_data->clk_ahb);
572err_clk_get: 590err_clk_get:
573 kfree(imx_data); 591 kfree(imx_data);
574err_imx_data: 592err_imx_data:
@@ -594,8 +612,10 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
594 gpio_free(boarddata->cd_gpio); 612 gpio_free(boarddata->cd_gpio);
595 } 613 }
596 614
597 clk_disable_unprepare(pltfm_host->clk); 615 clk_disable_unprepare(imx_data->clk_per);
598 clk_put(pltfm_host->clk); 616 clk_disable_unprepare(imx_data->clk_ipg);
617 clk_disable_unprepare(imx_data->clk_ahb);
618
599 kfree(imx_data); 619 kfree(imx_data);
600 620
601 sdhci_pltfm_free(pdev); 621 sdhci_pltfm_free(pdev);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index cc0678a967c..9e374e9bd29 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -690,7 +690,7 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
690 if (chip == -1) { 690 if (chip == -1) {
691 /* Disable the NFC clock */ 691 /* Disable the NFC clock */
692 if (host->clk_act) { 692 if (host->clk_act) {
693 clk_disable(host->clk); 693 clk_disable_unprepare(host->clk);
694 host->clk_act = 0; 694 host->clk_act = 0;
695 } 695 }
696 return; 696 return;
@@ -698,7 +698,7 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
698 698
699 if (!host->clk_act) { 699 if (!host->clk_act) {
700 /* Enable the NFC clock */ 700 /* Enable the NFC clock */
701 clk_enable(host->clk); 701 clk_prepare_enable(host->clk);
702 host->clk_act = 1; 702 host->clk_act = 1;
703 } 703 }
704 704
@@ -1078,7 +1078,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
1078 goto eclk; 1078 goto eclk;
1079 } 1079 }
1080 1080
1081 clk_enable(host->clk); 1081 clk_prepare_enable(host->clk);
1082 host->clk_act = 1; 1082 host->clk_act = 1;
1083 1083
1084 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1084 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 0f50ef38b87..513dc88a05c 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -17,6 +17,8 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20#include <linux/clk.h>
21#include <linux/err.h>
20#include <asm/io.h> 22#include <asm/io.h>
21#include <asm/sizes.h> 23#include <asm/sizes.h>
22#include <mach/hardware.h> 24#include <mach/hardware.h>
@@ -79,6 +81,7 @@ static int __init orion_nand_probe(struct platform_device *pdev)
79 struct nand_chip *nc; 81 struct nand_chip *nc;
80 struct orion_nand_data *board; 82 struct orion_nand_data *board;
81 struct resource *res; 83 struct resource *res;
84 struct clk *clk;
82 void __iomem *io_base; 85 void __iomem *io_base;
83 int ret = 0; 86 int ret = 0;
84 u32 val = 0; 87 u32 val = 0;
@@ -155,6 +158,14 @@ static int __init orion_nand_probe(struct platform_device *pdev)
155 158
156 platform_set_drvdata(pdev, mtd); 159 platform_set_drvdata(pdev, mtd);
157 160
161 /* Not all platforms can gate the clock, so it is not
162 an error if the clock does not exists. */
163 clk = clk_get(&pdev->dev, NULL);
164 if (!IS_ERR(clk)) {
165 clk_prepare_enable(clk);
166 clk_put(clk);
167 }
168
158 if (nand_scan(mtd, 1)) { 169 if (nand_scan(mtd, 1)) {
159 ret = -ENXIO; 170 ret = -ENXIO;
160 goto no_dev; 171 goto no_dev;
@@ -184,6 +195,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
184{ 195{
185 struct mtd_info *mtd = platform_get_drvdata(pdev); 196 struct mtd_info *mtd = platform_get_drvdata(pdev);
186 struct nand_chip *nc = mtd->priv; 197 struct nand_chip *nc = mtd->priv;
198 struct clk *clk;
187 199
188 nand_release(mtd); 200 nand_release(mtd);
189 201
@@ -191,6 +203,12 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
191 203
192 kfree(nc); 204 kfree(nc);
193 205
206 clk = clk_get(&pdev->dev, NULL);
207 if (!IS_ERR(clk)) {
208 clk_disable_unprepare(clk);
209 clk_put(clk);
210 }
211
194 return 0; 212 return 0;
195} 213}
196 214
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 8f2cf8c09e2..ff7f4c5115a 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -207,7 +207,8 @@ struct fec_enet_private {
207 207
208 struct net_device *netdev; 208 struct net_device *netdev;
209 209
210 struct clk *clk; 210 struct clk *clk_ipg;
211 struct clk *clk_ahb;
211 212
212 /* The saved address of a sent-in-place packet/buffer, for skfree(). */ 213 /* The saved address of a sent-in-place packet/buffer, for skfree(). */
213 unsigned char *tx_bounce[TX_RING_SIZE]; 214 unsigned char *tx_bounce[TX_RING_SIZE];
@@ -1065,7 +1066,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
1065 * Reference Manual has an error on this, and gets fixed on i.MX6Q 1066 * Reference Manual has an error on this, and gets fixed on i.MX6Q
1066 * document. 1067 * document.
1067 */ 1068 */
1068 fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000); 1069 fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
1069 if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) 1070 if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
1070 fep->phy_speed--; 1071 fep->phy_speed--;
1071 fep->phy_speed <<= 1; 1072 fep->phy_speed <<= 1;
@@ -1618,12 +1619,20 @@ fec_probe(struct platform_device *pdev)
1618 goto failed_pin; 1619 goto failed_pin;
1619 } 1620 }
1620 1621
1621 fep->clk = clk_get(&pdev->dev, NULL); 1622 fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1622 if (IS_ERR(fep->clk)) { 1623 if (IS_ERR(fep->clk_ipg)) {
1623 ret = PTR_ERR(fep->clk); 1624 ret = PTR_ERR(fep->clk_ipg);
1624 goto failed_clk; 1625 goto failed_clk;
1625 } 1626 }
1626 clk_prepare_enable(fep->clk); 1627
1628 fep->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
1629 if (IS_ERR(fep->clk_ahb)) {
1630 ret = PTR_ERR(fep->clk_ahb);
1631 goto failed_clk;
1632 }
1633
1634 clk_prepare_enable(fep->clk_ahb);
1635 clk_prepare_enable(fep->clk_ipg);
1627 1636
1628 ret = fec_enet_init(ndev); 1637 ret = fec_enet_init(ndev);
1629 if (ret) 1638 if (ret)
@@ -1646,8 +1655,8 @@ failed_register:
1646 fec_enet_mii_remove(fep); 1655 fec_enet_mii_remove(fep);
1647failed_mii_init: 1656failed_mii_init:
1648failed_init: 1657failed_init:
1649 clk_disable_unprepare(fep->clk); 1658 clk_disable_unprepare(fep->clk_ahb);
1650 clk_put(fep->clk); 1659 clk_disable_unprepare(fep->clk_ipg);
1651failed_pin: 1660failed_pin:
1652failed_clk: 1661failed_clk:
1653 for (i = 0; i < FEC_IRQ_NUM; i++) { 1662 for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1680,8 +1689,8 @@ fec_drv_remove(struct platform_device *pdev)
1680 if (irq > 0) 1689 if (irq > 0)
1681 free_irq(irq, ndev); 1690 free_irq(irq, ndev);
1682 } 1691 }
1683 clk_disable_unprepare(fep->clk); 1692 clk_disable_unprepare(fep->clk_ahb);
1684 clk_put(fep->clk); 1693 clk_disable_unprepare(fep->clk_ipg);
1685 iounmap(fep->hwp); 1694 iounmap(fep->hwp);
1686 free_netdev(ndev); 1695 free_netdev(ndev);
1687 1696
@@ -1705,7 +1714,8 @@ fec_suspend(struct device *dev)
1705 fec_stop(ndev); 1714 fec_stop(ndev);
1706 netif_device_detach(ndev); 1715 netif_device_detach(ndev);
1707 } 1716 }
1708 clk_disable_unprepare(fep->clk); 1717 clk_disable_unprepare(fep->clk_ahb);
1718 clk_disable_unprepare(fep->clk_ipg);
1709 1719
1710 return 0; 1720 return 0;
1711} 1721}
@@ -1716,7 +1726,8 @@ fec_resume(struct device *dev)
1716 struct net_device *ndev = dev_get_drvdata(dev); 1726 struct net_device *ndev = dev_get_drvdata(dev);
1717 struct fec_enet_private *fep = netdev_priv(ndev); 1727 struct fec_enet_private *fep = netdev_priv(ndev);
1718 1728
1719 clk_prepare_enable(fep->clk); 1729 clk_prepare_enable(fep->clk_ahb);
1730 clk_prepare_enable(fep->clk_ipg);
1720 if (netif_running(ndev)) { 1731 if (netif_running(ndev)) {
1721 fec_restart(ndev, fep->full_duplex); 1732 fec_restart(ndev, fep->full_duplex);
1722 netif_device_attach(ndev); 1733 netif_device_attach(ndev);
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index c8950da60e6..04d901d0ff6 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -57,6 +57,7 @@
57#include <linux/types.h> 57#include <linux/types.h>
58#include <linux/inet_lro.h> 58#include <linux/inet_lro.h>
59#include <linux/slab.h> 59#include <linux/slab.h>
60#include <linux/clk.h>
60 61
61static char mv643xx_eth_driver_name[] = "mv643xx_eth"; 62static char mv643xx_eth_driver_name[] = "mv643xx_eth";
62static char mv643xx_eth_driver_version[] = "1.4"; 63static char mv643xx_eth_driver_version[] = "1.4";
@@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private {
289 /* 290 /*
290 * Hardware-specific parameters. 291 * Hardware-specific parameters.
291 */ 292 */
292 unsigned int t_clk;
293 int extended_rx_coal_limit; 293 int extended_rx_coal_limit;
294 int tx_bw_control; 294 int tx_bw_control;
295 int tx_csum_limit; 295 int tx_csum_limit;
296
296}; 297};
297 298
298#define TX_BW_CONTROL_ABSENT 0 299#define TX_BW_CONTROL_ABSENT 0
@@ -431,6 +432,12 @@ struct mv643xx_eth_private {
431 int tx_desc_sram_size; 432 int tx_desc_sram_size;
432 int txq_count; 433 int txq_count;
433 struct tx_queue txq[8]; 434 struct tx_queue txq[8];
435
436 /*
437 * Hardware-specific parameters.
438 */
439 struct clk *clk;
440 unsigned int t_clk;
434}; 441};
435 442
436 443
@@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
1010 int mtu; 1017 int mtu;
1011 int bucket_size; 1018 int bucket_size;
1012 1019
1013 token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); 1020 token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000);
1014 if (token_rate > 1023) 1021 if (token_rate > 1023)
1015 token_rate = 1023; 1022 token_rate = 1023;
1016 1023
@@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst)
1042 int token_rate; 1049 int token_rate;
1043 int bucket_size; 1050 int bucket_size;
1044 1051
1045 token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); 1052 token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000);
1046 if (token_rate > 1023) 1053 if (token_rate > 1023)
1047 token_rate = 1023; 1054 token_rate = 1023;
1048 1055
@@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
1309 temp = (val & 0x003fff00) >> 8; 1316 temp = (val & 0x003fff00) >> 8;
1310 1317
1311 temp *= 64000000; 1318 temp *= 64000000;
1312 do_div(temp, mp->shared->t_clk); 1319 do_div(temp, mp->t_clk);
1313 1320
1314 return (unsigned int)temp; 1321 return (unsigned int)temp;
1315} 1322}
@@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
1319 u64 temp; 1326 u64 temp;
1320 u32 val; 1327 u32 val;
1321 1328
1322 temp = (u64)usec * mp->shared->t_clk; 1329 temp = (u64)usec * mp->t_clk;
1323 temp += 31999999; 1330 temp += 31999999;
1324 do_div(temp, 64000000); 1331 do_div(temp, 64000000);
1325 1332
@@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
1345 1352
1346 temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; 1353 temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
1347 temp *= 64000000; 1354 temp *= 64000000;
1348 do_div(temp, mp->shared->t_clk); 1355 do_div(temp, mp->t_clk);
1349 1356
1350 return (unsigned int)temp; 1357 return (unsigned int)temp;
1351} 1358}
@@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
1354{ 1361{
1355 u64 temp; 1362 u64 temp;
1356 1363
1357 temp = (u64)usec * mp->shared->t_clk; 1364 temp = (u64)usec * mp->t_clk;
1358 temp += 31999999; 1365 temp += 31999999;
1359 do_div(temp, 64000000); 1366 do_div(temp, 64000000);
1360 1367
@@ -2663,10 +2670,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2663 if (dram) 2670 if (dram)
2664 mv643xx_eth_conf_mbus_windows(msp, dram); 2671 mv643xx_eth_conf_mbus_windows(msp, dram);
2665 2672
2666 /*
2667 * Detect hardware parameters.
2668 */
2669 msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
2670 msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? 2673 msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
2671 pd->tx_csum_limit : 9 * 1024; 2674 pd->tx_csum_limit : 9 * 1024;
2672 infer_hw_params(msp); 2675 infer_hw_params(msp);
@@ -2891,6 +2894,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
2891 2894
2892 mp->dev = dev; 2895 mp->dev = dev;
2893 2896
2897 /*
2898 * Get the clk rate, if there is one, otherwise use the default.
2899 */
2900 mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0"));
2901 if (!IS_ERR(mp->clk)) {
2902 clk_prepare_enable(mp->clk);
2903 mp->t_clk = clk_get_rate(mp->clk);
2904 } else {
2905 mp->t_clk = 133000000;
2906 printk(KERN_WARNING "Unable to get clock");
2907 }
2908
2894 set_params(mp, pd); 2909 set_params(mp, pd);
2895 netif_set_real_num_tx_queues(dev, mp->txq_count); 2910 netif_set_real_num_tx_queues(dev, mp->txq_count);
2896 netif_set_real_num_rx_queues(dev, mp->rxq_count); 2911 netif_set_real_num_rx_queues(dev, mp->rxq_count);
@@ -2979,6 +2994,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
2979 if (mp->phy != NULL) 2994 if (mp->phy != NULL)
2980 phy_detach(mp->phy); 2995 phy_detach(mp->phy);
2981 cancel_work_sync(&mp->tx_timeout_task); 2996 cancel_work_sync(&mp->tx_timeout_task);
2997
2998 if (!IS_ERR(mp->clk)) {
2999 clk_disable_unprepare(mp->clk);
3000 clk_put(mp->clk);
3001 }
2982 free_netdev(mp->dev); 3002 free_netdev(mp->dev);
2983 3003
2984 platform_set_drvdata(pdev, NULL); 3004 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index d93a9608b1f..891cd6c61d0 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -405,7 +405,7 @@ static int dryice_rtc_probe(struct platform_device *pdev)
405 imxdi->clk = clk_get(&pdev->dev, NULL); 405 imxdi->clk = clk_get(&pdev->dev, NULL);
406 if (IS_ERR(imxdi->clk)) 406 if (IS_ERR(imxdi->clk))
407 return PTR_ERR(imxdi->clk); 407 return PTR_ERR(imxdi->clk);
408 clk_enable(imxdi->clk); 408 clk_prepare_enable(imxdi->clk);
409 409
410 /* 410 /*
411 * Initialize dryice hardware 411 * Initialize dryice hardware
@@ -470,7 +470,7 @@ static int dryice_rtc_probe(struct platform_device *pdev)
470 return 0; 470 return 0;
471 471
472err: 472err:
473 clk_disable(imxdi->clk); 473 clk_disable_unprepare(imxdi->clk);
474 clk_put(imxdi->clk); 474 clk_put(imxdi->clk);
475 475
476 return rc; 476 return rc;
@@ -487,7 +487,7 @@ static int __devexit dryice_rtc_remove(struct platform_device *pdev)
487 487
488 rtc_device_unregister(imxdi->rtc); 488 rtc_device_unregister(imxdi->rtc);
489 489
490 clk_disable(imxdi->clk); 490 clk_disable_unprepare(imxdi->clk);
491 clk_put(imxdi->clk); 491 clk_put(imxdi->clk);
492 492
493 return 0; 493 return 0;
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 69c9a6601f4..47877d68761 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -86,7 +86,8 @@ struct spi_imx_data {
86 struct completion xfer_done; 86 struct completion xfer_done;
87 void __iomem *base; 87 void __iomem *base;
88 int irq; 88 int irq;
89 struct clk *clk; 89 struct clk *clk_per;
90 struct clk *clk_ipg;
90 unsigned long spi_clk; 91 unsigned long spi_clk;
91 92
92 unsigned int count; 93 unsigned int count;
@@ -853,15 +854,22 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
853 goto out_free_irq; 854 goto out_free_irq;
854 } 855 }
855 856
856 spi_imx->clk = clk_get(&pdev->dev, NULL); 857 spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
857 if (IS_ERR(spi_imx->clk)) { 858 if (IS_ERR(spi_imx->clk_ipg)) {
858 dev_err(&pdev->dev, "unable to get clock\n"); 859 ret = PTR_ERR(spi_imx->clk_ipg);
859 ret = PTR_ERR(spi_imx->clk);
860 goto out_free_irq; 860 goto out_free_irq;
861 } 861 }
862 862
863 clk_enable(spi_imx->clk); 863 spi_imx->clk_per = devm_clk_get(&pdev->dev, "per");
864 spi_imx->spi_clk = clk_get_rate(spi_imx->clk); 864 if (IS_ERR(spi_imx->clk_per)) {
865 ret = PTR_ERR(spi_imx->clk_per);
866 goto out_free_irq;
867 }
868
869 clk_prepare_enable(spi_imx->clk_per);
870 clk_prepare_enable(spi_imx->clk_ipg);
871
872 spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per);
865 873
866 spi_imx->devtype_data->reset(spi_imx); 874 spi_imx->devtype_data->reset(spi_imx);
867 875
@@ -879,8 +887,8 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
879 return ret; 887 return ret;
880 888
881out_clk_put: 889out_clk_put:
882 clk_disable(spi_imx->clk); 890 clk_disable_unprepare(spi_imx->clk_per);
883 clk_put(spi_imx->clk); 891 clk_disable_unprepare(spi_imx->clk_ipg);
884out_free_irq: 892out_free_irq:
885 free_irq(spi_imx->irq, spi_imx); 893 free_irq(spi_imx->irq, spi_imx);
886out_iounmap: 894out_iounmap:
@@ -908,8 +916,8 @@ static int __devexit spi_imx_remove(struct platform_device *pdev)
908 spi_bitbang_stop(&spi_imx->bitbang); 916 spi_bitbang_stop(&spi_imx->bitbang);
909 917
910 writel(0, spi_imx->base + MXC_CSPICTRL); 918 writel(0, spi_imx->base + MXC_CSPICTRL);
911 clk_disable(spi_imx->clk); 919 clk_disable_unprepare(spi_imx->clk_per);
912 clk_put(spi_imx->clk); 920 clk_disable_unprepare(spi_imx->clk_ipg);
913 free_irq(spi_imx->irq, spi_imx); 921 free_irq(spi_imx->irq, spi_imx);
914 iounmap(spi_imx->base); 922 iounmap(spi_imx->base);
915 923
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index e496f799b7a..dfd04e91fa6 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -16,8 +16,8 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/spi/orion_spi.h>
20#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/clk.h>
21#include <asm/unaligned.h> 21#include <asm/unaligned.h>
22 22
23#define DRIVER_NAME "orion_spi" 23#define DRIVER_NAME "orion_spi"
@@ -46,6 +46,7 @@ struct orion_spi {
46 unsigned int max_speed; 46 unsigned int max_speed;
47 unsigned int min_speed; 47 unsigned int min_speed;
48 struct orion_spi_info *spi_info; 48 struct orion_spi_info *spi_info;
49 struct clk *clk;
49}; 50};
50 51
51static struct workqueue_struct *orion_spi_wq; 52static struct workqueue_struct *orion_spi_wq;
@@ -104,7 +105,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
104 105
105 orion_spi = spi_master_get_devdata(spi->master); 106 orion_spi = spi_master_get_devdata(spi->master);
106 107
107 tclk_hz = orion_spi->spi_info->tclk; 108 tclk_hz = clk_get_rate(orion_spi->clk);
108 109
109 /* 110 /*
110 * the supported rates are: 4,6,8...30 111 * the supported rates are: 4,6,8...30
@@ -450,6 +451,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
450 struct orion_spi *spi; 451 struct orion_spi *spi;
451 struct resource *r; 452 struct resource *r;
452 struct orion_spi_info *spi_info; 453 struct orion_spi_info *spi_info;
454 unsigned long tclk_hz;
453 int status = 0; 455 int status = 0;
454 456
455 spi_info = pdev->dev.platform_data; 457 spi_info = pdev->dev.platform_data;
@@ -476,19 +478,28 @@ static int __init orion_spi_probe(struct platform_device *pdev)
476 spi->master = master; 478 spi->master = master;
477 spi->spi_info = spi_info; 479 spi->spi_info = spi_info;
478 480
479 spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4); 481 spi->clk = clk_get(&pdev->dev, NULL);
480 spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30); 482 if (IS_ERR(spi->clk)) {
483 status = PTR_ERR(spi->clk);
484 goto out;
485 }
486
487 clk_prepare(spi->clk);
488 clk_enable(spi->clk);
489 tclk_hz = clk_get_rate(spi->clk);
490 spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
491 spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
481 492
482 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 493 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
483 if (r == NULL) { 494 if (r == NULL) {
484 status = -ENODEV; 495 status = -ENODEV;
485 goto out; 496 goto out_rel_clk;
486 } 497 }
487 498
488 if (!request_mem_region(r->start, resource_size(r), 499 if (!request_mem_region(r->start, resource_size(r),
489 dev_name(&pdev->dev))) { 500 dev_name(&pdev->dev))) {
490 status = -EBUSY; 501 status = -EBUSY;
491 goto out; 502 goto out_rel_clk;
492 } 503 }
493 spi->base = ioremap(r->start, SZ_1K); 504 spi->base = ioremap(r->start, SZ_1K);
494 505
@@ -508,7 +519,9 @@ static int __init orion_spi_probe(struct platform_device *pdev)
508 519
509out_rel_mem: 520out_rel_mem:
510 release_mem_region(r->start, resource_size(r)); 521 release_mem_region(r->start, resource_size(r));
511 522out_rel_clk:
523 clk_disable_unprepare(spi->clk);
524 clk_put(spi->clk);
512out: 525out:
513 spi_master_put(master); 526 spi_master_put(master);
514 return status; 527 return status;
@@ -526,6 +539,9 @@ static int __exit orion_spi_remove(struct platform_device *pdev)
526 539
527 cancel_work_sync(&spi->work); 540 cancel_work_sync(&spi->work);
528 541
542 clk_disable_unprepare(spi->clk);
543 clk_put(spi->clk);
544
529 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 545 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
530 release_mem_region(r->start, resource_size(r)); 546 release_mem_region(r->start, resource_size(r));
531 547
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index ec206732f68..4ef747307ec 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -205,7 +205,8 @@ struct imx_port {
205 unsigned int irda_inv_rx:1; 205 unsigned int irda_inv_rx:1;
206 unsigned int irda_inv_tx:1; 206 unsigned int irda_inv_tx:1;
207 unsigned short trcv_delay; /* transceiver delay */ 207 unsigned short trcv_delay; /* transceiver delay */
208 struct clk *clk; 208 struct clk *clk_ipg;
209 struct clk *clk_per;
209 struct imx_uart_data *devdata; 210 struct imx_uart_data *devdata;
210}; 211};
211 212
@@ -673,7 +674,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
673 * RFDIV is set such way to satisfy requested uartclk value 674 * RFDIV is set such way to satisfy requested uartclk value
674 */ 675 */
675 val = TXTL << 10 | RXTL; 676 val = TXTL << 10 | RXTL;
676 ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2) 677 ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2)
677 / sport->port.uartclk; 678 / sport->port.uartclk;
678 679
679 if(!ufcr_rfdiv) 680 if(!ufcr_rfdiv)
@@ -1286,7 +1287,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
1286 else 1287 else
1287 ucfr_rfdiv = 6 - ucfr_rfdiv; 1288 ucfr_rfdiv = 6 - ucfr_rfdiv;
1288 1289
1289 uartclk = clk_get_rate(sport->clk); 1290 uartclk = clk_get_rate(sport->clk_per);
1290 uartclk /= ucfr_rfdiv; 1291 uartclk /= ucfr_rfdiv;
1291 1292
1292 { /* 1293 { /*
@@ -1511,14 +1512,22 @@ static int serial_imx_probe(struct platform_device *pdev)
1511 goto unmap; 1512 goto unmap;
1512 } 1513 }
1513 1514
1514 sport->clk = clk_get(&pdev->dev, "uart"); 1515 sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1515 if (IS_ERR(sport->clk)) { 1516 if (IS_ERR(sport->clk_ipg)) {
1516 ret = PTR_ERR(sport->clk); 1517 ret = PTR_ERR(sport->clk_ipg);
1517 goto unmap; 1518 goto unmap;
1518 } 1519 }
1519 clk_prepare_enable(sport->clk);
1520 1520
1521 sport->port.uartclk = clk_get_rate(sport->clk); 1521 sport->clk_per = devm_clk_get(&pdev->dev, "per");
1522 if (IS_ERR(sport->clk_per)) {
1523 ret = PTR_ERR(sport->clk_per);
1524 goto unmap;
1525 }
1526
1527 clk_prepare_enable(sport->clk_per);
1528 clk_prepare_enable(sport->clk_ipg);
1529
1530 sport->port.uartclk = clk_get_rate(sport->clk_per);
1522 1531
1523 imx_ports[sport->port.line] = sport; 1532 imx_ports[sport->port.line] = sport;
1524 1533
@@ -1539,8 +1548,8 @@ deinit:
1539 if (pdata && pdata->exit) 1548 if (pdata && pdata->exit)
1540 pdata->exit(pdev); 1549 pdata->exit(pdev);
1541clkput: 1550clkput:
1542 clk_disable_unprepare(sport->clk); 1551 clk_disable_unprepare(sport->clk_per);
1543 clk_put(sport->clk); 1552 clk_disable_unprepare(sport->clk_ipg);
1544unmap: 1553unmap:
1545 iounmap(sport->port.membase); 1554 iounmap(sport->port.membase);
1546free: 1555free:
@@ -1558,11 +1567,10 @@ static int serial_imx_remove(struct platform_device *pdev)
1558 1567
1559 platform_set_drvdata(pdev, NULL); 1568 platform_set_drvdata(pdev, NULL);
1560 1569
1561 if (sport) { 1570 uart_remove_one_port(&imx_reg, &sport->port);
1562 uart_remove_one_port(&imx_reg, &sport->port); 1571
1563 clk_disable_unprepare(sport->clk); 1572 clk_disable_unprepare(sport->clk_per);
1564 clk_put(sport->clk); 1573 clk_disable_unprepare(sport->clk_ipg);
1565 }
1566 1574
1567 if (pdata && pdata->exit) 1575 if (pdata && pdata->exit)
1568 pdata->exit(pdev); 1576 pdata->exit(pdev);
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index a797d51ecbe..c778ffe4e4e 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -32,7 +32,7 @@
32#define ULPI_VIEWPORT_OFFSET 0x170 32#define ULPI_VIEWPORT_OFFSET 0x170
33 33
34struct ehci_mxc_priv { 34struct ehci_mxc_priv {
35 struct clk *usbclk, *ahbclk, *phy1clk; 35 struct clk *usbclk, *ahbclk, *phyclk;
36 struct usb_hcd *hcd; 36 struct usb_hcd *hcd;
37}; 37};
38 38
@@ -166,31 +166,26 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
166 } 166 }
167 167
168 /* enable clocks */ 168 /* enable clocks */
169 priv->usbclk = clk_get(dev, "usb"); 169 priv->usbclk = clk_get(dev, "ipg");
170 if (IS_ERR(priv->usbclk)) { 170 if (IS_ERR(priv->usbclk)) {
171 ret = PTR_ERR(priv->usbclk); 171 ret = PTR_ERR(priv->usbclk);
172 goto err_clk; 172 goto err_clk;
173 } 173 }
174 clk_enable(priv->usbclk); 174 clk_prepare_enable(priv->usbclk);
175 175
176 if (!cpu_is_mx35() && !cpu_is_mx25()) { 176 priv->ahbclk = clk_get(dev, "ahb");
177 priv->ahbclk = clk_get(dev, "usb_ahb"); 177 if (IS_ERR(priv->ahbclk)) {
178 if (IS_ERR(priv->ahbclk)) { 178 ret = PTR_ERR(priv->ahbclk);
179 ret = PTR_ERR(priv->ahbclk); 179 goto err_clk_ahb;
180 goto err_clk_ahb;
181 }
182 clk_enable(priv->ahbclk);
183 } 180 }
181 clk_prepare_enable(priv->ahbclk);
184 182
185 /* "dr" device has its own clock on i.MX51 */ 183 /* "dr" device has its own clock on i.MX51 */
186 if (cpu_is_mx51() && (pdev->id == 0)) { 184 priv->phyclk = clk_get(dev, "phy");
187 priv->phy1clk = clk_get(dev, "usb_phy1"); 185 if (IS_ERR(priv->phyclk))
188 if (IS_ERR(priv->phy1clk)) { 186 priv->phyclk = NULL;
189 ret = PTR_ERR(priv->phy1clk); 187 if (priv->phyclk)
190 goto err_clk_phy; 188 clk_prepare_enable(priv->phyclk);
191 }
192 clk_enable(priv->phy1clk);
193 }
194 189
195 190
196 /* call platform specific init function */ 191 /* call platform specific init function */
@@ -265,17 +260,15 @@ err_add:
265 if (pdata && pdata->exit) 260 if (pdata && pdata->exit)
266 pdata->exit(pdev); 261 pdata->exit(pdev);
267err_init: 262err_init:
268 if (priv->phy1clk) { 263 if (priv->phyclk) {
269 clk_disable(priv->phy1clk); 264 clk_disable_unprepare(priv->phyclk);
270 clk_put(priv->phy1clk); 265 clk_put(priv->phyclk);
271 }
272err_clk_phy:
273 if (priv->ahbclk) {
274 clk_disable(priv->ahbclk);
275 clk_put(priv->ahbclk);
276 } 266 }
267
268 clk_disable_unprepare(priv->ahbclk);
269 clk_put(priv->ahbclk);
277err_clk_ahb: 270err_clk_ahb:
278 clk_disable(priv->usbclk); 271 clk_disable_unprepare(priv->usbclk);
279 clk_put(priv->usbclk); 272 clk_put(priv->usbclk);
280err_clk: 273err_clk:
281 iounmap(hcd->regs); 274 iounmap(hcd->regs);
@@ -307,15 +300,14 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
307 usb_put_hcd(hcd); 300 usb_put_hcd(hcd);
308 platform_set_drvdata(pdev, NULL); 301 platform_set_drvdata(pdev, NULL);
309 302
310 clk_disable(priv->usbclk); 303 clk_disable_unprepare(priv->usbclk);
311 clk_put(priv->usbclk); 304 clk_put(priv->usbclk);
312 if (priv->ahbclk) { 305 clk_disable_unprepare(priv->ahbclk);
313 clk_disable(priv->ahbclk); 306 clk_put(priv->ahbclk);
314 clk_put(priv->ahbclk); 307
315 } 308 if (priv->phyclk) {
316 if (priv->phy1clk) { 309 clk_disable_unprepare(priv->phyclk);
317 clk_disable(priv->phy1clk); 310 clk_put(priv->phyclk);
318 clk_put(priv->phy1clk);
319 } 311 }
320 312
321 kfree(priv); 313 kfree(priv);
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 6c6a5a3b4ea..82de1073aa5 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/mbus.h> 14#include <linux/mbus.h>
15#include <linux/clk.h>
15#include <plat/ehci-orion.h> 16#include <plat/ehci-orion.h>
16 17
17#define rdl(off) __raw_readl(hcd->regs + (off)) 18#define rdl(off) __raw_readl(hcd->regs + (off))
@@ -198,6 +199,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
198 struct resource *res; 199 struct resource *res;
199 struct usb_hcd *hcd; 200 struct usb_hcd *hcd;
200 struct ehci_hcd *ehci; 201 struct ehci_hcd *ehci;
202 struct clk *clk;
201 void __iomem *regs; 203 void __iomem *regs;
202 int irq, err; 204 int irq, err;
203 205
@@ -238,6 +240,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
238 goto err2; 240 goto err2;
239 } 241 }
240 242
243 /* Not all platforms can gate the clock, so it is not
244 an error if the clock does not exists. */
245 clk = clk_get(&pdev->dev, NULL);
246 if (!IS_ERR(clk)) {
247 clk_prepare_enable(clk);
248 clk_put(clk);
249 }
250
241 hcd = usb_create_hcd(&ehci_orion_hc_driver, 251 hcd = usb_create_hcd(&ehci_orion_hc_driver,
242 &pdev->dev, dev_name(&pdev->dev)); 252 &pdev->dev, dev_name(&pdev->dev));
243 if (!hcd) { 253 if (!hcd) {
@@ -301,12 +311,18 @@ err1:
301static int __exit ehci_orion_drv_remove(struct platform_device *pdev) 311static int __exit ehci_orion_drv_remove(struct platform_device *pdev)
302{ 312{
303 struct usb_hcd *hcd = platform_get_drvdata(pdev); 313 struct usb_hcd *hcd = platform_get_drvdata(pdev);
314 struct clk *clk;
304 315
305 usb_remove_hcd(hcd); 316 usb_remove_hcd(hcd);
306 iounmap(hcd->regs); 317 iounmap(hcd->regs);
307 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 318 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
308 usb_put_hcd(hcd); 319 usb_put_hcd(hcd);
309 320
321 clk = clk_get(&pdev->dev, NULL);
322 if (!IS_ERR(clk)) {
323 clk_disable_unprepare(clk);
324 clk_put(clk);
325 }
310 return 0; 326 return 0;
311} 327}
312 328
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index f135dbead07..caad3689b4e 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -131,7 +131,9 @@ struct imxfb_rgb {
131struct imxfb_info { 131struct imxfb_info {
132 struct platform_device *pdev; 132 struct platform_device *pdev;
133 void __iomem *regs; 133 void __iomem *regs;
134 struct clk *clk; 134 struct clk *clk_ipg;
135 struct clk *clk_ahb;
136 struct clk *clk_per;
135 137
136 /* 138 /*
137 * These are the addresses we mapped 139 * These are the addresses we mapped
@@ -340,7 +342,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
340 342
341 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); 343 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
342 344
343 lcd_clk = clk_get_rate(fbi->clk); 345 lcd_clk = clk_get_rate(fbi->clk_per);
344 346
345 tmp = var->pixclock * (unsigned long long)lcd_clk; 347 tmp = var->pixclock * (unsigned long long)lcd_clk;
346 348
@@ -455,11 +457,17 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
455 457
456 fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness; 458 fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
457 459
458 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 460 if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
459 clk_enable(fbi->clk); 461 clk_prepare_enable(fbi->clk_ipg);
462 clk_prepare_enable(fbi->clk_ahb);
463 clk_prepare_enable(fbi->clk_per);
464 }
460 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 465 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
461 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 466 if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
462 clk_disable(fbi->clk); 467 clk_disable_unprepare(fbi->clk_per);
468 clk_disable_unprepare(fbi->clk_ahb);
469 clk_disable_unprepare(fbi->clk_ipg);
470 }
463 471
464 return 0; 472 return 0;
465} 473}
@@ -522,7 +530,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
522 */ 530 */
523 writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR); 531 writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
524 532
525 clk_enable(fbi->clk); 533 clk_prepare_enable(fbi->clk_ipg);
534 clk_prepare_enable(fbi->clk_ahb);
535 clk_prepare_enable(fbi->clk_per);
526 536
527 if (fbi->backlight_power) 537 if (fbi->backlight_power)
528 fbi->backlight_power(1); 538 fbi->backlight_power(1);
@@ -539,7 +549,9 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
539 if (fbi->lcd_power) 549 if (fbi->lcd_power)
540 fbi->lcd_power(0); 550 fbi->lcd_power(0);
541 551
542 clk_disable(fbi->clk); 552 clk_disable_unprepare(fbi->clk_per);
553 clk_disable_unprepare(fbi->clk_ipg);
554 clk_disable_unprepare(fbi->clk_ahb);
543 555
544 writel(0, fbi->regs + LCDC_RMCR); 556 writel(0, fbi->regs + LCDC_RMCR);
545} 557}
@@ -770,10 +782,21 @@ static int __init imxfb_probe(struct platform_device *pdev)
770 goto failed_req; 782 goto failed_req;
771 } 783 }
772 784
773 fbi->clk = clk_get(&pdev->dev, NULL); 785 fbi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
774 if (IS_ERR(fbi->clk)) { 786 if (IS_ERR(fbi->clk_ipg)) {
775 ret = PTR_ERR(fbi->clk); 787 ret = PTR_ERR(fbi->clk_ipg);
776 dev_err(&pdev->dev, "unable to get clock: %d\n", ret); 788 goto failed_getclock;
789 }
790
791 fbi->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
792 if (IS_ERR(fbi->clk_ahb)) {
793 ret = PTR_ERR(fbi->clk_ahb);
794 goto failed_getclock;
795 }
796
797 fbi->clk_per = devm_clk_get(&pdev->dev, "per");
798 if (IS_ERR(fbi->clk_per)) {
799 ret = PTR_ERR(fbi->clk_per);
777 goto failed_getclock; 800 goto failed_getclock;
778 } 801 }
779 802
@@ -858,7 +881,6 @@ failed_platform_init:
858failed_map: 881failed_map:
859 iounmap(fbi->regs); 882 iounmap(fbi->regs);
860failed_ioremap: 883failed_ioremap:
861 clk_put(fbi->clk);
862failed_getclock: 884failed_getclock:
863 release_mem_region(res->start, resource_size(res)); 885 release_mem_region(res->start, resource_size(res));
864failed_req: 886failed_req:
@@ -895,8 +917,6 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
895 917
896 iounmap(fbi->regs); 918 iounmap(fbi->regs);
897 release_mem_region(res->start, resource_size(res)); 919 release_mem_region(res->start, resource_size(res));
898 clk_disable(fbi->clk);
899 clk_put(fbi->clk);
900 920
901 platform_set_drvdata(pdev, NULL); 921 platform_set_drvdata(pdev, NULL);
902 922
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index a3b6a74c67a..1cc61a700fa 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -138,7 +138,7 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev)
138 goto failed_ioremap; 138 goto failed_ioremap;
139 } 139 }
140 140
141 clk_enable(mdev->clk); 141 clk_prepare_enable(mdev->clk);
142 __raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER); 142 __raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER);
143 143
144 mdev->bus_master.data = mdev; 144 mdev->bus_master.data = mdev;
@@ -178,7 +178,7 @@ static int __devexit mxc_w1_remove(struct platform_device *pdev)
178 178
179 iounmap(mdev->regs); 179 iounmap(mdev->regs);
180 release_mem_region(res->start, resource_size(res)); 180 release_mem_region(res->start, resource_size(res));
181 clk_disable(mdev->clk); 181 clk_disable_unprepare(mdev->clk);
182 clk_put(mdev->clk); 182 clk_put(mdev->clk);
183 183
184 platform_set_drvdata(pdev, NULL); 184 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 7a2b734fcdc..bcfab2b00ad 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -121,7 +121,7 @@ static void imx2_wdt_start(void)
121{ 121{
122 if (!test_and_set_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) { 122 if (!test_and_set_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) {
123 /* at our first start we enable clock and do initialisations */ 123 /* at our first start we enable clock and do initialisations */
124 clk_enable(imx2_wdt.clk); 124 clk_prepare_enable(imx2_wdt.clk);
125 125
126 imx2_wdt_setup(); 126 imx2_wdt_setup();
127 } else /* delete the timer that pings the watchdog after close */ 127 } else /* delete the timer that pings the watchdog after close */
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 788aa158e78..0f5736949c6 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -24,8 +24,8 @@
24#include <linux/uaccess.h> 24#include <linux/uaccess.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/clk.h>
27#include <mach/bridge-regs.h> 28#include <mach/bridge-regs.h>
28#include <plat/orion_wdt.h>
29 29
30/* 30/*
31 * Watchdog timer block registers. 31 * Watchdog timer block registers.
@@ -41,6 +41,7 @@
41static bool nowayout = WATCHDOG_NOWAYOUT; 41static bool nowayout = WATCHDOG_NOWAYOUT;
42static int heartbeat = -1; /* module parameter (seconds) */ 42static int heartbeat = -1; /* module parameter (seconds) */
43static unsigned int wdt_max_duration; /* (seconds) */ 43static unsigned int wdt_max_duration; /* (seconds) */
44static struct clk *clk;
44static unsigned int wdt_tclk; 45static unsigned int wdt_tclk;
45static void __iomem *wdt_reg; 46static void __iomem *wdt_reg;
46static unsigned long wdt_status; 47static unsigned long wdt_status;
@@ -237,16 +238,16 @@ static struct miscdevice orion_wdt_miscdev = {
237 238
238static int __devinit orion_wdt_probe(struct platform_device *pdev) 239static int __devinit orion_wdt_probe(struct platform_device *pdev)
239{ 240{
240 struct orion_wdt_platform_data *pdata = pdev->dev.platform_data;
241 struct resource *res; 241 struct resource *res;
242 int ret; 242 int ret;
243 243
244 if (pdata) { 244 clk = clk_get(&pdev->dev, NULL);
245 wdt_tclk = pdata->tclk; 245 if (IS_ERR(clk)) {
246 } else { 246 printk(KERN_ERR "Orion Watchdog missing clock\n");
247 pr_err("misses platform data\n");
248 return -ENODEV; 247 return -ENODEV;
249 } 248 }
249 clk_prepare_enable(clk);
250 wdt_tclk = clk_get_rate(clk);
250 251
251 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 252 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
252 253
@@ -282,6 +283,9 @@ static int __devexit orion_wdt_remove(struct platform_device *pdev)
282 if (!ret) 283 if (!ret)
283 orion_wdt_miscdev.parent = NULL; 284 orion_wdt_miscdev.parent = NULL;
284 285
286 clk_disable_unprepare(clk);
287 clk_put(clk);
288
285 return ret; 289 return ret;
286} 290}
287 291