diff options
author | Andrzej Hajda <a.hajda@samsung.com> | 2015-03-17 13:12:23 -0400 |
---|---|---|
committer | Kukjin Kim <kgene@kernel.org> | 2015-03-17 13:12:23 -0400 |
commit | 528eae6c14a45f40809733862675f6cf03998d17 (patch) | |
tree | ff77c0078d4c0f095eb38e50df3562a566f2a84e | |
parent | c517d838eb7d07bbe9507871fab3931deccff539 (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.c | 27 |
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 | ||
42 | static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) | 43 | static 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; |