clk: samsung: Fix Exynos 5420 pinctrl setup and clock disable failure due to domain being gated

Audio subsystem clocks are located in separate block. On Exynos 5420 if
clock for this block (from main clock domain) 'mau_epll' is gated then
any read or write to audss registers will block.

This kind of boot hang was observed on Arndale Octa and Peach Pi/Pit
after introducing runtime PM to pl330 DMA driver. After that commit the
'mau_epll' was gated, because the "amba" clock was disabled and there
were no more users of mau_epll.

The system hang on one of steps:
1. Disabling unused clocks from audss block.
2. During audss GPIO setup (just before probing i2s0 because
samsung_pinmux_setup() tried to access memory from audss block which was
gated.

Add a workaround for this by enabling the 'mau_epll' clock in probe.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Michael Turquette <mturquette@linaro.org>

authored by Krzysztof Kozlowski and committed by Michael Turquette f1e9203e 83ccc467

Changed files
+28 -1
drivers
clk
+28 -1
drivers/clk/samsung/clk-exynos-audss.c
··· 29 29 static struct clk **clk_table; 30 30 static void __iomem *reg_base; 31 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 40 #define ASS_CLK_SRC 0x0 34 41 #define ASS_CLK_DIV 0x4 ··· 105 98 dev_err(&pdev->dev, "failed to map audss registers\n"); 106 99 return PTR_ERR(reg_base); 107 100 } 101 + /* EPLL don't have to be enabled for boards other than Exynos5420 */ 102 + epll = ERR_PTR(-ENODEV); 108 103 109 104 clk_table = devm_kzalloc(&pdev->dev, 110 105 sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, ··· 124 115 pll_in = devm_clk_get(&pdev->dev, "pll_in"); 125 116 if (!IS_ERR(pll_ref)) 126 117 mout_audss_p[0] = __clk_get_name(pll_ref); 127 - if (!IS_ERR(pll_in)) 118 + if (!IS_ERR(pll_in)) { 128 119 mout_audss_p[1] = __clk_get_name(pll_in); 120 + 121 + if (variant == TYPE_EXYNOS5420) { 122 + epll = pll_in; 123 + 124 + ret = clk_prepare_enable(epll); 125 + if (ret) { 126 + dev_err(&pdev->dev, 127 + "failed to prepare the epll clock\n"); 128 + return ret; 129 + } 130 + } 131 + } 129 132 clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", 130 133 mout_audss_p, ARRAY_SIZE(mout_audss_p), 131 134 CLK_SET_RATE_NO_REPARENT, ··· 224 203 clk_unregister(clk_table[i]); 225 204 } 226 205 206 + if (!IS_ERR(epll)) 207 + clk_disable_unprepare(epll); 208 + 227 209 return ret; 228 210 } 229 211 ··· 244 220 if (!IS_ERR(clk_table[i])) 245 221 clk_unregister(clk_table[i]); 246 222 } 223 + 224 + if (!IS_ERR(epll)) 225 + clk_disable_unprepare(epll); 247 226 248 227 return 0; 249 228 }