blob: 8a0dcd05afeb9a3af89ec8b280cb3b39f247f0d7 [file] [log] [blame]
Paul Walmsleyad67ef62008-08-19 11:08:40 +03001/*
2 * OMAP powerdomain control
3 *
4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
Paul Walmsley55ed9692010-01-26 20:12:59 -07005 * Copyright (C) 2007-2009 Nokia Corporation
Paul Walmsleyad67ef62008-08-19 11:08:40 +03006 *
7 * Written by Paul Walmsley
Abhijit Pagare3a759f02010-01-26 20:12:53 -07008 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
Paul Walmsley4788da22010-05-18 20:24:05 -06009 * State counting code by Tero Kristo <tero.kristo@nokia.com>
Abhijit Pagare3a759f02010-01-26 20:12:53 -070010 *
Paul Walmsleyad67ef62008-08-19 11:08:40 +030011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
Paul Walmsley33903eb2009-12-08 16:33:10 -070015#undef DEBUG
Paul Walmsleyad67ef62008-08-19 11:08:40 +030016
17#include <linux/kernel.h>
Paul Walmsleyad67ef62008-08-19 11:08:40 +030018#include <linux/types.h>
Paul Walmsleyad67ef62008-08-19 11:08:40 +030019#include <linux/list.h>
20#include <linux/errno.h>
Rajendra Nayak9b7fc902010-12-21 20:01:19 -070021#include <linux/string.h>
Paul Walmsley59fb6592010-12-21 15:30:55 -070022#include "cm2xxx_3xxx.h"
23#include "cm44xx.h"
24#include "prm2xxx_3xxx.h"
Paul Walmsleyd198b512010-12-21 15:30:54 -070025#include "prm44xx.h"
Paul Walmsleyad67ef62008-08-19 11:08:40 +030026
Tony Lindgrence491cf2009-10-20 09:40:47 -070027#include <plat/cpu.h>
28#include <plat/powerdomain.h>
29#include <plat/clockdomain.h>
Paul Walmsley55ed9692010-01-26 20:12:59 -070030#include <plat/prcm.h>
Paul Walmsleyad67ef62008-08-19 11:08:40 +030031
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +030032#include "pm.h"
33
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +030034enum {
35 PWRDM_STATE_NOW = 0,
36 PWRDM_STATE_PREV,
37};
38
Abhijit Pagare3a759f02010-01-26 20:12:53 -070039
Paul Walmsleyad67ef62008-08-19 11:08:40 +030040/* pwrdm_list contains all registered struct powerdomains */
41static LIST_HEAD(pwrdm_list);
42
Rajendra Nayak3b1e8b22010-12-21 20:01:18 -070043static struct pwrdm_ops *arch_pwrdm;
44
Paul Walmsleyad67ef62008-08-19 11:08:40 +030045/* Private functions */
46
Paul Walmsleyad67ef62008-08-19 11:08:40 +030047static struct powerdomain *_pwrdm_lookup(const char *name)
48{
49 struct powerdomain *pwrdm, *temp_pwrdm;
50
51 pwrdm = NULL;
52
53 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
54 if (!strcmp(name, temp_pwrdm->name)) {
55 pwrdm = temp_pwrdm;
56 break;
57 }
58 }
59
60 return pwrdm;
61}
62
Paul Walmsleye909d62a82010-01-26 20:13:00 -070063/**
64 * _pwrdm_register - register a powerdomain
65 * @pwrdm: struct powerdomain * to register
66 *
67 * Adds a powerdomain to the internal powerdomain list. Returns
68 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
69 * already registered by the provided name, or 0 upon success.
70 */
71static int _pwrdm_register(struct powerdomain *pwrdm)
72{
73 int i;
74
75 if (!pwrdm)
76 return -EINVAL;
77
78 if (!omap_chip_is(pwrdm->omap_chip))
79 return -EINVAL;
80
81 if (_pwrdm_lookup(pwrdm->name))
82 return -EEXIST;
83
84 list_add(&pwrdm->node, &pwrdm_list);
85
86 /* Initialize the powerdomain's state counter */
Paul Walmsleycf57aa72010-01-26 20:13:01 -070087 for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
Paul Walmsleye909d62a82010-01-26 20:13:00 -070088 pwrdm->state_counter[i] = 0;
89
Thara Gopinathcde08f82010-02-24 12:05:50 -070090 pwrdm->ret_logic_off_counter = 0;
91 for (i = 0; i < pwrdm->banks; i++)
92 pwrdm->ret_mem_off_counter[i] = 0;
93
Paul Walmsleye909d62a82010-01-26 20:13:00 -070094 pwrdm_wait_transition(pwrdm);
95 pwrdm->state = pwrdm_read_pwrst(pwrdm);
96 pwrdm->state_counter[pwrdm->state] = 1;
97
98 pr_debug("powerdomain: registered %s\n", pwrdm->name);
99
100 return 0;
101}
102
Thara Gopinathcde08f82010-02-24 12:05:50 -0700103static void _update_logic_membank_counters(struct powerdomain *pwrdm)
104{
105 int i;
106 u8 prev_logic_pwrst, prev_mem_pwrst;
107
108 prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
109 if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
110 (prev_logic_pwrst == PWRDM_POWER_OFF))
111 pwrdm->ret_logic_off_counter++;
112
113 for (i = 0; i < pwrdm->banks; i++) {
114 prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
115
116 if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
117 (prev_mem_pwrst == PWRDM_POWER_OFF))
118 pwrdm->ret_mem_off_counter[i]++;
119 }
120}
121
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300122static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
123{
124
125 int prev;
126 int state;
127
128 if (pwrdm == NULL)
129 return -EINVAL;
130
131 state = pwrdm_read_pwrst(pwrdm);
132
133 switch (flag) {
134 case PWRDM_STATE_NOW:
135 prev = pwrdm->state;
136 break;
137 case PWRDM_STATE_PREV:
138 prev = pwrdm_read_prev_pwrst(pwrdm);
139 if (pwrdm->state != prev)
140 pwrdm->state_counter[prev]++;
Thara Gopinathcde08f82010-02-24 12:05:50 -0700141 if (prev == PWRDM_POWER_RET)
142 _update_logic_membank_counters(pwrdm);
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300143 break;
144 default:
145 return -EINVAL;
146 }
147
148 if (state != prev)
149 pwrdm->state_counter[state]++;
150
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300151 pm_dbg_update_time(pwrdm, prev);
152
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300153 pwrdm->state = state;
154
155 return 0;
156}
157
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300158static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300159{
160 pwrdm_clear_all_prev_pwrst(pwrdm);
161 _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
162 return 0;
163}
164
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300165static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300166{
167 _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
168 return 0;
169}
170
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300171/* Public functions */
172
173/**
174 * pwrdm_init - set up the powerdomain layer
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700175 * @pwrdm_list: array of struct powerdomain pointers to register
Rajendra Nayak3b1e8b22010-12-21 20:01:18 -0700176 * @custom_funcs: func pointers for arch specfic implementations
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300177 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700178 * Loop through the array of powerdomains @pwrdm_list, registering all
179 * that are available on the current CPU. If pwrdm_list is supplied
180 * and not null, all of the referenced powerdomains will be
181 * registered. No return value. XXX pwrdm_list is not really a
182 * "list"; it is an array. Rename appropriately.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300183 */
Rajendra Nayak3b1e8b22010-12-21 20:01:18 -0700184void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300185{
186 struct powerdomain **p = NULL;
187
Rajendra Nayak3b1e8b22010-12-21 20:01:18 -0700188 if (!custom_funcs)
189 WARN(1, "powerdomain: No custom pwrdm functions registered\n");
190 else
191 arch_pwrdm = custom_funcs;
192
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300193 if (pwrdm_list) {
Paul Walmsleye909d62a82010-01-26 20:13:00 -0700194 for (p = pwrdm_list; *p; p++)
195 _pwrdm_register(*p);
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300196 }
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300197}
198
199/**
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300200 * pwrdm_lookup - look up a powerdomain by name, return a pointer
201 * @name: name of powerdomain
202 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700203 * Find a registered powerdomain by its name @name. Returns a pointer
204 * to the struct powerdomain if found, or NULL otherwise.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300205 */
206struct powerdomain *pwrdm_lookup(const char *name)
207{
208 struct powerdomain *pwrdm;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300209
210 if (!name)
211 return NULL;
212
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300213 pwrdm = _pwrdm_lookup(name);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300214
215 return pwrdm;
216}
217
218/**
Paul Walmsleye909d62a82010-01-26 20:13:00 -0700219 * pwrdm_for_each - call function on each registered clockdomain
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300220 * @fn: callback function *
221 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700222 * Call the supplied function @fn for each registered powerdomain.
223 * The callback function @fn can return anything but 0 to bail out
224 * early from the iterator. Returns the last return value of the
225 * callback function, which should be 0 for success or anything else
226 * to indicate failure; or -EINVAL if the function pointer is null.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300227 */
Paul Walmsleye909d62a82010-01-26 20:13:00 -0700228int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
229 void *user)
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300230{
231 struct powerdomain *temp_pwrdm;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300232 int ret = 0;
233
234 if (!fn)
235 return -EINVAL;
236
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300237 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300238 ret = (*fn)(temp_pwrdm, user);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300239 if (ret)
240 break;
241 }
Artem Bityutskiyee894b12009-10-01 10:01:55 +0300242
243 return ret;
244}
245
246/**
Paul Walmsley8420bb12008-08-19 11:08:44 +0300247 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
248 * @pwrdm: struct powerdomain * to add the clockdomain to
249 * @clkdm: struct clockdomain * to associate with a powerdomain
250 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700251 * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This
Paul Walmsley8420bb12008-08-19 11:08:44 +0300252 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
253 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
254 * or 0 upon success.
255 */
256int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
257{
Paul Walmsley8420bb12008-08-19 11:08:44 +0300258 int i;
259 int ret = -EINVAL;
260
261 if (!pwrdm || !clkdm)
262 return -EINVAL;
263
264 pr_debug("powerdomain: associating clockdomain %s with powerdomain "
265 "%s\n", clkdm->name, pwrdm->name);
266
Paul Walmsley8420bb12008-08-19 11:08:44 +0300267 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
268 if (!pwrdm->pwrdm_clkdms[i])
269 break;
270#ifdef DEBUG
271 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
272 ret = -EINVAL;
273 goto pac_exit;
274 }
275#endif
276 }
277
278 if (i == PWRDM_MAX_CLKDMS) {
279 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
280 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
281 WARN_ON(1);
282 ret = -ENOMEM;
283 goto pac_exit;
284 }
285
286 pwrdm->pwrdm_clkdms[i] = clkdm;
287
288 ret = 0;
289
290pac_exit:
Paul Walmsley8420bb12008-08-19 11:08:44 +0300291 return ret;
292}
293
294/**
295 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
296 * @pwrdm: struct powerdomain * to add the clockdomain to
297 * @clkdm: struct clockdomain * to associate with a powerdomain
298 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700299 * Dissociate the clockdomain @clkdm from the powerdomain
300 * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
301 * if @clkdm was not associated with the powerdomain, or 0 upon
302 * success.
Paul Walmsley8420bb12008-08-19 11:08:44 +0300303 */
304int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
305{
Paul Walmsley8420bb12008-08-19 11:08:44 +0300306 int ret = -EINVAL;
307 int i;
308
309 if (!pwrdm || !clkdm)
310 return -EINVAL;
311
312 pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
313 "%s\n", clkdm->name, pwrdm->name);
314
Paul Walmsley8420bb12008-08-19 11:08:44 +0300315 for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
316 if (pwrdm->pwrdm_clkdms[i] == clkdm)
317 break;
318
319 if (i == PWRDM_MAX_CLKDMS) {
320 pr_debug("powerdomain: clkdm %s not associated with pwrdm "
321 "%s ?!\n", clkdm->name, pwrdm->name);
322 ret = -ENOENT;
323 goto pdc_exit;
324 }
325
326 pwrdm->pwrdm_clkdms[i] = NULL;
327
328 ret = 0;
329
330pdc_exit:
Paul Walmsley8420bb12008-08-19 11:08:44 +0300331 return ret;
332}
333
334/**
335 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
336 * @pwrdm: struct powerdomain * to iterate over
337 * @fn: callback function *
338 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700339 * Call the supplied function @fn for each clockdomain in the powerdomain
340 * @pwrdm. The callback function can return anything but 0 to bail
Paul Walmsleye909d62a82010-01-26 20:13:00 -0700341 * out early from the iterator. Returns -EINVAL if presented with
342 * invalid pointers; or passes along the last return value of the
343 * callback function, which should be 0 for success or anything else
344 * to indicate failure.
Paul Walmsley8420bb12008-08-19 11:08:44 +0300345 */
346int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
347 int (*fn)(struct powerdomain *pwrdm,
348 struct clockdomain *clkdm))
349{
Paul Walmsley8420bb12008-08-19 11:08:44 +0300350 int ret = 0;
351 int i;
352
353 if (!fn)
354 return -EINVAL;
355
Paul Walmsley8420bb12008-08-19 11:08:44 +0300356 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
357 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
358
Paul Walmsley8420bb12008-08-19 11:08:44 +0300359 return ret;
360}
361
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300362/**
363 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
364 * @pwrdm: struct powerdomain *
365 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700366 * Return the number of controllable memory banks in powerdomain @pwrdm,
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300367 * starting with 1. Returns -EINVAL if the powerdomain pointer is null.
368 */
369int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
370{
371 if (!pwrdm)
372 return -EINVAL;
373
374 return pwrdm->banks;
375}
376
377/**
378 * pwrdm_set_next_pwrst - set next powerdomain power state
379 * @pwrdm: struct powerdomain * to set
380 * @pwrst: one of the PWRDM_POWER_* macros
381 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700382 * Set the powerdomain @pwrdm's next power state to @pwrst. The powerdomain
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300383 * may not enter this state immediately if the preconditions for this state
384 * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
385 * null or if the power state is invalid for the powerdomin, or returns 0
386 * upon success.
387 */
388int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
389{
Rajendra Nayakf327e072010-12-21 20:01:18 -0700390 int ret = -EINVAL;
391
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300392 if (!pwrdm)
393 return -EINVAL;
394
395 if (!(pwrdm->pwrsts & (1 << pwrst)))
396 return -EINVAL;
397
398 pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
399 pwrdm->name, pwrst);
400
Rajendra Nayakf327e072010-12-21 20:01:18 -0700401 if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst)
402 ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300403
Rajendra Nayakf327e072010-12-21 20:01:18 -0700404 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300405}
406
407/**
408 * pwrdm_read_next_pwrst - get next powerdomain power state
409 * @pwrdm: struct powerdomain * to get power state
410 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700411 * Return the powerdomain @pwrdm's next power state. Returns -EINVAL
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300412 * if the powerdomain pointer is null or returns the next power state
413 * upon success.
414 */
415int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
416{
Rajendra Nayakf327e072010-12-21 20:01:18 -0700417 int ret = -EINVAL;
418
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300419 if (!pwrdm)
420 return -EINVAL;
421
Rajendra Nayakf327e072010-12-21 20:01:18 -0700422 if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
423 ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
424
425 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300426}
427
428/**
429 * pwrdm_read_pwrst - get current powerdomain power state
430 * @pwrdm: struct powerdomain * to get power state
431 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700432 * Return the powerdomain @pwrdm's current power state. Returns -EINVAL
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300433 * if the powerdomain pointer is null or returns the current power state
434 * upon success.
435 */
436int pwrdm_read_pwrst(struct powerdomain *pwrdm)
437{
Rajendra Nayakf327e072010-12-21 20:01:18 -0700438 int ret = -EINVAL;
439
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300440 if (!pwrdm)
441 return -EINVAL;
442
Rajendra Nayakf327e072010-12-21 20:01:18 -0700443 if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
444 ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
445
446 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300447}
448
449/**
450 * pwrdm_read_prev_pwrst - get previous powerdomain power state
451 * @pwrdm: struct powerdomain * to get previous power state
452 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700453 * Return the powerdomain @pwrdm's previous power state. Returns -EINVAL
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300454 * if the powerdomain pointer is null or returns the previous power state
455 * upon success.
456 */
457int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
458{
Rajendra Nayakf327e072010-12-21 20:01:18 -0700459 int ret = -EINVAL;
460
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300461 if (!pwrdm)
462 return -EINVAL;
463
Rajendra Nayakf327e072010-12-21 20:01:18 -0700464 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
465 ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
466
467 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300468}
469
470/**
471 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
472 * @pwrdm: struct powerdomain * to set
473 * @pwrst: one of the PWRDM_POWER_* macros
474 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700475 * Set the next power state @pwrst that the logic portion of the
476 * powerdomain @pwrdm will enter when the powerdomain enters retention.
477 * This will be either RETENTION or OFF, if supported. Returns
478 * -EINVAL if the powerdomain pointer is null or the target power
479 * state is not not supported, or returns 0 upon success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300480 */
481int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
482{
Rajendra Nayak12627572010-12-21 20:01:18 -0700483 int ret = -EINVAL;
Paul Walmsley2bc4ef72010-05-18 18:47:24 -0600484
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300485 if (!pwrdm)
486 return -EINVAL;
487
488 if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
489 return -EINVAL;
490
491 pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
492 pwrdm->name, pwrst);
493
Rajendra Nayak12627572010-12-21 20:01:18 -0700494 if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
495 ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300496
Rajendra Nayak12627572010-12-21 20:01:18 -0700497 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300498}
499
500/**
501 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
502 * @pwrdm: struct powerdomain * to set
503 * @bank: memory bank number to set (0-3)
504 * @pwrst: one of the PWRDM_POWER_* macros
505 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700506 * Set the next power state @pwrst that memory bank @bank of the
507 * powerdomain @pwrdm will enter when the powerdomain enters the ON
508 * state. @bank will be a number from 0 to 3, and represents different
509 * types of memory, depending on the powerdomain. Returns -EINVAL if
510 * the powerdomain pointer is null or the target power state is not
511 * not supported for this memory bank, -EEXIST if the target memory
512 * bank does not exist or is not controllable, or returns 0 upon
513 * success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300514 */
515int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
516{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700517 int ret = -EINVAL;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300518
519 if (!pwrdm)
520 return -EINVAL;
521
522 if (pwrdm->banks < (bank + 1))
523 return -EEXIST;
524
525 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
526 return -EINVAL;
527
528 pr_debug("powerdomain: setting next memory powerstate for domain %s "
529 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
530
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700531 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
532 ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300533
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700534 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300535}
536
537/**
538 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
539 * @pwrdm: struct powerdomain * to set
540 * @bank: memory bank number to set (0-3)
541 * @pwrst: one of the PWRDM_POWER_* macros
542 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700543 * Set the next power state @pwrst that memory bank @bank of the
544 * powerdomain @pwrdm will enter when the powerdomain enters the
545 * RETENTION state. Bank will be a number from 0 to 3, and represents
546 * different types of memory, depending on the powerdomain. @pwrst
547 * will be either RETENTION or OFF, if supported. Returns -EINVAL if
548 * the powerdomain pointer is null or the target power state is not
549 * not supported for this memory bank, -EEXIST if the target memory
550 * bank does not exist or is not controllable, or returns 0 upon
551 * success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300552 */
553int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
554{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700555 int ret = -EINVAL;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300556
557 if (!pwrdm)
558 return -EINVAL;
559
560 if (pwrdm->banks < (bank + 1))
561 return -EEXIST;
562
563 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
564 return -EINVAL;
565
566 pr_debug("powerdomain: setting next memory powerstate for domain %s "
567 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
568
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700569 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
570 ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300571
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700572 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300573}
574
575/**
576 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
577 * @pwrdm: struct powerdomain * to get current logic retention power state
578 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700579 * Return the power state that the logic portion of powerdomain @pwrdm
580 * will enter when the powerdomain enters retention. Returns -EINVAL
581 * if the powerdomain pointer is null or returns the logic retention
582 * power state upon success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300583 */
584int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
585{
Rajendra Nayak12627572010-12-21 20:01:18 -0700586 int ret = -EINVAL;
587
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300588 if (!pwrdm)
589 return -EINVAL;
590
Rajendra Nayak12627572010-12-21 20:01:18 -0700591 if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
592 ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
593
594 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300595}
596
597/**
598 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
599 * @pwrdm: struct powerdomain * to get previous logic power state
600 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700601 * Return the powerdomain @pwrdm's previous logic power state. Returns
602 * -EINVAL if the powerdomain pointer is null or returns the previous
603 * logic power state upon success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300604 */
605int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
606{
Rajendra Nayak12627572010-12-21 20:01:18 -0700607 int ret = -EINVAL;
608
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300609 if (!pwrdm)
610 return -EINVAL;
611
Rajendra Nayak12627572010-12-21 20:01:18 -0700612 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
613 ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
614
615 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300616}
617
618/**
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700619 * pwrdm_read_logic_retst - get next powerdomain logic power state
620 * @pwrdm: struct powerdomain * to get next logic power state
621 *
622 * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
623 * if the powerdomain pointer is null or returns the next logic
624 * power state upon success.
625 */
626int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
627{
Rajendra Nayak12627572010-12-21 20:01:18 -0700628 int ret = -EINVAL;
629
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700630 if (!pwrdm)
631 return -EINVAL;
632
Rajendra Nayak12627572010-12-21 20:01:18 -0700633 if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
634 ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
635
636 return ret;
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700637}
638
639/**
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300640 * pwrdm_read_mem_pwrst - get current memory bank power state
641 * @pwrdm: struct powerdomain * to get current memory bank power state
642 * @bank: memory bank number (0-3)
643 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700644 * Return the powerdomain @pwrdm's current memory power state for bank
645 * @bank. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300646 * the target memory bank does not exist or is not controllable, or
647 * returns the current memory power state upon success.
648 */
649int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
650{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700651 int ret = -EINVAL;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300652
653 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700654 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300655
656 if (pwrdm->banks < (bank + 1))
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700657 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300658
Thara Gopinath3863c742009-12-08 16:33:15 -0700659 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
660 bank = 1;
661
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700662 if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
663 ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300664
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700665 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300666}
667
668/**
669 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
670 * @pwrdm: struct powerdomain * to get previous memory bank power state
671 * @bank: memory bank number (0-3)
672 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700673 * Return the powerdomain @pwrdm's previous memory power state for
674 * bank @bank. Returns -EINVAL if the powerdomain pointer is null,
675 * -EEXIST if the target memory bank does not exist or is not
676 * controllable, or returns the previous memory power state upon
677 * success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300678 */
679int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
680{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700681 int ret = -EINVAL;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300682
683 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700684 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300685
686 if (pwrdm->banks < (bank + 1))
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700687 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300688
Thara Gopinath3863c742009-12-08 16:33:15 -0700689 if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
690 bank = 1;
691
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700692 if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
693 ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300694
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700695 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300696}
697
698/**
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700699 * pwrdm_read_mem_retst - get next memory bank power state
700 * @pwrdm: struct powerdomain * to get mext memory bank power state
701 * @bank: memory bank number (0-3)
702 *
703 * Return the powerdomain pwrdm's next memory power state for bank
704 * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
705 * the target memory bank does not exist or is not controllable, or
706 * returns the next memory power state upon success.
707 */
708int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
709{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700710 int ret = -EINVAL;
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700711
712 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700713 return ret;
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700714
715 if (pwrdm->banks < (bank + 1))
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700716 return ret;
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700717
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700718 if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
719 ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700720
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700721 return ret;
Thara Gopinath1e3d0d22010-02-24 12:05:49 -0700722}
723
724/**
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300725 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
726 * @pwrdm: struct powerdomain * to clear
727 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700728 * Clear the powerdomain's previous power state register @pwrdm.
729 * Clears the entire register, including logic and memory bank
730 * previous power states. Returns -EINVAL if the powerdomain pointer
731 * is null, or returns 0 upon success.
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300732 */
733int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
734{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700735 int ret = -EINVAL;
736
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300737 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700738 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300739
740 /*
741 * XXX should get the powerdomain's current state here;
742 * warn & fail if it is not ON.
743 */
744
745 pr_debug("powerdomain: clearing previous power state reg for %s\n",
746 pwrdm->name);
747
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700748 if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
749 ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300750
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700751 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300752}
753
754/**
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600755 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
756 * @pwrdm: struct powerdomain *
757 *
758 * Enable automatic context save-and-restore upon power state change
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700759 * for some devices in the powerdomain @pwrdm. Warning: this only
760 * affects a subset of devices in a powerdomain; check the TRM
761 * closely. Returns -EINVAL if the powerdomain pointer is null or if
762 * the powerdomain does not support automatic save-and-restore, or
763 * returns 0 upon success.
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600764 */
765int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
766{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700767 int ret = -EINVAL;
768
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600769 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700770 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600771
772 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700773 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600774
775 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
776 pwrdm->name);
777
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700778 if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
779 ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600780
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700781 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600782}
783
784/**
785 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
786 * @pwrdm: struct powerdomain *
787 *
788 * Disable automatic context save-and-restore upon power state change
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700789 * for some devices in the powerdomain @pwrdm. Warning: this only
790 * affects a subset of devices in a powerdomain; check the TRM
791 * closely. Returns -EINVAL if the powerdomain pointer is null or if
792 * the powerdomain does not support automatic save-and-restore, or
793 * returns 0 upon success.
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600794 */
795int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
796{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700797 int ret = -EINVAL;
798
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600799 if (!pwrdm)
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700800 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600801
802 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700803 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600804
805 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
806 pwrdm->name);
807
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700808 if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
809 ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600810
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700811 return ret;
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600812}
813
814/**
815 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
816 * @pwrdm: struct powerdomain *
817 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700818 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
Paul Walmsley0b7cbfb2008-06-25 18:09:37 -0600819 * for some devices, or 0 if it does not.
820 */
821bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
822{
823 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
824}
825
826/**
Rajendra Nayak90dbc7b2010-05-18 20:24:03 -0600827 * pwrdm_set_lowpwrstchange - Request a low power state change
828 * @pwrdm: struct powerdomain *
829 *
830 * Allows a powerdomain to transtion to a lower power sleep state
831 * from an existing sleep state without waking up the powerdomain.
832 * Returns -EINVAL if the powerdomain pointer is null or if the
833 * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
834 * upon success.
835 */
836int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
837{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700838 int ret = -EINVAL;
839
Rajendra Nayak90dbc7b2010-05-18 20:24:03 -0600840 if (!pwrdm)
841 return -EINVAL;
842
843 if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
844 return -EINVAL;
845
846 pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
847 pwrdm->name);
848
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700849 if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
850 ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
Rajendra Nayak90dbc7b2010-05-18 20:24:03 -0600851
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700852 return ret;
Rajendra Nayak90dbc7b2010-05-18 20:24:03 -0600853}
854
855/**
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300856 * pwrdm_wait_transition - wait for powerdomain power transition to finish
857 * @pwrdm: struct powerdomain * to wait for
858 *
Paul Walmsleyf0271d62010-01-26 20:13:02 -0700859 * If the powerdomain @pwrdm is in the process of a state transition,
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300860 * spin until it completes the power transition, or until an iteration
861 * bailout value is reached. Returns -EINVAL if the powerdomain
862 * pointer is null, -EAGAIN if the bailout value was reached, or
863 * returns 0 upon success.
864 */
865int pwrdm_wait_transition(struct powerdomain *pwrdm)
866{
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700867 int ret = -EINVAL;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300868
869 if (!pwrdm)
870 return -EINVAL;
871
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700872 if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
873 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300874
Rajendra Nayak9b7fc902010-12-21 20:01:19 -0700875 return ret;
Paul Walmsleyad67ef62008-08-19 11:08:40 +0300876}
877
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300878int pwrdm_state_switch(struct powerdomain *pwrdm)
879{
880 return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
881}
882
883int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
884{
885 if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
886 pwrdm_wait_transition(clkdm->pwrdm.ptr);
887 return pwrdm_state_switch(clkdm->pwrdm.ptr);
888 }
889
890 return -EINVAL;
891}
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300892
893int pwrdm_pre_transition(void)
894{
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300895 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300896 return 0;
897}
898
899int pwrdm_post_transition(void)
900{
Peter 'p2' De Schrijver6199ab22008-10-15 18:13:49 +0300901 pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
Peter 'p2' De Schrijverba20bb12008-10-15 17:48:43 +0300902 return 0;
903}