aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@chromium.org>2013-09-25 17:12:47 -0400
committerTomasz Figa <t.figa@samsung.com>2014-01-08 12:02:41 -0500
commitb37a4224104568198b93fb9831224cfe7d83fff8 (patch)
tree9611f57e12078f03290a45381bc9a1bc4aa5c0d3
parentad3ab455d31da40061c4df32ae5ff11a731f5890 (diff)
clk: exynos-audss: convert to platform device
The Exynos AudioSS clock controller will later be modified to allow input clocks to be specified via device-tree in order to support multiple Exynos SoCs. This will introduce a dependency on the core SoC clock controller being initialized first so that the AudioSS driver can look up its input clocks, but the order in which clock providers are probed in of_clk_init() is not guaranteed. Since deferred probing is not supported in of_clk_init() and the AudioSS block is not the core controller, we can initialize it later as a platform device. Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Acked-by: Tomasz Figa <t.figa@samsung.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Acked-by: Mike Turquette <mturquette@linaro.org> Acked-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c104
1 files changed, 88 insertions, 16 deletions
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 68e515d093d8..1d8f6770ccfe 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -14,6 +14,8 @@
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/syscore_ops.h> 16#include <linux/syscore_ops.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
17 19
18#include <dt-bindings/clk/exynos-audss-clk.h> 20#include <dt-bindings/clk/exynos-audss-clk.h>
19 21
@@ -62,24 +64,26 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = {
62#endif /* CONFIG_PM_SLEEP */ 64#endif /* CONFIG_PM_SLEEP */
63 65
64/* register exynos_audss clocks */ 66/* register exynos_audss clocks */
65static void __init exynos_audss_clk_init(struct device_node *np) 67static int exynos_audss_clk_probe(struct platform_device *pdev)
66{ 68{
67 reg_base = of_iomap(np, 0); 69 int i, ret = 0;
68 if (!reg_base) { 70 struct resource *res;
69 pr_err("%s: failed to map audss registers\n", __func__); 71
70 return; 72 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
73 reg_base = devm_ioremap_resource(&pdev->dev, res);
74 if (IS_ERR(reg_base)) {
75 dev_err(&pdev->dev, "failed to map audss registers\n");
76 return PTR_ERR(reg_base);
71 } 77 }
72 78
73 clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, 79 clk_table = devm_kzalloc(&pdev->dev,
80 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
74 GFP_KERNEL); 81 GFP_KERNEL);
75 if (!clk_table) { 82 if (!clk_table)
76 pr_err("%s: could not allocate clk lookup table\n", __func__); 83 return -ENOMEM;
77 return;
78 }
79 84
80 clk_data.clks = clk_table; 85 clk_data.clks = clk_table;
81 clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS; 86 clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
82 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
83 87
84 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", 88 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
85 mout_audss_p, ARRAY_SIZE(mout_audss_p), 89 mout_audss_p, ARRAY_SIZE(mout_audss_p),
@@ -123,13 +127,81 @@ static void __init exynos_audss_clk_init(struct device_node *np)
123 "div_pcm0", CLK_SET_RATE_PARENT, 127 "div_pcm0", CLK_SET_RATE_PARENT,
124 reg_base + ASS_CLK_GATE, 5, 0, &lock); 128 reg_base + ASS_CLK_GATE, 5, 0, &lock);
125 129
130 for (i = 0; i < clk_data.clk_num; i++) {
131 if (IS_ERR(clk_table[i])) {
132 dev_err(&pdev->dev, "failed to register clock %d\n", i);
133 ret = PTR_ERR(clk_table[i]);
134 goto unregister;
135 }
136 }
137
138 ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
139 &clk_data);
140 if (ret) {
141 dev_err(&pdev->dev, "failed to add clock provider\n");
142 goto unregister;
143 }
144
126#ifdef CONFIG_PM_SLEEP 145#ifdef CONFIG_PM_SLEEP
127 register_syscore_ops(&exynos_audss_clk_syscore_ops); 146 register_syscore_ops(&exynos_audss_clk_syscore_ops);
128#endif 147#endif
129 148
130 pr_info("Exynos: Audss: clock setup completed\n"); 149 dev_info(&pdev->dev, "setup completed\n");
150
151 return 0;
152
153unregister:
154 for (i = 0; i < clk_data.clk_num; i++) {
155 if (!IS_ERR(clk_table[i]))
156 clk_unregister(clk_table[i]);
157 }
158
159 return ret;
160}
161
162static int exynos_audss_clk_remove(struct platform_device *pdev)
163{
164 int i;
165
166 of_clk_del_provider(pdev->dev.of_node);
167
168 for (i = 0; i < clk_data.clk_num; i++) {
169 if (!IS_ERR(clk_table[i]))
170 clk_unregister(clk_table[i]);
171 }
172
173 return 0;
131} 174}
132CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock", 175
133 exynos_audss_clk_init); 176static const struct of_device_id exynos_audss_clk_of_match[] = {
134CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock", 177 { .compatible = "samsung,exynos4210-audss-clock", },
135 exynos_audss_clk_init); 178 { .compatible = "samsung,exynos5250-audss-clock", },
179 {},
180};
181
182static struct platform_driver exynos_audss_clk_driver = {
183 .driver = {
184 .name = "exynos-audss-clk",
185 .owner = THIS_MODULE,
186 .of_match_table = exynos_audss_clk_of_match,
187 },
188 .probe = exynos_audss_clk_probe,
189 .remove = exynos_audss_clk_remove,
190};
191
192static int __init exynos_audss_clk_init(void)
193{
194 return platform_driver_register(&exynos_audss_clk_driver);
195}
196core_initcall(exynos_audss_clk_init);
197
198static void __exit exynos_audss_clk_exit(void)
199{
200 platform_driver_unregister(&exynos_audss_clk_driver);
201}
202module_exit(exynos_audss_clk_exit);
203
204MODULE_AUTHOR("Padmavathi Venna <padma.v@samsung.com>");
205MODULE_DESCRIPTION("Exynos Audio Subsystem Clock Controller");
206MODULE_LICENSE("GPL v2");
207MODULE_ALIAS("platform:exynos-audss-clk");