diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 23:11:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 23:11:00 -0400 |
commit | 952414505f55afe5cd6dc004765076aa22b3ed7e (patch) | |
tree | eba11ed702ae02fea7f1a0d422346454fc98296f /arch/arm/mach-omap2/clockdomain.c | |
parent | 68e24ba70465b82ad24e0774ceab5360180d4627 (diff) | |
parent | 3e965b176341b78620f7404fd8b7f9a0d061f8a2 (diff) |
Merge branch 'next/cleanup' of git://git.linaro.org/people/arnd/arm-soc
* 'next/cleanup' of git://git.linaro.org/people/arnd/arm-soc: (125 commits)
ARM: mach-mxs: fix machines' initializers order
mmc: mxcmmc: explicitly includes mach/hardware.h
arm/imx: explicitly includes mach/hardware.h in pm-imx27.c
arm/imx: remove mx27_setup_weimcs() from mx27.h
arm/imx: explicitly includes mach/hardware.h in mach-kzm_arm11_01.c
arm/imx: remove mx31_setup_weimcs() from mx31.h
ARM: tegra: devices.c should include devices.h
ARM: tegra: cpu-tegra: unexport two functions
ARM: tegra: cpu-tegra: sparse type fix
ARM: tegra: dma: staticify some tables and functions
ARM: tegra: tegra2_clocks: don't export some tables
ARM: tegra: tegra_powergate_is_powered should be static
ARM: tegra: tegra_rtc_read_ms should be static
ARM: tegra: tegra_init_cache should be static
ARM: tegra: pcie: 0 -> NULL changes
ARM: tegra: pcie: include board.h
ARM: tegra: pcie: don't cast __iomem pointers
ARM: tegra: tegra2_clocks: 0 -> NULL changes
ARM: tegra: tegra2_clocks: don't cast __iomem pointers
ARM: tegra: timer: don't cast __iomem pointers
...
Fix up trivial conflicts in
arch/arm/mach-omap2/Makefile,
arch/arm/mach-u300/{Makefile.boot,core.c}
arch/arm/plat-{mxc,omap}/devices.c
Diffstat (limited to 'arch/arm/mach-omap2/clockdomain.c')
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 149 |
1 files changed, 102 insertions, 47 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 8f0890685d7b..8480ee4344ea 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -73,9 +73,6 @@ static int _clkdm_register(struct clockdomain *clkdm) | |||
73 | if (!clkdm || !clkdm->name) | 73 | if (!clkdm || !clkdm->name) |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | 75 | ||
76 | if (!omap_chip_is(clkdm->omap_chip)) | ||
77 | return -EINVAL; | ||
78 | |||
79 | pwrdm = pwrdm_lookup(clkdm->pwrdm.name); | 76 | pwrdm = pwrdm_lookup(clkdm->pwrdm.name); |
80 | if (!pwrdm) { | 77 | if (!pwrdm) { |
81 | pr_err("clockdomain: %s: powerdomain %s does not exist\n", | 78 | pr_err("clockdomain: %s: powerdomain %s does not exist\n", |
@@ -105,13 +102,10 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm, | |||
105 | { | 102 | { |
106 | struct clkdm_dep *cd; | 103 | struct clkdm_dep *cd; |
107 | 104 | ||
108 | if (!clkdm || !deps || !omap_chip_is(clkdm->omap_chip)) | 105 | if (!clkdm || !deps) |
109 | return ERR_PTR(-EINVAL); | 106 | return ERR_PTR(-EINVAL); |
110 | 107 | ||
111 | for (cd = deps; cd->clkdm_name; cd++) { | 108 | for (cd = deps; cd->clkdm_name; cd++) { |
112 | if (!omap_chip_is(cd->omap_chip)) | ||
113 | continue; | ||
114 | |||
115 | if (!cd->clkdm && cd->clkdm_name) | 109 | if (!cd->clkdm && cd->clkdm_name) |
116 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); | 110 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); |
117 | 111 | ||
@@ -148,9 +142,6 @@ static void _autodep_lookup(struct clkdm_autodep *autodep) | |||
148 | if (!autodep) | 142 | if (!autodep) |
149 | return; | 143 | return; |
150 | 144 | ||
151 | if (!omap_chip_is(autodep->omap_chip)) | ||
152 | return; | ||
153 | |||
154 | clkdm = clkdm_lookup(autodep->clkdm.name); | 145 | clkdm = clkdm_lookup(autodep->clkdm.name); |
155 | if (!clkdm) { | 146 | if (!clkdm) { |
156 | pr_err("clockdomain: autodeps: clockdomain %s does not exist\n", | 147 | pr_err("clockdomain: autodeps: clockdomain %s does not exist\n", |
@@ -182,9 +173,6 @@ void _clkdm_add_autodeps(struct clockdomain *clkdm) | |||
182 | if (IS_ERR(autodep->clkdm.ptr)) | 173 | if (IS_ERR(autodep->clkdm.ptr)) |
183 | continue; | 174 | continue; |
184 | 175 | ||
185 | if (!omap_chip_is(autodep->omap_chip)) | ||
186 | continue; | ||
187 | |||
188 | pr_debug("clockdomain: adding %s sleepdep/wkdep for " | 176 | pr_debug("clockdomain: adding %s sleepdep/wkdep for " |
189 | "clkdm %s\n", autodep->clkdm.ptr->name, | 177 | "clkdm %s\n", autodep->clkdm.ptr->name, |
190 | clkdm->name); | 178 | clkdm->name); |
@@ -216,9 +204,6 @@ void _clkdm_del_autodeps(struct clockdomain *clkdm) | |||
216 | if (IS_ERR(autodep->clkdm.ptr)) | 204 | if (IS_ERR(autodep->clkdm.ptr)) |
217 | continue; | 205 | continue; |
218 | 206 | ||
219 | if (!omap_chip_is(autodep->omap_chip)) | ||
220 | continue; | ||
221 | |||
222 | pr_debug("clockdomain: removing %s sleepdep/wkdep for " | 207 | pr_debug("clockdomain: removing %s sleepdep/wkdep for " |
223 | "clkdm %s\n", autodep->clkdm.ptr->name, | 208 | "clkdm %s\n", autodep->clkdm.ptr->name, |
224 | clkdm->name); | 209 | clkdm->name); |
@@ -243,8 +228,6 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm, | |||
243 | struct clkdm_dep *cd; | 228 | struct clkdm_dep *cd; |
244 | 229 | ||
245 | for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { | 230 | for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { |
246 | if (!omap_chip_is(cd->omap_chip)) | ||
247 | continue; | ||
248 | if (cd->clkdm) | 231 | if (cd->clkdm) |
249 | continue; | 232 | continue; |
250 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); | 233 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); |
@@ -257,43 +240,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm, | |||
257 | /* Public functions */ | 240 | /* Public functions */ |
258 | 241 | ||
259 | /** | 242 | /** |
260 | * clkdm_init - set up the clockdomain layer | 243 | * clkdm_register_platform_funcs - register clockdomain implementation fns |
261 | * @clkdms: optional pointer to an array of clockdomains to register | 244 | * @co: func pointers for arch specific implementations |
262 | * @init_autodeps: optional pointer to an array of autodeps to register | 245 | * |
263 | * @custom_funcs: func pointers for arch specific implementations | 246 | * Register the list of function pointers used to implement the |
264 | * | 247 | * clockdomain functions on different OMAP SoCs. Should be called |
265 | * Set up internal state. If a pointer to an array of clockdomains | 248 | * before any other clkdm_register*() function. Returns -EINVAL if |
266 | * @clkdms was supplied, loop through the list of clockdomains, | 249 | * @co is null, -EEXIST if platform functions have already been |
267 | * register all that are available on the current platform. Similarly, | 250 | * registered, or 0 upon success. |
268 | * if a pointer to an array of clockdomain autodependencies | 251 | */ |
269 | * @init_autodeps was provided, register those. No return value. | 252 | int clkdm_register_platform_funcs(struct clkdm_ops *co) |
253 | { | ||
254 | if (!co) | ||
255 | return -EINVAL; | ||
256 | |||
257 | if (arch_clkdm) | ||
258 | return -EEXIST; | ||
259 | |||
260 | arch_clkdm = co; | ||
261 | |||
262 | return 0; | ||
263 | }; | ||
264 | |||
265 | /** | ||
266 | * clkdm_register_clkdms - register SoC clockdomains | ||
267 | * @cs: pointer to an array of struct clockdomain to register | ||
268 | * | ||
269 | * Register the clockdomains available on a particular OMAP SoC. Must | ||
270 | * be called after clkdm_register_platform_funcs(). May be called | ||
271 | * multiple times. Returns -EACCES if called before | ||
272 | * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is | ||
273 | * null; or 0 upon success. | ||
270 | */ | 274 | */ |
271 | void clkdm_init(struct clockdomain **clkdms, | 275 | int clkdm_register_clkdms(struct clockdomain **cs) |
272 | struct clkdm_autodep *init_autodeps, | ||
273 | struct clkdm_ops *custom_funcs) | ||
274 | { | 276 | { |
275 | struct clockdomain **c = NULL; | 277 | struct clockdomain **c = NULL; |
276 | struct clockdomain *clkdm; | ||
277 | struct clkdm_autodep *autodep = NULL; | ||
278 | 278 | ||
279 | if (!custom_funcs) | 279 | if (!arch_clkdm) |
280 | WARN(1, "No custom clkdm functions registered\n"); | 280 | return -EACCES; |
281 | else | 281 | |
282 | arch_clkdm = custom_funcs; | 282 | if (!cs) |
283 | return -EINVAL; | ||
284 | |||
285 | for (c = cs; *c; c++) | ||
286 | _clkdm_register(*c); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * clkdm_register_autodeps - register autodeps (if required) | ||
293 | * @ia: pointer to a static array of struct clkdm_autodep to register | ||
294 | * | ||
295 | * Register clockdomain "automatic dependencies." These are | ||
296 | * clockdomain wakeup and sleep dependencies that are automatically | ||
297 | * added whenever the first clock inside a clockdomain is enabled, and | ||
298 | * removed whenever the last clock inside a clockdomain is disabled. | ||
299 | * These are currently only used on OMAP3 devices, and are deprecated, | ||
300 | * since they waste energy. However, until the OMAP2/3 IP block | ||
301 | * enable/disable sequence can be converted to match the OMAP4 | ||
302 | * sequence, they are needed. | ||
303 | * | ||
304 | * Must be called only after all of the SoC clockdomains are | ||
305 | * registered, since the function will resolve autodep clockdomain | ||
306 | * names into clockdomain pointers. | ||
307 | * | ||
308 | * The struct clkdm_autodep @ia array must be static, as this function | ||
309 | * does not copy the array elements. | ||
310 | * | ||
311 | * Returns -EACCES if called before any clockdomains have been | ||
312 | * registered, -EINVAL if called with a null @ia argument, -EEXIST if | ||
313 | * autodeps have already been registered, or 0 upon success. | ||
314 | */ | ||
315 | int clkdm_register_autodeps(struct clkdm_autodep *ia) | ||
316 | { | ||
317 | struct clkdm_autodep *a = NULL; | ||
283 | 318 | ||
284 | if (clkdms) | 319 | if (list_empty(&clkdm_list)) |
285 | for (c = clkdms; *c; c++) | 320 | return -EACCES; |
286 | _clkdm_register(*c); | 321 | |
322 | if (!ia) | ||
323 | return -EINVAL; | ||
287 | 324 | ||
288 | autodeps = init_autodeps; | ||
289 | if (autodeps) | 325 | if (autodeps) |
290 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) | 326 | return -EEXIST; |
291 | _autodep_lookup(autodep); | 327 | |
328 | autodeps = ia; | ||
329 | for (a = autodeps; a->clkdm.ptr; a++) | ||
330 | _autodep_lookup(a); | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * clkdm_complete_init - set up the clockdomain layer | ||
337 | * | ||
338 | * Put all clockdomains into software-supervised mode; PM code should | ||
339 | * later enable hardware-supervised mode as appropriate. Must be | ||
340 | * called after clkdm_register_clkdms(). Returns -EACCES if called | ||
341 | * before clkdm_register_clkdms(), or 0 upon success. | ||
342 | */ | ||
343 | int clkdm_complete_init(void) | ||
344 | { | ||
345 | struct clockdomain *clkdm; | ||
346 | |||
347 | if (list_empty(&clkdm_list)) | ||
348 | return -EACCES; | ||
292 | 349 | ||
293 | /* | ||
294 | * Put all clockdomains into software-supervised mode; PM code | ||
295 | * should later enable hardware-supervised mode as appropriate | ||
296 | */ | ||
297 | list_for_each_entry(clkdm, &clkdm_list, node) { | 350 | list_for_each_entry(clkdm, &clkdm_list, node) { |
298 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | 351 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) |
299 | clkdm_wakeup(clkdm); | 352 | clkdm_wakeup(clkdm); |
@@ -306,6 +359,8 @@ void clkdm_init(struct clockdomain **clkdms, | |||
306 | _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); | 359 | _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); |
307 | clkdm_clear_all_sleepdeps(clkdm); | 360 | clkdm_clear_all_sleepdeps(clkdm); |
308 | } | 361 | } |
362 | |||
363 | return 0; | ||
309 | } | 364 | } |
310 | 365 | ||
311 | /** | 366 | /** |