aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2015-03-17 13:12:23 -0400
committerKukjin Kim <kgene@kernel.org>2015-03-17 13:12:23 -0400
commit528eae6c14a45f40809733862675f6cf03998d17 (patch)
treeff77c0078d4c0f095eb38e50df3562a566f2a84e
parentc517d838eb7d07bbe9507871fab3931deccff539 (diff)
ARM: EXYNOS: add support for async-bridge clocks for pm_domains
Since Exynos5420 there are async-bridges (ASB) between different IPs. These bridges must be operational during power domain on/off, ie. clocks used by these bridges should be enabled. This patch enabled these clocks during domain on/off. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Reviewed-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kukjin Kim <kgene@kernel.org>
-rw-r--r--arch/arm/mach-exynos/pm_domains.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 20f267121b3e..ccdcacbd1cd9 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -37,6 +37,7 @@ struct exynos_pm_domain {
37 struct clk *oscclk; 37 struct clk *oscclk;
38 struct clk *clk[MAX_CLK_PER_DOMAIN]; 38 struct clk *clk[MAX_CLK_PER_DOMAIN];
39 struct clk *pclk[MAX_CLK_PER_DOMAIN]; 39 struct clk *pclk[MAX_CLK_PER_DOMAIN];
40 struct clk *asb_clk[MAX_CLK_PER_DOMAIN];
40}; 41};
41 42
42static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) 43static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
@@ -45,14 +46,19 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
45 void __iomem *base; 46 void __iomem *base;
46 u32 timeout, pwr; 47 u32 timeout, pwr;
47 char *op; 48 char *op;
49 int i;
48 50
49 pd = container_of(domain, struct exynos_pm_domain, pd); 51 pd = container_of(domain, struct exynos_pm_domain, pd);
50 base = pd->base; 52 base = pd->base;
51 53
54 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
55 if (IS_ERR(pd->asb_clk[i]))
56 break;
57 clk_prepare_enable(pd->asb_clk[i]);
58 }
59
52 /* Set oscclk before powering off a domain*/ 60 /* Set oscclk before powering off a domain*/
53 if (!power_on) { 61 if (!power_on) {
54 int i;
55
56 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { 62 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
57 if (IS_ERR(pd->clk[i])) 63 if (IS_ERR(pd->clk[i]))
58 break; 64 break;
@@ -81,8 +87,6 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
81 87
82 /* Restore clocks after powering on a domain*/ 88 /* Restore clocks after powering on a domain*/
83 if (power_on) { 89 if (power_on) {
84 int i;
85
86 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { 90 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
87 if (IS_ERR(pd->clk[i])) 91 if (IS_ERR(pd->clk[i]))
88 break; 92 break;
@@ -92,6 +96,12 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
92 } 96 }
93 } 97 }
94 98
99 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
100 if (IS_ERR(pd->asb_clk[i]))
101 break;
102 clk_disable_unprepare(pd->asb_clk[i]);
103 }
104
95 return 0; 105 return 0;
96} 106}
97 107
@@ -131,6 +141,15 @@ static __init int exynos4_pm_init_power_domain(void)
131 pd->pd.power_off = exynos_pd_power_off; 141 pd->pd.power_off = exynos_pd_power_off;
132 pd->pd.power_on = exynos_pd_power_on; 142 pd->pd.power_on = exynos_pd_power_on;
133 143
144 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
145 char clk_name[8];
146
147 snprintf(clk_name, sizeof(clk_name), "asb%d", i);
148 pd->asb_clk[i] = clk_get(dev, clk_name);
149 if (IS_ERR(pd->asb_clk[i]))
150 break;
151 }
152
134 pd->oscclk = clk_get(dev, "oscclk"); 153 pd->oscclk = clk_get(dev, "oscclk");
135 if (IS_ERR(pd->oscclk)) 154 if (IS_ERR(pd->oscclk))
136 goto no_clk; 155 goto no_clk;