diff options
author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2014-05-21 07:23:01 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-05-23 18:44:03 -0400 |
commit | e8b60a45a54738243d13aeba230af20a68619b1b (patch) | |
tree | d67f2df3cc56f82f93e448e4f461f8c6153676f6 /drivers/clk/clk-s2mps11.c | |
parent | 7002483c7b28a808d2bd4366b00c48911688c768 (diff) |
clk: s2mps11: Add support for S2MPS14 clocks
This patch adds support for S2MPS14 PMIC clocks (BT and AP) to the
s2mps11 clock driver.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/clk-s2mps11.c')
-rw-r--r-- | drivers/clk/clk-s2mps11.c | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 23ffd89c4023..9b7b5859a420 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * clk-s2mps11.c - Clock driver for S2MPS11. | 2 | * clk-s2mps11.c - Clock driver for S2MPS11. |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electornics | 4 | * Copyright (C) 2013,2014 Samsung Electornics |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -13,10 +13,6 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include <linux/module.h> | 18 | #include <linux/module.h> |
@@ -27,6 +23,7 @@ | |||
27 | #include <linux/clk-provider.h> | 23 | #include <linux/clk-provider.h> |
28 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
29 | #include <linux/mfd/samsung/s2mps11.h> | 25 | #include <linux/mfd/samsung/s2mps11.h> |
26 | #include <linux/mfd/samsung/s2mps14.h> | ||
30 | #include <linux/mfd/samsung/s5m8767.h> | 27 | #include <linux/mfd/samsung/s5m8767.h> |
31 | #include <linux/mfd/samsung/core.h> | 28 | #include <linux/mfd/samsung/core.h> |
32 | 29 | ||
@@ -126,7 +123,21 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { | |||
126 | }, | 123 | }, |
127 | }; | 124 | }; |
128 | 125 | ||
129 | static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) | 126 | static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { |
127 | [S2MPS11_CLK_AP] = { | ||
128 | .name = "s2mps14_ap", | ||
129 | .ops = &s2mps11_clk_ops, | ||
130 | .flags = CLK_IS_ROOT, | ||
131 | }, | ||
132 | [S2MPS11_CLK_BT] = { | ||
133 | .name = "s2mps14_bt", | ||
134 | .ops = &s2mps11_clk_ops, | ||
135 | .flags = CLK_IS_ROOT, | ||
136 | }, | ||
137 | }; | ||
138 | |||
139 | static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, | ||
140 | struct clk_init_data *clks_init) | ||
130 | { | 141 | { |
131 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 142 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
132 | struct device_node *clk_np; | 143 | struct device_node *clk_np; |
@@ -141,9 +152,12 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) | |||
141 | return ERR_PTR(-EINVAL); | 152 | return ERR_PTR(-EINVAL); |
142 | } | 153 | } |
143 | 154 | ||
144 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) | 155 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) { |
156 | if (!clks_init[i].name) | ||
157 | continue; /* Skip clocks not present in some devices */ | ||
145 | of_property_read_string_index(clk_np, "clock-output-names", i, | 158 | of_property_read_string_index(clk_np, "clock-output-names", i, |
146 | &s2mps11_clks_init[i].name); | 159 | &clks_init[i].name); |
160 | } | ||
147 | 161 | ||
148 | return clk_np; | 162 | return clk_np; |
149 | } | 163 | } |
@@ -153,6 +167,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) | |||
153 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 167 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
154 | struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; | 168 | struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; |
155 | unsigned int s2mps11_reg; | 169 | unsigned int s2mps11_reg; |
170 | struct clk_init_data *clks_init; | ||
156 | int i, ret = 0; | 171 | int i, ret = 0; |
157 | u32 val; | 172 | u32 val; |
158 | 173 | ||
@@ -168,26 +183,34 @@ static int s2mps11_clk_probe(struct platform_device *pdev) | |||
168 | if (!clk_table) | 183 | if (!clk_table) |
169 | return -ENOMEM; | 184 | return -ENOMEM; |
170 | 185 | ||
171 | /* Store clocks of_node in first element of s2mps11_clks array */ | ||
172 | s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev); | ||
173 | if (IS_ERR(s2mps11_clks->clk_np)) | ||
174 | return PTR_ERR(s2mps11_clks->clk_np); | ||
175 | |||
176 | switch(platform_get_device_id(pdev)->driver_data) { | 186 | switch(platform_get_device_id(pdev)->driver_data) { |
177 | case S2MPS11X: | 187 | case S2MPS11X: |
178 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; | 188 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; |
189 | clks_init = s2mps11_clks_init; | ||
190 | break; | ||
191 | case S2MPS14X: | ||
192 | s2mps11_reg = S2MPS14_REG_RTCCTRL; | ||
193 | clks_init = s2mps14_clks_init; | ||
179 | break; | 194 | break; |
180 | case S5M8767X: | 195 | case S5M8767X: |
181 | s2mps11_reg = S5M8767_REG_CTRL1; | 196 | s2mps11_reg = S5M8767_REG_CTRL1; |
197 | clks_init = s2mps11_clks_init; | ||
182 | break; | 198 | break; |
183 | default: | 199 | default: |
184 | dev_err(&pdev->dev, "Invalid device type\n"); | 200 | dev_err(&pdev->dev, "Invalid device type\n"); |
185 | return -EINVAL; | 201 | return -EINVAL; |
186 | }; | 202 | }; |
187 | 203 | ||
204 | /* Store clocks of_node in first element of s2mps11_clks array */ | ||
205 | s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); | ||
206 | if (IS_ERR(s2mps11_clks->clk_np)) | ||
207 | return PTR_ERR(s2mps11_clks->clk_np); | ||
208 | |||
188 | for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { | 209 | for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { |
210 | if (!clks_init[i].name) | ||
211 | continue; /* Skip clocks not present in some devices */ | ||
189 | s2mps11_clk->iodev = iodev; | 212 | s2mps11_clk->iodev = iodev; |
190 | s2mps11_clk->hw.init = &s2mps11_clks_init[i]; | 213 | s2mps11_clk->hw.init = &clks_init[i]; |
191 | s2mps11_clk->mask = 1 << i; | 214 | s2mps11_clk->mask = 1 << i; |
192 | s2mps11_clk->reg = s2mps11_reg; | 215 | s2mps11_clk->reg = s2mps11_reg; |
193 | 216 | ||
@@ -220,8 +243,12 @@ static int s2mps11_clk_probe(struct platform_device *pdev) | |||
220 | clkdev_add(s2mps11_clk->lookup); | 243 | clkdev_add(s2mps11_clk->lookup); |
221 | } | 244 | } |
222 | 245 | ||
223 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) | 246 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) { |
247 | /* Skip clocks not present on S2MPS14 */ | ||
248 | if (!clks_init[i].name) | ||
249 | continue; | ||
224 | clk_table[i] = s2mps11_clks[i].clk; | 250 | clk_table[i] = s2mps11_clks[i].clk; |
251 | } | ||
225 | 252 | ||
226 | clk_data.clks = clk_table; | 253 | clk_data.clks = clk_table; |
227 | clk_data.clk_num = S2MPS11_CLKS_NUM; | 254 | clk_data.clk_num = S2MPS11_CLKS_NUM; |
@@ -254,14 +281,19 @@ static int s2mps11_clk_remove(struct platform_device *pdev) | |||
254 | /* Drop the reference obtained in s2mps11_clk_parse_dt */ | 281 | /* Drop the reference obtained in s2mps11_clk_parse_dt */ |
255 | of_node_put(s2mps11_clks[0].clk_np); | 282 | of_node_put(s2mps11_clks[0].clk_np); |
256 | 283 | ||
257 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) | 284 | for (i = 0; i < S2MPS11_CLKS_NUM; i++) { |
285 | /* Skip clocks not present on S2MPS14 */ | ||
286 | if (!s2mps11_clks[i].lookup) | ||
287 | continue; | ||
258 | clkdev_drop(s2mps11_clks[i].lookup); | 288 | clkdev_drop(s2mps11_clks[i].lookup); |
289 | } | ||
259 | 290 | ||
260 | return 0; | 291 | return 0; |
261 | } | 292 | } |
262 | 293 | ||
263 | static const struct platform_device_id s2mps11_clk_id[] = { | 294 | static const struct platform_device_id s2mps11_clk_id[] = { |
264 | { "s2mps11-clk", S2MPS11X}, | 295 | { "s2mps11-clk", S2MPS11X}, |
296 | { "s2mps14-clk", S2MPS14X}, | ||
265 | { "s5m8767-clk", S5M8767X}, | 297 | { "s5m8767-clk", S5M8767X}, |
266 | { }, | 298 | { }, |
267 | }; | 299 | }; |