diff options
| -rw-r--r-- | drivers/clk/samsung/clk-exynos-audss.c | 29 |
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); | |||
| 29 | static struct clk **clk_table; | 29 | static struct clk **clk_table; |
| 30 | static void __iomem *reg_base; | 30 | static void __iomem *reg_base; |
| 31 | static struct clk_onecell_data clk_data; | 31 | static 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 | */ | ||
| 38 | static 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 | ||
