aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index b50469faf70c..f7eff82738ab 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -29,6 +29,13 @@ static DEFINE_SPINLOCK(lock);
29static struct clk **clk_table; 29static struct clk **clk_table;
30static void __iomem *reg_base; 30static void __iomem *reg_base;
31static struct clk_onecell_data clk_data; 31static struct clk_onecell_data clk_data;
32/*
33 * On Exynos5420 this will be a clock which has to be enabled before any
34 * access to audss registers. Typically a child of EPLL.
35 *
36 * On other platforms this will be -ENODEV.
37 */
38static struct clk *epll;
32 39
33#define ASS_CLK_SRC 0x0 40#define ASS_CLK_SRC 0x0
34#define ASS_CLK_DIV 0x4 41#define ASS_CLK_DIV 0x4
@@ -98,6 +105,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
98 dev_err(&pdev->dev, "failed to map audss registers\n"); 105 dev_err(&pdev->dev, "failed to map audss registers\n");
99 return PTR_ERR(reg_base); 106 return PTR_ERR(reg_base);
100 } 107 }
108 /* EPLL don't have to be enabled for boards other than Exynos5420 */
109 epll = ERR_PTR(-ENODEV);
101 110
102 clk_table = devm_kzalloc(&pdev->dev, 111 clk_table = devm_kzalloc(&pdev->dev,
103 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, 112 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
@@ -115,8 +124,20 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
115 pll_in = devm_clk_get(&pdev->dev, "pll_in"); 124 pll_in = devm_clk_get(&pdev->dev, "pll_in");
116 if (!IS_ERR(pll_ref)) 125 if (!IS_ERR(pll_ref))
117 mout_audss_p[0] = __clk_get_name(pll_ref); 126 mout_audss_p[0] = __clk_get_name(pll_ref);
118 if (!IS_ERR(pll_in)) 127 if (!IS_ERR(pll_in)) {
119 mout_audss_p[1] = __clk_get_name(pll_in); 128 mout_audss_p[1] = __clk_get_name(pll_in);
129
130 if (variant == TYPE_EXYNOS5420) {
131 epll = pll_in;
132
133 ret = clk_prepare_enable(epll);
134 if (ret) {
135 dev_err(&pdev->dev,
136 "failed to prepare the epll clock\n");
137 return ret;
138 }
139 }
140 }
120 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", 141 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
121 mout_audss_p, ARRAY_SIZE(mout_audss_p), 142 mout_audss_p, ARRAY_SIZE(mout_audss_p),
122 CLK_SET_RATE_NO_REPARENT, 143 CLK_SET_RATE_NO_REPARENT,
@@ -203,6 +224,9 @@ unregister:
203 clk_unregister(clk_table[i]); 224 clk_unregister(clk_table[i]);
204 } 225 }
205 226
227 if (!IS_ERR(epll))
228 clk_disable_unprepare(epll);
229
206 return ret; 230 return ret;
207} 231}
208 232
@@ -221,6 +245,9 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
221 clk_unregister(clk_table[i]); 245 clk_unregister(clk_table[i]);
222 } 246 }
223 247
248 if (!IS_ERR(epll))
249 clk_disable_unprepare(epll);
250
224 return 0; 251 return 0;
225} 252}
226 253