diff options
Diffstat (limited to 'arch/arm/mach-omap2/powerdomain.c')
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index ef71fdd40fc4..896cb4c5eb1a 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP powerdomain control | 2 | * OMAP powerdomain control |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. |
5 | * Copyright (C) 2007-2011 Nokia Corporation | 5 | * Copyright (C) 2007-2011 Nokia Corporation |
6 | * | 6 | * |
7 | * Written by Paul Walmsley | 7 | * Written by Paul Walmsley |
@@ -81,9 +81,6 @@ static int _pwrdm_register(struct powerdomain *pwrdm) | |||
81 | if (!pwrdm || !pwrdm->name) | 81 | if (!pwrdm || !pwrdm->name) |
82 | return -EINVAL; | 82 | return -EINVAL; |
83 | 83 | ||
84 | if (!omap_chip_is(pwrdm->omap_chip)) | ||
85 | return -EINVAL; | ||
86 | |||
87 | if (cpu_is_omap44xx() && | 84 | if (cpu_is_omap44xx() && |
88 | pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) { | 85 | pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) { |
89 | pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n", | 86 | pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n", |
@@ -194,36 +191,76 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) | |||
194 | /* Public functions */ | 191 | /* Public functions */ |
195 | 192 | ||
196 | /** | 193 | /** |
197 | * pwrdm_init - set up the powerdomain layer | 194 | * pwrdm_register_platform_funcs - register powerdomain implementation fns |
198 | * @pwrdms: array of struct powerdomain pointers to register | 195 | * @po: func pointers for arch specific implementations |
199 | * @custom_funcs: func pointers for arch specific implementations | 196 | * |
197 | * Register the list of function pointers used to implement the | ||
198 | * powerdomain functions on different OMAP SoCs. Should be called | ||
199 | * before any other pwrdm_register*() function. Returns -EINVAL if | ||
200 | * @po is null, -EEXIST if platform functions have already been | ||
201 | * registered, or 0 upon success. | ||
202 | */ | ||
203 | int pwrdm_register_platform_funcs(struct pwrdm_ops *po) | ||
204 | { | ||
205 | if (!po) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (arch_pwrdm) | ||
209 | return -EEXIST; | ||
210 | |||
211 | arch_pwrdm = po; | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * pwrdm_register_pwrdms - register SoC powerdomains | ||
218 | * @ps: pointer to an array of struct powerdomain to register | ||
200 | * | 219 | * |
201 | * Loop through the array of powerdomains @pwrdms, registering all | 220 | * Register the powerdomains available on a particular OMAP SoC. Must |
202 | * that are available on the current CPU. Also, program all | 221 | * be called after pwrdm_register_platform_funcs(). May be called |
203 | * powerdomain target state as ON; this is to prevent domains from | 222 | * multiple times. Returns -EACCES if called before |
204 | * hitting low power states (if bootloader has target states set to | 223 | * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is |
205 | * something other than ON) and potentially even losing context while | 224 | * null; or 0 upon success. |
206 | * PM is not fully initialized. The PM late init code can then program | ||
207 | * the desired target state for all the power domains. No return | ||
208 | * value. | ||
209 | */ | 225 | */ |
210 | void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs) | 226 | int pwrdm_register_pwrdms(struct powerdomain **ps) |
211 | { | 227 | { |
212 | struct powerdomain **p = NULL; | 228 | struct powerdomain **p = NULL; |
213 | struct powerdomain *temp_p; | ||
214 | 229 | ||
215 | if (!custom_funcs) | 230 | if (!arch_pwrdm) |
216 | WARN(1, "powerdomain: No custom pwrdm functions registered\n"); | 231 | return -EEXIST; |
217 | else | ||
218 | arch_pwrdm = custom_funcs; | ||
219 | 232 | ||
220 | if (pwrdms) { | 233 | if (!ps) |
221 | for (p = pwrdms; *p; p++) | 234 | return -EINVAL; |
222 | _pwrdm_register(*p); | 235 | |
223 | } | 236 | for (p = ps; *p; p++) |
237 | _pwrdm_register(*p); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * pwrdm_complete_init - set up the powerdomain layer | ||
244 | * | ||
245 | * Do whatever is necessary to initialize registered powerdomains and | ||
246 | * powerdomain code. Currently, this programs the next power state | ||
247 | * for each powerdomain to ON. This prevents powerdomains from | ||
248 | * unexpectedly losing context or entering high wakeup latency modes | ||
249 | * with non-power-management-enabled kernels. Must be called after | ||
250 | * pwrdm_register_pwrdms(). Returns -EACCES if called before | ||
251 | * pwrdm_register_pwrdms(), or 0 upon success. | ||
252 | */ | ||
253 | int pwrdm_complete_init(void) | ||
254 | { | ||
255 | struct powerdomain *temp_p; | ||
256 | |||
257 | if (list_empty(&pwrdm_list)) | ||
258 | return -EACCES; | ||
224 | 259 | ||
225 | list_for_each_entry(temp_p, &pwrdm_list, node) | 260 | list_for_each_entry(temp_p, &pwrdm_list, node) |
226 | pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON); | 261 | pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON); |
262 | |||
263 | return 0; | ||
227 | } | 264 | } |
228 | 265 | ||
229 | /** | 266 | /** |