diff options
author | Olof Johansson <olof@lixom.net> | 2015-01-21 20:02:21 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2015-01-21 20:02:21 -0500 |
commit | a71596933cf792dacc3c5080df298c0fccef1d94 (patch) | |
tree | bc4f6bceb862ddead81b8ce433a63c3f2c6d0dd5 | |
parent | a62d351dc54543513bdae5ff5dd679f6bffde632 (diff) | |
parent | 2173fc7cb681c38b9e5bc526211045caecf96e44 (diff) |
Merge tag 'renesas-soc2-for-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc
Merge "Second Round of Renesas ARM Based SoC Updates for v3.20" from Simon
Horman:
* Add DT support for PM domains
* tag 'renesas-soc2-for-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
ARM: shmobile: R-Mobile: Add DT support for PM domains
ARM: shmobile: R-Mobile: Store SYSC base address in rmobile_pm_domain
ARM: shmobile: R-Mobile: Use generic_pm_domain.attach_dev() for pm_clk setup
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/mach-shmobile/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-r8a7740.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-rmobile.c | 275 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-rmobile.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-sh7372.c | 11 |
5 files changed, 289 insertions, 17 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index d107b9386bda..894c68760060 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -7,6 +7,7 @@ config PM_RCAR | |||
7 | 7 | ||
8 | config PM_RMOBILE | 8 | config PM_RMOBILE |
9 | bool | 9 | bool |
10 | select PM_GENERIC_DOMAINS | ||
10 | 11 | ||
11 | config ARCH_RCAR_GEN1 | 12 | config ARCH_RCAR_GEN1 |
12 | bool | 13 | bool |
@@ -23,7 +24,7 @@ config ARCH_RCAR_GEN2 | |||
23 | 24 | ||
24 | config ARCH_RMOBILE | 25 | config ARCH_RMOBILE |
25 | bool | 26 | bool |
26 | select PM_RMOBILE if PM && !ARCH_SHMOBILE_MULTI | 27 | select PM_RMOBILE if PM |
27 | select SYS_SUPPORTS_SH_CMT | 28 | select SYS_SUPPORTS_SH_CMT |
28 | select SYS_SUPPORTS_SH_TMU | 29 | select SYS_SUPPORTS_SH_TMU |
29 | 30 | ||
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c index ac2eecd6f5ea..34608fcf0648 100644 --- a/arch/arm/mach-shmobile/pm-r8a7740.c +++ b/arch/arm/mach-shmobile/pm-r8a7740.c | |||
@@ -9,10 +9,14 @@ | |||
9 | * for more details. | 9 | * for more details. |
10 | */ | 10 | */ |
11 | #include <linux/console.h> | 11 | #include <linux/console.h> |
12 | #include <linux/io.h> | ||
12 | #include <linux/suspend.h> | 13 | #include <linux/suspend.h> |
14 | |||
13 | #include "common.h" | 15 | #include "common.h" |
14 | #include "pm-rmobile.h" | 16 | #include "pm-rmobile.h" |
15 | 17 | ||
18 | #define SYSC_BASE IOMEM(0xe6180000) | ||
19 | |||
16 | #if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) | 20 | #if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) |
17 | static int r8a7740_pd_a3sm_suspend(void) | 21 | static int r8a7740_pd_a3sm_suspend(void) |
18 | { | 22 | { |
@@ -45,41 +49,51 @@ static int r8a7740_pd_d4_suspend(void) | |||
45 | static struct rmobile_pm_domain r8a7740_pm_domains[] = { | 49 | static struct rmobile_pm_domain r8a7740_pm_domains[] = { |
46 | { | 50 | { |
47 | .genpd.name = "A4LC", | 51 | .genpd.name = "A4LC", |
52 | .base = SYSC_BASE, | ||
48 | .bit_shift = 1, | 53 | .bit_shift = 1, |
49 | }, { | 54 | }, { |
50 | .genpd.name = "A4MP", | 55 | .genpd.name = "A4MP", |
56 | .base = SYSC_BASE, | ||
51 | .bit_shift = 2, | 57 | .bit_shift = 2, |
52 | }, { | 58 | }, { |
53 | .genpd.name = "D4", | 59 | .genpd.name = "D4", |
60 | .base = SYSC_BASE, | ||
54 | .bit_shift = 3, | 61 | .bit_shift = 3, |
55 | .gov = &pm_domain_always_on_gov, | 62 | .gov = &pm_domain_always_on_gov, |
56 | .suspend = r8a7740_pd_d4_suspend, | 63 | .suspend = r8a7740_pd_d4_suspend, |
57 | }, { | 64 | }, { |
58 | .genpd.name = "A4R", | 65 | .genpd.name = "A4R", |
66 | .base = SYSC_BASE, | ||
59 | .bit_shift = 5, | 67 | .bit_shift = 5, |
60 | }, { | 68 | }, { |
61 | .genpd.name = "A3RV", | 69 | .genpd.name = "A3RV", |
70 | .base = SYSC_BASE, | ||
62 | .bit_shift = 6, | 71 | .bit_shift = 6, |
63 | }, { | 72 | }, { |
64 | .genpd.name = "A4S", | 73 | .genpd.name = "A4S", |
74 | .base = SYSC_BASE, | ||
65 | .bit_shift = 10, | 75 | .bit_shift = 10, |
66 | .no_debug = true, | 76 | .no_debug = true, |
67 | }, { | 77 | }, { |
68 | .genpd.name = "A3SP", | 78 | .genpd.name = "A3SP", |
79 | .base = SYSC_BASE, | ||
69 | .bit_shift = 11, | 80 | .bit_shift = 11, |
70 | .gov = &pm_domain_always_on_gov, | 81 | .gov = &pm_domain_always_on_gov, |
71 | .no_debug = true, | 82 | .no_debug = true, |
72 | .suspend = r8a7740_pd_a3sp_suspend, | 83 | .suspend = r8a7740_pd_a3sp_suspend, |
73 | }, { | 84 | }, { |
74 | .genpd.name = "A3SM", | 85 | .genpd.name = "A3SM", |
86 | .base = SYSC_BASE, | ||
75 | .bit_shift = 12, | 87 | .bit_shift = 12, |
76 | .gov = &pm_domain_always_on_gov, | 88 | .gov = &pm_domain_always_on_gov, |
77 | .suspend = r8a7740_pd_a3sm_suspend, | 89 | .suspend = r8a7740_pd_a3sm_suspend, |
78 | }, { | 90 | }, { |
79 | .genpd.name = "A3SG", | 91 | .genpd.name = "A3SG", |
92 | .base = SYSC_BASE, | ||
80 | .bit_shift = 13, | 93 | .bit_shift = 13, |
81 | }, { | 94 | }, { |
82 | .genpd.name = "A4SU", | 95 | .genpd.name = "A4SU", |
96 | .base = SYSC_BASE, | ||
83 | .bit_shift = 20, | 97 | .bit_shift = 20, |
84 | }, | 98 | }, |
85 | }; | 99 | }; |
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 6f7d56ecf969..85a7fdd9823b 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2012 Renesas Solutions Corp. | 4 | * Copyright (C) 2012 Renesas Solutions Corp. |
5 | * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 5 | * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
6 | * Copyright (C) 2014 Glider bvba | ||
6 | * | 7 | * |
7 | * based on pm-sh7372.c | 8 | * based on pm-sh7372.c |
8 | * Copyright (C) 2011 Magnus Damm | 9 | * Copyright (C) 2011 Magnus Damm |
@@ -13,16 +14,22 @@ | |||
13 | */ | 14 | */ |
14 | #include <linux/console.h> | 15 | #include <linux/console.h> |
15 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_platform.h> | ||
16 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
17 | #include <linux/pm.h> | 21 | #include <linux/pm.h> |
18 | #include <linux/pm_clock.h> | 22 | #include <linux/pm_clock.h> |
23 | #include <linux/slab.h> | ||
24 | |||
19 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | |||
20 | #include "pm-rmobile.h" | 27 | #include "pm-rmobile.h" |
21 | 28 | ||
22 | /* SYSC */ | 29 | /* SYSC */ |
23 | #define SPDCR IOMEM(0xe6180008) | 30 | #define SPDCR 0x08 /* SYS Power Down Control Register */ |
24 | #define SWUCR IOMEM(0xe6180014) | 31 | #define SWUCR 0x14 /* SYS Wakeup Control Register */ |
25 | #define PSTR IOMEM(0xe6180080) | 32 | #define PSTR 0x80 /* Power Status Register */ |
26 | 33 | ||
27 | #define PSTR_RETRIES 100 | 34 | #define PSTR_RETRIES 100 |
28 | #define PSTR_DELAY_US 10 | 35 | #define PSTR_DELAY_US 10 |
@@ -30,8 +37,12 @@ | |||
30 | static int rmobile_pd_power_down(struct generic_pm_domain *genpd) | 37 | static int rmobile_pd_power_down(struct generic_pm_domain *genpd) |
31 | { | 38 | { |
32 | struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd); | 39 | struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd); |
33 | unsigned int mask = 1 << rmobile_pd->bit_shift; | 40 | unsigned int mask; |
41 | |||
42 | if (rmobile_pd->bit_shift == ~0) | ||
43 | return -EBUSY; | ||
34 | 44 | ||
45 | mask = 1 << rmobile_pd->bit_shift; | ||
35 | if (rmobile_pd->suspend) { | 46 | if (rmobile_pd->suspend) { |
36 | int ret = rmobile_pd->suspend(); | 47 | int ret = rmobile_pd->suspend(); |
37 | 48 | ||
@@ -39,12 +50,12 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd) | |||
39 | return ret; | 50 | return ret; |
40 | } | 51 | } |
41 | 52 | ||
42 | if (__raw_readl(PSTR) & mask) { | 53 | if (__raw_readl(rmobile_pd->base + PSTR) & mask) { |
43 | unsigned int retry_count; | 54 | unsigned int retry_count; |
44 | __raw_writel(mask, SPDCR); | 55 | __raw_writel(mask, rmobile_pd->base + SPDCR); |
45 | 56 | ||
46 | for (retry_count = PSTR_RETRIES; retry_count; retry_count--) { | 57 | for (retry_count = PSTR_RETRIES; retry_count; retry_count--) { |
47 | if (!(__raw_readl(SPDCR) & mask)) | 58 | if (!(__raw_readl(rmobile_pd->base + SPDCR) & mask)) |
48 | break; | 59 | break; |
49 | cpu_relax(); | 60 | cpu_relax(); |
50 | } | 61 | } |
@@ -52,7 +63,8 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd) | |||
52 | 63 | ||
53 | if (!rmobile_pd->no_debug) | 64 | if (!rmobile_pd->no_debug) |
54 | pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n", | 65 | pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n", |
55 | genpd->name, mask, __raw_readl(PSTR)); | 66 | genpd->name, mask, |
67 | __raw_readl(rmobile_pd->base + PSTR)); | ||
56 | 68 | ||
57 | return 0; | 69 | return 0; |
58 | } | 70 | } |
@@ -60,17 +72,21 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd) | |||
60 | static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd, | 72 | static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd, |
61 | bool do_resume) | 73 | bool do_resume) |
62 | { | 74 | { |
63 | unsigned int mask = 1 << rmobile_pd->bit_shift; | 75 | unsigned int mask; |
64 | unsigned int retry_count; | 76 | unsigned int retry_count; |
65 | int ret = 0; | 77 | int ret = 0; |
66 | 78 | ||
67 | if (__raw_readl(PSTR) & mask) | 79 | if (rmobile_pd->bit_shift == ~0) |
80 | return 0; | ||
81 | |||
82 | mask = 1 << rmobile_pd->bit_shift; | ||
83 | if (__raw_readl(rmobile_pd->base + PSTR) & mask) | ||
68 | goto out; | 84 | goto out; |
69 | 85 | ||
70 | __raw_writel(mask, SWUCR); | 86 | __raw_writel(mask, rmobile_pd->base + SWUCR); |
71 | 87 | ||
72 | for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) { | 88 | for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) { |
73 | if (!(__raw_readl(SWUCR) & mask)) | 89 | if (!(__raw_readl(rmobile_pd->base + SWUCR) & mask)) |
74 | break; | 90 | break; |
75 | if (retry_count > PSTR_RETRIES) | 91 | if (retry_count > PSTR_RETRIES) |
76 | udelay(PSTR_DELAY_US); | 92 | udelay(PSTR_DELAY_US); |
@@ -82,7 +98,8 @@ static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd, | |||
82 | 98 | ||
83 | if (!rmobile_pd->no_debug) | 99 | if (!rmobile_pd->no_debug) |
84 | pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n", | 100 | pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n", |
85 | rmobile_pd->genpd.name, mask, __raw_readl(PSTR)); | 101 | rmobile_pd->genpd.name, mask, |
102 | __raw_readl(rmobile_pd->base + PSTR)); | ||
86 | 103 | ||
87 | out: | 104 | out: |
88 | if (ret == 0 && rmobile_pd->resume && do_resume) | 105 | if (ret == 0 && rmobile_pd->resume && do_resume) |
@@ -101,6 +118,36 @@ static bool rmobile_pd_active_wakeup(struct device *dev) | |||
101 | return true; | 118 | return true; |
102 | } | 119 | } |
103 | 120 | ||
121 | static int rmobile_pd_attach_dev(struct generic_pm_domain *domain, | ||
122 | struct device *dev) | ||
123 | { | ||
124 | int error; | ||
125 | |||
126 | error = pm_clk_create(dev); | ||
127 | if (error) { | ||
128 | dev_err(dev, "pm_clk_create failed %d\n", error); | ||
129 | return error; | ||
130 | } | ||
131 | |||
132 | error = pm_clk_add(dev, NULL); | ||
133 | if (error) { | ||
134 | dev_err(dev, "pm_clk_add failed %d\n", error); | ||
135 | goto fail; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | |||
140 | fail: | ||
141 | pm_clk_destroy(dev); | ||
142 | return error; | ||
143 | } | ||
144 | |||
145 | static void rmobile_pd_detach_dev(struct generic_pm_domain *domain, | ||
146 | struct device *dev) | ||
147 | { | ||
148 | pm_clk_destroy(dev); | ||
149 | } | ||
150 | |||
104 | static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) | 151 | static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) |
105 | { | 152 | { |
106 | struct generic_pm_domain *genpd = &rmobile_pd->genpd; | 153 | struct generic_pm_domain *genpd = &rmobile_pd->genpd; |
@@ -111,9 +158,13 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) | |||
111 | genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; | 158 | genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; |
112 | genpd->power_off = rmobile_pd_power_down; | 159 | genpd->power_off = rmobile_pd_power_down; |
113 | genpd->power_on = rmobile_pd_power_up; | 160 | genpd->power_on = rmobile_pd_power_up; |
161 | genpd->attach_dev = rmobile_pd_attach_dev; | ||
162 | genpd->detach_dev = rmobile_pd_detach_dev; | ||
114 | __rmobile_pd_power_up(rmobile_pd, false); | 163 | __rmobile_pd_power_up(rmobile_pd, false); |
115 | } | 164 | } |
116 | 165 | ||
166 | #ifdef CONFIG_ARCH_SHMOBILE_LEGACY | ||
167 | |||
117 | void rmobile_init_domains(struct rmobile_pm_domain domains[], int num) | 168 | void rmobile_init_domains(struct rmobile_pm_domain domains[], int num) |
118 | { | 169 | { |
119 | int j; | 170 | int j; |
@@ -129,8 +180,6 @@ void rmobile_add_device_to_domain_td(const char *domain_name, | |||
129 | struct device *dev = &pdev->dev; | 180 | struct device *dev = &pdev->dev; |
130 | 181 | ||
131 | __pm_genpd_name_add_device(domain_name, dev, td); | 182 | __pm_genpd_name_add_device(domain_name, dev, td); |
132 | if (pm_clk_no_clocks(dev)) | ||
133 | pm_clk_add(dev, NULL); | ||
134 | } | 183 | } |
135 | 184 | ||
136 | void rmobile_add_devices_to_domains(struct pm_domain_device data[], | 185 | void rmobile_add_devices_to_domains(struct pm_domain_device data[], |
@@ -148,3 +197,199 @@ void rmobile_add_devices_to_domains(struct pm_domain_device data[], | |||
148 | rmobile_add_device_to_domain_td(data[j].domain_name, | 197 | rmobile_add_device_to_domain_td(data[j].domain_name, |
149 | data[j].pdev, &latencies); | 198 | data[j].pdev, &latencies); |
150 | } | 199 | } |
200 | |||
201 | #else /* !CONFIG_ARCH_SHMOBILE_LEGACY */ | ||
202 | |||
203 | static int rmobile_pd_suspend_cpu(void) | ||
204 | { | ||
205 | /* | ||
206 | * This domain contains the CPU core and therefore it should | ||
207 | * only be turned off if the CPU is not in use. | ||
208 | */ | ||
209 | return -EBUSY; | ||
210 | } | ||
211 | |||
212 | static int rmobile_pd_suspend_console(void) | ||
213 | { | ||
214 | /* | ||
215 | * Serial consoles make use of SCIF hardware located in this domain, | ||
216 | * hence keep the power domain on if "no_console_suspend" is set. | ||
217 | */ | ||
218 | return console_suspend_enabled ? 0 : -EBUSY; | ||
219 | } | ||
220 | |||
221 | static int rmobile_pd_suspend_debug(void) | ||
222 | { | ||
223 | /* | ||
224 | * This domain contains the Coresight-ETM hardware block and | ||
225 | * therefore it should only be turned off if the debug module is | ||
226 | * not in use. | ||
227 | */ | ||
228 | return -EBUSY; | ||
229 | } | ||
230 | |||
231 | #define MAX_NUM_CPU_PDS 8 | ||
232 | |||
233 | static unsigned int num_cpu_pds __initdata; | ||
234 | static struct device_node *cpu_pds[MAX_NUM_CPU_PDS] __initdata; | ||
235 | static struct device_node *console_pd __initdata; | ||
236 | static struct device_node *debug_pd __initdata; | ||
237 | |||
238 | static void __init get_special_pds(void) | ||
239 | { | ||
240 | struct device_node *np, *pd; | ||
241 | unsigned int i; | ||
242 | |||
243 | /* PM domains containing CPUs */ | ||
244 | for_each_node_by_type(np, "cpu") { | ||
245 | pd = of_parse_phandle(np, "power-domains", 0); | ||
246 | if (!pd) | ||
247 | continue; | ||
248 | |||
249 | for (i = 0; i < num_cpu_pds; i++) | ||
250 | if (pd == cpu_pds[i]) | ||
251 | break; | ||
252 | |||
253 | if (i < num_cpu_pds) { | ||
254 | of_node_put(pd); | ||
255 | continue; | ||
256 | } | ||
257 | |||
258 | if (num_cpu_pds == MAX_NUM_CPU_PDS) { | ||
259 | pr_warn("Too many CPU PM domains\n"); | ||
260 | of_node_put(pd); | ||
261 | continue; | ||
262 | } | ||
263 | |||
264 | cpu_pds[num_cpu_pds++] = pd; | ||
265 | } | ||
266 | |||
267 | /* PM domain containing console */ | ||
268 | if (of_stdout) | ||
269 | console_pd = of_parse_phandle(of_stdout, "power-domains", 0); | ||
270 | |||
271 | /* PM domain containing Coresight-ETM */ | ||
272 | np = of_find_compatible_node(NULL, NULL, "arm,coresight-etm3x"); | ||
273 | if (np) { | ||
274 | debug_pd = of_parse_phandle(np, "power-domains", 0); | ||
275 | of_node_put(np); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | static void __init put_special_pds(void) | ||
280 | { | ||
281 | unsigned int i; | ||
282 | |||
283 | for (i = 0; i < num_cpu_pds; i++) | ||
284 | of_node_put(cpu_pds[i]); | ||
285 | of_node_put(console_pd); | ||
286 | of_node_put(debug_pd); | ||
287 | } | ||
288 | |||
289 | static bool __init pd_contains_cpu(const struct device_node *pd) | ||
290 | { | ||
291 | unsigned int i; | ||
292 | |||
293 | for (i = 0; i < num_cpu_pds; i++) | ||
294 | if (pd == cpu_pds[i]) | ||
295 | return true; | ||
296 | |||
297 | return false; | ||
298 | } | ||
299 | |||
300 | static void __init rmobile_setup_pm_domain(struct device_node *np, | ||
301 | struct rmobile_pm_domain *pd) | ||
302 | { | ||
303 | const char *name = pd->genpd.name; | ||
304 | |||
305 | if (pd_contains_cpu(np)) { | ||
306 | pr_debug("PM domain %s contains CPU\n", name); | ||
307 | pd->gov = &pm_domain_always_on_gov; | ||
308 | pd->suspend = rmobile_pd_suspend_cpu; | ||
309 | } else if (np == console_pd) { | ||
310 | pr_debug("PM domain %s contains serial console\n", name); | ||
311 | pd->gov = &pm_domain_always_on_gov; | ||
312 | pd->suspend = rmobile_pd_suspend_console; | ||
313 | } else if (np == debug_pd) { | ||
314 | pr_debug("PM domain %s contains Coresight-ETM\n", name); | ||
315 | pd->gov = &pm_domain_always_on_gov; | ||
316 | pd->suspend = rmobile_pd_suspend_debug; | ||
317 | } | ||
318 | |||
319 | rmobile_init_pm_domain(pd); | ||
320 | } | ||
321 | |||
322 | static int __init rmobile_add_pm_domains(void __iomem *base, | ||
323 | struct device_node *parent, | ||
324 | struct generic_pm_domain *genpd_parent) | ||
325 | { | ||
326 | struct device_node *np; | ||
327 | |||
328 | for_each_child_of_node(parent, np) { | ||
329 | struct rmobile_pm_domain *pd; | ||
330 | u32 idx = ~0; | ||
331 | |||
332 | if (of_property_read_u32(np, "reg", &idx)) { | ||
333 | /* always-on domain */ | ||
334 | } | ||
335 | |||
336 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); | ||
337 | if (!pd) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | pd->genpd.name = np->name; | ||
341 | pd->base = base; | ||
342 | pd->bit_shift = idx; | ||
343 | |||
344 | rmobile_setup_pm_domain(np, pd); | ||
345 | if (genpd_parent) | ||
346 | pm_genpd_add_subdomain(genpd_parent, &pd->genpd); | ||
347 | of_genpd_add_provider_simple(np, &pd->genpd); | ||
348 | |||
349 | rmobile_add_pm_domains(base, np, &pd->genpd); | ||
350 | } | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int __init rmobile_init_pm_domains(void) | ||
355 | { | ||
356 | struct device_node *np, *pmd; | ||
357 | bool scanned = false; | ||
358 | void __iomem *base; | ||
359 | int ret = 0; | ||
360 | |||
361 | for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") { | ||
362 | base = of_iomap(np, 0); | ||
363 | if (!base) { | ||
364 | pr_warn("%s cannot map reg 0\n", np->full_name); | ||
365 | continue; | ||
366 | } | ||
367 | |||
368 | pmd = of_get_child_by_name(np, "pm-domains"); | ||
369 | if (!pmd) { | ||
370 | pr_warn("%s lacks pm-domains node\n", np->full_name); | ||
371 | continue; | ||
372 | } | ||
373 | |||
374 | if (!scanned) { | ||
375 | /* Find PM domains containing special blocks */ | ||
376 | get_special_pds(); | ||
377 | scanned = true; | ||
378 | } | ||
379 | |||
380 | ret = rmobile_add_pm_domains(base, pmd, NULL); | ||
381 | of_node_put(pmd); | ||
382 | if (ret) { | ||
383 | of_node_put(np); | ||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | put_special_pds(); | ||
389 | |||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | core_initcall(rmobile_init_pm_domains); | ||
394 | |||
395 | #endif /* !CONFIG_ARCH_SHMOBILE_LEGACY */ | ||
diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h index 8f66b343162b..53219786f539 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.h +++ b/arch/arm/mach-shmobile/pm-rmobile.h | |||
@@ -21,6 +21,7 @@ struct rmobile_pm_domain { | |||
21 | struct dev_power_governor *gov; | 21 | struct dev_power_governor *gov; |
22 | int (*suspend)(void); | 22 | int (*suspend)(void); |
23 | void (*resume)(void); | 23 | void (*resume)(void); |
24 | void __iomem *base; | ||
24 | unsigned int bit_shift; | 25 | unsigned int bit_shift; |
25 | bool no_debug; | 26 | bool no_debug; |
26 | }; | 27 | }; |
@@ -36,7 +37,7 @@ struct pm_domain_device { | |||
36 | struct platform_device *pdev; | 37 | struct platform_device *pdev; |
37 | }; | 38 | }; |
38 | 39 | ||
39 | #ifdef CONFIG_PM_RMOBILE | 40 | #if defined(CONFIG_PM_RMOBILE) && defined(CONFIG_ARCH_SHMOBILE_LEGACY) |
40 | extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); | 41 | extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); |
41 | extern void rmobile_add_device_to_domain_td(const char *domain_name, | 42 | extern void rmobile_add_device_to_domain_td(const char *domain_name, |
42 | struct platform_device *pdev, | 43 | struct platform_device *pdev, |
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 0e37da654ed5..c0293ae4b013 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #define PLLC01STPCR IOMEM(0xe61500c8) | 45 | #define PLLC01STPCR IOMEM(0xe61500c8) |
46 | 46 | ||
47 | /* SYSC */ | 47 | /* SYSC */ |
48 | #define SYSC_BASE IOMEM(0xe6180000) | ||
49 | |||
48 | #define SBAR IOMEM(0xe6180020) | 50 | #define SBAR IOMEM(0xe6180020) |
49 | #define WUPRMSK IOMEM(0xe6180028) | 51 | #define WUPRMSK IOMEM(0xe6180028) |
50 | #define WUPSMSK IOMEM(0xe618002c) | 52 | #define WUPSMSK IOMEM(0xe618002c) |
@@ -118,24 +120,28 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { | |||
118 | .genpd.name = "A4LC", | 120 | .genpd.name = "A4LC", |
119 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 121 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
120 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 122 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
123 | .base = SYSC_BASE, | ||
121 | .bit_shift = 1, | 124 | .bit_shift = 1, |
122 | }, | 125 | }, |
123 | { | 126 | { |
124 | .genpd.name = "A4MP", | 127 | .genpd.name = "A4MP", |
125 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 128 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
126 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 129 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
130 | .base = SYSC_BASE, | ||
127 | .bit_shift = 2, | 131 | .bit_shift = 2, |
128 | }, | 132 | }, |
129 | { | 133 | { |
130 | .genpd.name = "D4", | 134 | .genpd.name = "D4", |
131 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 135 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
132 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 136 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
137 | .base = SYSC_BASE, | ||
133 | .bit_shift = 3, | 138 | .bit_shift = 3, |
134 | }, | 139 | }, |
135 | { | 140 | { |
136 | .genpd.name = "A4R", | 141 | .genpd.name = "A4R", |
137 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 142 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
138 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 143 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
144 | .base = SYSC_BASE, | ||
139 | .bit_shift = 5, | 145 | .bit_shift = 5, |
140 | .suspend = sh7372_a4r_pd_suspend, | 146 | .suspend = sh7372_a4r_pd_suspend, |
141 | .resume = sh7372_intcs_resume, | 147 | .resume = sh7372_intcs_resume, |
@@ -144,18 +150,21 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { | |||
144 | .genpd.name = "A3RV", | 150 | .genpd.name = "A3RV", |
145 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 151 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
146 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 152 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
153 | .base = SYSC_BASE, | ||
147 | .bit_shift = 6, | 154 | .bit_shift = 6, |
148 | }, | 155 | }, |
149 | { | 156 | { |
150 | .genpd.name = "A3RI", | 157 | .genpd.name = "A3RI", |
151 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 158 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
152 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 159 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
160 | .base = SYSC_BASE, | ||
153 | .bit_shift = 8, | 161 | .bit_shift = 8, |
154 | }, | 162 | }, |
155 | { | 163 | { |
156 | .genpd.name = "A4S", | 164 | .genpd.name = "A4S", |
157 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 165 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
158 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 166 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
167 | .base = SYSC_BASE, | ||
159 | .bit_shift = 10, | 168 | .bit_shift = 10, |
160 | .gov = &pm_domain_always_on_gov, | 169 | .gov = &pm_domain_always_on_gov, |
161 | .no_debug = true, | 170 | .no_debug = true, |
@@ -166,6 +175,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { | |||
166 | .genpd.name = "A3SP", | 175 | .genpd.name = "A3SP", |
167 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 176 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
168 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 177 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
178 | .base = SYSC_BASE, | ||
169 | .bit_shift = 11, | 179 | .bit_shift = 11, |
170 | .gov = &pm_domain_always_on_gov, | 180 | .gov = &pm_domain_always_on_gov, |
171 | .no_debug = true, | 181 | .no_debug = true, |
@@ -175,6 +185,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { | |||
175 | .genpd.name = "A3SG", | 185 | .genpd.name = "A3SG", |
176 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 186 | .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
177 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, | 187 | .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, |
188 | .base = SYSC_BASE, | ||
178 | .bit_shift = 13, | 189 | .bit_shift = 13, |
179 | }, | 190 | }, |
180 | }; | 191 | }; |