OMAP: hwmod: Fix softreset for modules with optional clocks
[deliverable/linux.git] / arch / arm / mach-omap2 / omap_hwmod.c
CommitLineData
63c85238
PW
1/*
2 * omap_hwmod implementation for OMAP2/3/4
3 *
db2a60bf 4 * Copyright (C) 2009-2010 Nokia Corporation
63c85238 5 *
4788da26
PW
6 * Paul Walmsley, Benoît Cousson, Kevin Hilman
7 *
8 * Created in collaboration with (alphabetical order): Thara Gopinath,
9 * Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari Poussa, Anand
10 * Sawant, Santosh Shilimkar, Richard Woodruff
63c85238
PW
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This code manages "OMAP modules" (on-chip devices) and their
17 * integration with Linux device driver and bus code.
18 *
19 * References:
20 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
21 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
22 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
23 * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
24 * - Open Core Protocol Specification 2.2
25 *
26 * To do:
27 * - pin mux handling
28 * - handle IO mapping
29 * - bus throughput & module latency measurement code
30 *
31 * XXX add tests at the beginning of each function to ensure the hwmod is
32 * in the appropriate state
33 * XXX error return values should be checked to ensure that they are
34 * appropriate
35 */
36#undef DEBUG
37
38#include <linux/kernel.h>
39#include <linux/errno.h>
40#include <linux/io.h>
41#include <linux/clk.h>
42#include <linux/delay.h>
43#include <linux/err.h>
44#include <linux/list.h>
45#include <linux/mutex.h>
63c85238 46
6f8b7ff5 47#include <plat/common.h>
ce491cf8
TL
48#include <plat/cpu.h>
49#include <plat/clockdomain.h>
50#include <plat/powerdomain.h>
51#include <plat/clock.h>
52#include <plat/omap_hwmod.h>
5365efbe 53#include <plat/prcm.h>
63c85238
PW
54
55#include "cm.h"
5365efbe 56#include "prm.h"
63c85238 57
5365efbe
BC
58/* Maximum microseconds to wait for OMAP module to softreset */
59#define MAX_MODULE_SOFTRESET_WAIT 10000
63c85238
PW
60
61/* Name of the OMAP hwmod for the MPU */
5c2c0296 62#define MPU_INITIATOR_NAME "mpu"
63c85238
PW
63
64/* omap_hwmod_list contains all registered struct omap_hwmods */
65static LIST_HEAD(omap_hwmod_list);
66
67static DEFINE_MUTEX(omap_hwmod_mutex);
68
69/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
70static struct omap_hwmod *mpu_oh;
71
72/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */
73static u8 inited;
74
75
76/* Private functions */
77
78/**
79 * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy
80 * @oh: struct omap_hwmod *
81 *
82 * Load the current value of the hwmod OCP_SYSCONFIG register into the
83 * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no
84 * OCP_SYSCONFIG register or 0 upon success.
85 */
86static int _update_sysc_cache(struct omap_hwmod *oh)
87{
43b40992
PW
88 if (!oh->class->sysc) {
89 WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
63c85238
PW
90 return -EINVAL;
91 }
92
93 /* XXX ensure module interface clock is up */
94
43b40992 95 oh->_sysc_cache = omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
63c85238 96
43b40992 97 if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
883edfdd 98 oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
63c85238
PW
99
100 return 0;
101}
102
103/**
104 * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register
105 * @v: OCP_SYSCONFIG value to write
106 * @oh: struct omap_hwmod *
107 *
43b40992
PW
108 * Write @v into the module class' OCP_SYSCONFIG register, if it has
109 * one. No return value.
63c85238
PW
110 */
111static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
112{
43b40992
PW
113 if (!oh->class->sysc) {
114 WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
63c85238
PW
115 return;
116 }
117
118 /* XXX ensure module interface clock is up */
119
120 if (oh->_sysc_cache != v) {
121 oh->_sysc_cache = v;
43b40992 122 omap_hwmod_writel(v, oh, oh->class->sysc->sysc_offs);
63c85238
PW
123 }
124}
125
126/**
127 * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v
128 * @oh: struct omap_hwmod *
129 * @standbymode: MIDLEMODE field bits
130 * @v: pointer to register contents to modify
131 *
132 * Update the master standby mode bits in @v to be @standbymode for
133 * the @oh hwmod. Does not write to the hardware. Returns -EINVAL
134 * upon error or 0 upon success.
135 */
136static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
137 u32 *v)
138{
358f0e63
TG
139 u32 mstandby_mask;
140 u8 mstandby_shift;
141
43b40992
PW
142 if (!oh->class->sysc ||
143 !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
63c85238
PW
144 return -EINVAL;
145
43b40992
PW
146 if (!oh->class->sysc->sysc_fields) {
147 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
148 return -EINVAL;
149 }
150
43b40992 151 mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
358f0e63
TG
152 mstandby_mask = (0x3 << mstandby_shift);
153
154 *v &= ~mstandby_mask;
155 *v |= __ffs(standbymode) << mstandby_shift;
63c85238
PW
156
157 return 0;
158}
159
160/**
161 * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v
162 * @oh: struct omap_hwmod *
163 * @idlemode: SIDLEMODE field bits
164 * @v: pointer to register contents to modify
165 *
166 * Update the slave idle mode bits in @v to be @idlemode for the @oh
167 * hwmod. Does not write to the hardware. Returns -EINVAL upon error
168 * or 0 upon success.
169 */
170static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
171{
358f0e63
TG
172 u32 sidle_mask;
173 u8 sidle_shift;
174
43b40992
PW
175 if (!oh->class->sysc ||
176 !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
63c85238
PW
177 return -EINVAL;
178
43b40992
PW
179 if (!oh->class->sysc->sysc_fields) {
180 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
181 return -EINVAL;
182 }
183
43b40992 184 sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
358f0e63
TG
185 sidle_mask = (0x3 << sidle_shift);
186
187 *v &= ~sidle_mask;
188 *v |= __ffs(idlemode) << sidle_shift;
63c85238
PW
189
190 return 0;
191}
192
193/**
194 * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
195 * @oh: struct omap_hwmod *
196 * @clockact: CLOCKACTIVITY field bits
197 * @v: pointer to register contents to modify
198 *
199 * Update the clockactivity mode bits in @v to be @clockact for the
200 * @oh hwmod. Used for additional powersaving on some modules. Does
201 * not write to the hardware. Returns -EINVAL upon error or 0 upon
202 * success.
203 */
204static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
205{
358f0e63
TG
206 u32 clkact_mask;
207 u8 clkact_shift;
208
43b40992
PW
209 if (!oh->class->sysc ||
210 !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
63c85238
PW
211 return -EINVAL;
212
43b40992
PW
213 if (!oh->class->sysc->sysc_fields) {
214 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
215 return -EINVAL;
216 }
217
43b40992 218 clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
358f0e63
TG
219 clkact_mask = (0x3 << clkact_shift);
220
221 *v &= ~clkact_mask;
222 *v |= clockact << clkact_shift;
63c85238
PW
223
224 return 0;
225}
226
227/**
228 * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
229 * @oh: struct omap_hwmod *
230 * @v: pointer to register contents to modify
231 *
232 * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon
233 * error or 0 upon success.
234 */
235static int _set_softreset(struct omap_hwmod *oh, u32 *v)
236{
358f0e63
TG
237 u32 softrst_mask;
238
43b40992
PW
239 if (!oh->class->sysc ||
240 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
63c85238
PW
241 return -EINVAL;
242
43b40992
PW
243 if (!oh->class->sysc->sysc_fields) {
244 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
245 return -EINVAL;
246 }
247
43b40992 248 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
358f0e63
TG
249
250 *v |= softrst_mask;
63c85238
PW
251
252 return 0;
253}
254
726072e5
PW
255/**
256 * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
257 * @oh: struct omap_hwmod *
258 * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
259 * @v: pointer to register contents to modify
260 *
261 * Update the module autoidle bit in @v to be @autoidle for the @oh
262 * hwmod. The autoidle bit controls whether the module can gate
263 * internal clocks automatically when it isn't doing anything; the
264 * exact function of this bit varies on a per-module basis. This
265 * function does not write to the hardware. Returns -EINVAL upon
266 * error or 0 upon success.
267 */
268static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
269 u32 *v)
270{
358f0e63
TG
271 u32 autoidle_mask;
272 u8 autoidle_shift;
273
43b40992
PW
274 if (!oh->class->sysc ||
275 !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
726072e5
PW
276 return -EINVAL;
277
43b40992
PW
278 if (!oh->class->sysc->sysc_fields) {
279 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
280 return -EINVAL;
281 }
282
43b40992 283 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
358f0e63
TG
284 autoidle_mask = (0x3 << autoidle_shift);
285
286 *v &= ~autoidle_mask;
287 *v |= autoidle << autoidle_shift;
726072e5
PW
288
289 return 0;
290}
291
63c85238
PW
292/**
293 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
294 * @oh: struct omap_hwmod *
295 *
296 * Allow the hardware module @oh to send wakeups. Returns -EINVAL
297 * upon error or 0 upon success.
298 */
299static int _enable_wakeup(struct omap_hwmod *oh)
300{
358f0e63 301 u32 v, wakeup_mask;
63c85238 302
43b40992
PW
303 if (!oh->class->sysc ||
304 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
63c85238
PW
305 return -EINVAL;
306
43b40992
PW
307 if (!oh->class->sysc->sysc_fields) {
308 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
309 return -EINVAL;
310 }
311
43b40992 312 wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
358f0e63 313
63c85238 314 v = oh->_sysc_cache;
358f0e63 315 v |= wakeup_mask;
63c85238
PW
316 _write_sysconfig(v, oh);
317
318 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
319
320 oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
321
322 return 0;
323}
324
325/**
326 * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
327 * @oh: struct omap_hwmod *
328 *
329 * Prevent the hardware module @oh to send wakeups. Returns -EINVAL
330 * upon error or 0 upon success.
331 */
332static int _disable_wakeup(struct omap_hwmod *oh)
333{
358f0e63 334 u32 v, wakeup_mask;
63c85238 335
43b40992
PW
336 if (!oh->class->sysc ||
337 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
63c85238
PW
338 return -EINVAL;
339
43b40992
PW
340 if (!oh->class->sysc->sysc_fields) {
341 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
358f0e63
TG
342 return -EINVAL;
343 }
344
43b40992 345 wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
358f0e63 346
63c85238 347 v = oh->_sysc_cache;
358f0e63 348 v &= ~wakeup_mask;
63c85238
PW
349 _write_sysconfig(v, oh);
350
351 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
352
353 oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
354
355 return 0;
356}
357
358/**
359 * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
360 * @oh: struct omap_hwmod *
361 *
362 * Prevent the hardware module @oh from entering idle while the
363 * hardare module initiator @init_oh is active. Useful when a module
364 * will be accessed by a particular initiator (e.g., if a module will
365 * be accessed by the IVA, there should be a sleepdep between the IVA
366 * initiator and the module). Only applies to modules in smart-idle
367 * mode. Returns -EINVAL upon error or passes along
55ed9694 368 * clkdm_add_sleepdep() value upon success.
63c85238
PW
369 */
370static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
371{
372 if (!oh->_clk)
373 return -EINVAL;
374
55ed9694 375 return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
63c85238
PW
376}
377
378/**
379 * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active
380 * @oh: struct omap_hwmod *
381 *
382 * Allow the hardware module @oh to enter idle while the hardare
383 * module initiator @init_oh is active. Useful when a module will not
384 * be accessed by a particular initiator (e.g., if a module will not
385 * be accessed by the IVA, there should be no sleepdep between the IVA
386 * initiator and the module). Only applies to modules in smart-idle
387 * mode. Returns -EINVAL upon error or passes along
55ed9694 388 * clkdm_del_sleepdep() value upon success.
63c85238
PW
389 */
390static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
391{
392 if (!oh->_clk)
393 return -EINVAL;
394
55ed9694 395 return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
63c85238
PW
396}
397
398/**
399 * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
400 * @oh: struct omap_hwmod *
401 *
402 * Called from _init_clocks(). Populates the @oh _clk (main
403 * functional clock pointer) if a main_clk is present. Returns 0 on
404 * success or -EINVAL on error.
405 */
406static int _init_main_clk(struct omap_hwmod *oh)
407{
63c85238
PW
408 int ret = 0;
409
50ebdac2 410 if (!oh->main_clk)
63c85238
PW
411 return 0;
412
63403384 413 oh->_clk = omap_clk_get_by_name(oh->main_clk);
dc75925d 414 if (!oh->_clk) {
20383d82
BC
415 pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
416 oh->name, oh->main_clk);
63403384 417 return -EINVAL;
dc75925d 418 }
63c85238 419
63403384
BC
420 if (!oh->_clk->clkdm)
421 pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
422 oh->main_clk, oh->_clk->name);
81d7c6ff 423
63c85238
PW
424 return ret;
425}
426
427/**
887adeac 428 * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
63c85238
PW
429 * @oh: struct omap_hwmod *
430 *
431 * Called from _init_clocks(). Populates the @oh OCP slave interface
432 * clock pointers. Returns 0 on success or -EINVAL on error.
433 */
434static int _init_interface_clks(struct omap_hwmod *oh)
435{
63c85238
PW
436 struct clk *c;
437 int i;
438 int ret = 0;
439
440 if (oh->slaves_cnt == 0)
441 return 0;
442
682fdc96
BC
443 for (i = 0; i < oh->slaves_cnt; i++) {
444 struct omap_hwmod_ocp_if *os = oh->slaves[i];
445
50ebdac2 446 if (!os->clk)
63c85238
PW
447 continue;
448
50ebdac2 449 c = omap_clk_get_by_name(os->clk);
dc75925d 450 if (!c) {
20383d82
BC
451 pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
452 oh->name, os->clk);
63c85238 453 ret = -EINVAL;
dc75925d 454 }
63c85238
PW
455 os->_clk = c;
456 }
457
458 return ret;
459}
460
461/**
462 * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
463 * @oh: struct omap_hwmod *
464 *
465 * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk
466 * clock pointers. Returns 0 on success or -EINVAL on error.
467 */
468static int _init_opt_clks(struct omap_hwmod *oh)
469{
470 struct omap_hwmod_opt_clk *oc;
471 struct clk *c;
472 int i;
473 int ret = 0;
474
475 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
50ebdac2 476 c = omap_clk_get_by_name(oc->clk);
dc75925d 477 if (!c) {
20383d82
BC
478 pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
479 oh->name, oc->clk);
63c85238 480 ret = -EINVAL;
dc75925d 481 }
63c85238
PW
482 oc->_clk = c;
483 }
484
485 return ret;
486}
487
488/**
489 * _enable_clocks - enable hwmod main clock and interface clocks
490 * @oh: struct omap_hwmod *
491 *
492 * Enables all clocks necessary for register reads and writes to succeed
493 * on the hwmod @oh. Returns 0.
494 */
495static int _enable_clocks(struct omap_hwmod *oh)
496{
63c85238
PW
497 int i;
498
499 pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
500
4d3ae5a9 501 if (oh->_clk)
63c85238
PW
502 clk_enable(oh->_clk);
503
504 if (oh->slaves_cnt > 0) {
682fdc96
BC
505 for (i = 0; i < oh->slaves_cnt; i++) {
506 struct omap_hwmod_ocp_if *os = oh->slaves[i];
63c85238
PW
507 struct clk *c = os->_clk;
508
4d3ae5a9 509 if (c && (os->flags & OCPIF_SWSUP_IDLE))
63c85238
PW
510 clk_enable(c);
511 }
512 }
513
514 /* The opt clocks are controlled by the device driver. */
515
516 return 0;
517}
518
519/**
520 * _disable_clocks - disable hwmod main clock and interface clocks
521 * @oh: struct omap_hwmod *
522 *
523 * Disables the hwmod @oh main functional and interface clocks. Returns 0.
524 */
525static int _disable_clocks(struct omap_hwmod *oh)
526{
63c85238
PW
527 int i;
528
529 pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
530
4d3ae5a9 531 if (oh->_clk)
63c85238
PW
532 clk_disable(oh->_clk);
533
534 if (oh->slaves_cnt > 0) {
682fdc96
BC
535 for (i = 0; i < oh->slaves_cnt; i++) {
536 struct omap_hwmod_ocp_if *os = oh->slaves[i];
63c85238
PW
537 struct clk *c = os->_clk;
538
4d3ae5a9 539 if (c && (os->flags & OCPIF_SWSUP_IDLE))
63c85238
PW
540 clk_disable(c);
541 }
542 }
543
544 /* The opt clocks are controlled by the device driver. */
545
546 return 0;
547}
548
96835af9
BC
549static void _enable_optional_clocks(struct omap_hwmod *oh)
550{
551 struct omap_hwmod_opt_clk *oc;
552 int i;
553
554 pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
555
556 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
557 if (oc->_clk) {
558 pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
559 oc->_clk->name);
560 clk_enable(oc->_clk);
561 }
562}
563
564static void _disable_optional_clocks(struct omap_hwmod *oh)
565{
566 struct omap_hwmod_opt_clk *oc;
567 int i;
568
569 pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
570
571 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
572 if (oc->_clk) {
573 pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
574 oc->_clk->name);
575 clk_disable(oc->_clk);
576 }
577}
578
63c85238
PW
579/**
580 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
581 * @oh: struct omap_hwmod *
582 *
583 * Returns the array index of the OCP slave port that the MPU
584 * addresses the device on, or -EINVAL upon error or not found.
585 */
586static int _find_mpu_port_index(struct omap_hwmod *oh)
587{
63c85238
PW
588 int i;
589 int found = 0;
590
591 if (!oh || oh->slaves_cnt == 0)
592 return -EINVAL;
593
682fdc96
BC
594 for (i = 0; i < oh->slaves_cnt; i++) {
595 struct omap_hwmod_ocp_if *os = oh->slaves[i];
596
63c85238
PW
597 if (os->user & OCP_USER_MPU) {
598 found = 1;
599 break;
600 }
601 }
602
603 if (found)
604 pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n",
605 oh->name, i);
606 else
607 pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n",
608 oh->name);
609
610 return (found) ? i : -EINVAL;
611}
612
613/**
614 * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU
615 * @oh: struct omap_hwmod *
616 *
617 * Return the virtual address of the base of the register target of
618 * device @oh, or NULL on error.
619 */
620static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
621{
622 struct omap_hwmod_ocp_if *os;
623 struct omap_hwmod_addr_space *mem;
624 int i;
625 int found = 0;
986a13f5 626 void __iomem *va_start;
63c85238
PW
627
628 if (!oh || oh->slaves_cnt == 0)
629 return NULL;
630
682fdc96 631 os = oh->slaves[index];
63c85238
PW
632
633 for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) {
634 if (mem->flags & ADDR_TYPE_RT) {
635 found = 1;
636 break;
637 }
638 }
639
986a13f5
TL
640 if (found) {
641 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
642 if (!va_start) {
643 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
644 return NULL;
645 }
63c85238 646 pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
986a13f5
TL
647 oh->name, va_start);
648 } else {
63c85238
PW
649 pr_debug("omap_hwmod: %s: no MPU register target found\n",
650 oh->name);
986a13f5 651 }
63c85238 652
986a13f5 653 return (found) ? va_start : NULL;
63c85238
PW
654}
655
656/**
657 * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG
658 * @oh: struct omap_hwmod *
659 *
660 * If module is marked as SWSUP_SIDLE, force the module out of slave
661 * idle; otherwise, configure it for smart-idle. If module is marked
662 * as SWSUP_MSUSPEND, force the module out of master standby;
663 * otherwise, configure it for smart-standby. No return value.
664 */
665static void _sysc_enable(struct omap_hwmod *oh)
666{
43b40992 667 u8 idlemode, sf;
63c85238
PW
668 u32 v;
669
43b40992 670 if (!oh->class->sysc)
63c85238
PW
671 return;
672
673 v = oh->_sysc_cache;
43b40992 674 sf = oh->class->sysc->sysc_flags;
63c85238 675
43b40992 676 if (sf & SYSC_HAS_SIDLEMODE) {
63c85238
PW
677 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
678 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
679 _set_slave_idlemode(oh, idlemode, &v);
680 }
681
43b40992 682 if (sf & SYSC_HAS_MIDLEMODE) {
63c85238
PW
683 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
684 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
685 _set_master_standbymode(oh, idlemode, &v);
686 }
687
43b40992 688 if (sf & SYSC_HAS_AUTOIDLE) {
726072e5
PW
689 idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
690 0 : 1;
691 _set_module_autoidle(oh, idlemode, &v);
692 }
693
694 /* XXX OCP ENAWAKEUP bit? */
63c85238 695
a16b1f7f
PW
696 /*
697 * XXX The clock framework should handle this, by
698 * calling into this code. But this must wait until the
699 * clock structures are tagged with omap_hwmod entries
700 */
43b40992
PW
701 if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
702 (sf & SYSC_HAS_CLOCKACTIVITY))
703 _set_clockactivity(oh, oh->class->sysc->clockact, &v);
63c85238
PW
704
705 _write_sysconfig(v, oh);
706}
707
708/**
709 * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG
710 * @oh: struct omap_hwmod *
711 *
712 * If module is marked as SWSUP_SIDLE, force the module into slave
713 * idle; otherwise, configure it for smart-idle. If module is marked
714 * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
715 * configure it for smart-standby. No return value.
716 */
717static void _sysc_idle(struct omap_hwmod *oh)
718{
43b40992 719 u8 idlemode, sf;
63c85238
PW
720 u32 v;
721
43b40992 722 if (!oh->class->sysc)
63c85238
PW
723 return;
724
725 v = oh->_sysc_cache;
43b40992 726 sf = oh->class->sysc->sysc_flags;
63c85238 727
43b40992 728 if (sf & SYSC_HAS_SIDLEMODE) {
63c85238
PW
729 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
730 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
731 _set_slave_idlemode(oh, idlemode, &v);
732 }
733
43b40992 734 if (sf & SYSC_HAS_MIDLEMODE) {
63c85238
PW
735 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
736 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
737 _set_master_standbymode(oh, idlemode, &v);
738 }
739
740 _write_sysconfig(v, oh);
741}
742
743/**
744 * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG
745 * @oh: struct omap_hwmod *
746 *
747 * Force the module into slave idle and master suspend. No return
748 * value.
749 */
750static void _sysc_shutdown(struct omap_hwmod *oh)
751{
752 u32 v;
43b40992 753 u8 sf;
63c85238 754
43b40992 755 if (!oh->class->sysc)
63c85238
PW
756 return;
757
758 v = oh->_sysc_cache;
43b40992 759 sf = oh->class->sysc->sysc_flags;
63c85238 760
43b40992 761 if (sf & SYSC_HAS_SIDLEMODE)
63c85238
PW
762 _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
763
43b40992 764 if (sf & SYSC_HAS_MIDLEMODE)
63c85238
PW
765 _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
766
43b40992 767 if (sf & SYSC_HAS_AUTOIDLE)
726072e5 768 _set_module_autoidle(oh, 1, &v);
63c85238
PW
769
770 _write_sysconfig(v, oh);
771}
772
773/**
774 * _lookup - find an omap_hwmod by name
775 * @name: find an omap_hwmod by name
776 *
777 * Return a pointer to an omap_hwmod by name, or NULL if not found.
778 * Caller must hold omap_hwmod_mutex.
779 */
780static struct omap_hwmod *_lookup(const char *name)
781{
782 struct omap_hwmod *oh, *temp_oh;
783
784 oh = NULL;
785
786 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
787 if (!strcmp(name, temp_oh->name)) {
788 oh = temp_oh;
789 break;
790 }
791 }
792
793 return oh;
794}
795
796/**
797 * _init_clocks - clk_get() all clocks associated with this hwmod
798 * @oh: struct omap_hwmod *
97d60162 799 * @data: not used; pass NULL
63c85238
PW
800 *
801 * Called by omap_hwmod_late_init() (after omap2_clk_init()).
12b1fdb4
KH
802 * Resolves all clock names embedded in the hwmod. Returns -EINVAL if
803 * the omap_hwmod has not yet been registered or if the clocks have
804 * already been initialized, 0 on success, or a non-zero error on
805 * failure.
63c85238 806 */
97d60162 807static int _init_clocks(struct omap_hwmod *oh, void *data)
63c85238
PW
808{
809 int ret = 0;
810
811 if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED))
812 return -EINVAL;
813
814 pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
815
816 ret |= _init_main_clk(oh);
817 ret |= _init_interface_clks(oh);
818 ret |= _init_opt_clks(oh);
819
f5c1f84b
BC
820 if (!ret)
821 oh->_state = _HWMOD_STATE_CLKS_INITED;
63c85238 822
f5c1f84b 823 return 0;
63c85238
PW
824}
825
826/**
827 * _wait_target_ready - wait for a module to leave slave idle
828 * @oh: struct omap_hwmod *
829 *
830 * Wait for a module @oh to leave slave idle. Returns 0 if the module
831 * does not have an IDLEST bit or if the module successfully leaves
832 * slave idle; otherwise, pass along the return value of the
833 * appropriate *_cm_wait_module_ready() function.
834 */
835static int _wait_target_ready(struct omap_hwmod *oh)
836{
837 struct omap_hwmod_ocp_if *os;
838 int ret;
839
840 if (!oh)
841 return -EINVAL;
842
843 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
844 return 0;
845
682fdc96 846 os = oh->slaves[oh->_mpu_port_index];
63c85238 847
33f7ec81 848 if (oh->flags & HWMOD_NO_IDLEST)
63c85238
PW
849 return 0;
850
851 /* XXX check module SIDLEMODE */
852
853 /* XXX check clock enable states */
854
855 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
856 ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
857 oh->prcm.omap2.idlest_reg_id,
858 oh->prcm.omap2.idlest_idle_bit);
63c85238 859 } else if (cpu_is_omap44xx()) {
9a23dfe1 860 ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg);
63c85238
PW
861 } else {
862 BUG();
863 };
864
865 return ret;
866}
867
5365efbe
BC
868/**
869 * _lookup_hardreset - return the register bit shift for this hwmod/reset line
870 * @oh: struct omap_hwmod *
871 * @name: name of the reset line in the context of this hwmod
872 *
873 * Return the bit position of the reset line that match the
874 * input name. Return -ENOENT if not found.
875 */
876static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
877{
878 int i;
879
880 for (i = 0; i < oh->rst_lines_cnt; i++) {
881 const char *rst_line = oh->rst_lines[i].name;
882 if (!strcmp(rst_line, name)) {
883 u8 shift = oh->rst_lines[i].rst_shift;
884 pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n",
885 oh->name, rst_line, shift);
886
887 return shift;
888 }
889 }
890
891 return -ENOENT;
892}
893
894/**
895 * _assert_hardreset - assert the HW reset line of submodules
896 * contained in the hwmod module.
897 * @oh: struct omap_hwmod *
898 * @name: name of the reset line to lookup and assert
899 *
900 * Some IP like dsp, ipu or iva contain processor that require
901 * an HW reset line to be assert / deassert in order to enable fully
902 * the IP.
903 */
904static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
905{
906 u8 shift;
907
908 if (!oh)
909 return -EINVAL;
910
911 shift = _lookup_hardreset(oh, name);
912 if (IS_ERR_VALUE(shift))
913 return shift;
914
915 if (cpu_is_omap24xx() || cpu_is_omap34xx())
916 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
917 shift);
918 else if (cpu_is_omap44xx())
919 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
920 shift);
921 else
922 return -EINVAL;
923}
924
925/**
926 * _deassert_hardreset - deassert the HW reset line of submodules contained
927 * in the hwmod module.
928 * @oh: struct omap_hwmod *
929 * @name: name of the reset line to look up and deassert
930 *
931 * Some IP like dsp, ipu or iva contain processor that require
932 * an HW reset line to be assert / deassert in order to enable fully
933 * the IP.
934 */
935static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
936{
937 u8 shift;
938 int r;
939
940 if (!oh)
941 return -EINVAL;
942
943 shift = _lookup_hardreset(oh, name);
944 if (IS_ERR_VALUE(shift))
945 return shift;
946
947 if (cpu_is_omap24xx() || cpu_is_omap34xx())
948 r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
949 shift);
950 else if (cpu_is_omap44xx())
951 r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
952 shift);
953 else
954 return -EINVAL;
955
956 if (r == -EBUSY)
957 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
958
959 return r;
960}
961
962/**
963 * _read_hardreset - read the HW reset line state of submodules
964 * contained in the hwmod module
965 * @oh: struct omap_hwmod *
966 * @name: name of the reset line to look up and read
967 *
968 * Return the state of the reset line.
969 */
970static int _read_hardreset(struct omap_hwmod *oh, const char *name)
971{
972 u8 shift;
973
974 if (!oh)
975 return -EINVAL;
976
977 shift = _lookup_hardreset(oh, name);
978 if (IS_ERR_VALUE(shift))
979 return shift;
980
981 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
982 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
983 shift);
984 } else if (cpu_is_omap44xx()) {
985 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
986 shift);
987 } else {
988 return -EINVAL;
989 }
990}
991
63c85238
PW
992/**
993 * _reset - reset an omap_hwmod
994 * @oh: struct omap_hwmod *
995 *
996 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
12b1fdb4
KH
997 * enabled for this to work. Returns -EINVAL if the hwmod cannot be
998 * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
999 * the module did not reset in time, or 0 upon success.
2cb06814
BC
1000 *
1001 * In OMAP3 a specific SYSSTATUS register is used to get the reset status.
1002 * Starting in OMAP4, some IPs does not have SYSSTATUS register and instead
1003 * use the SYSCONFIG softreset bit to provide the status.
1004 *
1005 * Note that some IP like McBSP does have a reset control but no reset status.
63c85238
PW
1006 */
1007static int _reset(struct omap_hwmod *oh)
1008{
96835af9 1009 u32 v;
6f8b7ff5 1010 int c = 0;
96835af9 1011 int ret = 0;
63c85238 1012
43b40992 1013 if (!oh->class->sysc ||
2cb06814 1014 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
63c85238
PW
1015 return -EINVAL;
1016
1017 /* clocks must be on for this operation */
1018 if (oh->_state != _HWMOD_STATE_ENABLED) {
76e5589e
BC
1019 pr_warning("omap_hwmod: %s: reset can only be entered from "
1020 "enabled state\n", oh->name);
63c85238
PW
1021 return -EINVAL;
1022 }
1023
96835af9
BC
1024 /* For some modules, all optionnal clocks need to be enabled as well */
1025 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1026 _enable_optional_clocks(oh);
1027
63c85238
PW
1028 pr_debug("omap_hwmod: %s: resetting\n", oh->name);
1029
1030 v = oh->_sysc_cache;
96835af9
BC
1031 ret = _set_softreset(oh, &v);
1032 if (ret)
1033 goto dis_opt_clks;
63c85238
PW
1034 _write_sysconfig(v, oh);
1035
2cb06814
BC
1036 if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
1037 omap_test_timeout((omap_hwmod_readl(oh,
1038 oh->class->sysc->syss_offs)
1039 & SYSS_RESETDONE_MASK),
1040 MAX_MODULE_SOFTRESET_WAIT, c);
1041 else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS)
1042 omap_test_timeout(!(omap_hwmod_readl(oh,
1043 oh->class->sysc->sysc_offs)
1044 & SYSC_TYPE2_SOFTRESET_MASK),
1045 MAX_MODULE_SOFTRESET_WAIT, c);
63c85238 1046
5365efbe 1047 if (c == MAX_MODULE_SOFTRESET_WAIT)
76e5589e
BC
1048 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1049 oh->name, MAX_MODULE_SOFTRESET_WAIT);
63c85238 1050 else
5365efbe 1051 pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
63c85238
PW
1052
1053 /*
1054 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
1055 * _wait_target_ready() or _reset()
1056 */
1057
96835af9
BC
1058 ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
1059
1060dis_opt_clks:
1061 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1062 _disable_optional_clocks(oh);
1063
1064 return ret;
63c85238
PW
1065}
1066
1067/**
84824022 1068 * _omap_hwmod_enable - enable an omap_hwmod
63c85238
PW
1069 * @oh: struct omap_hwmod *
1070 *
1071 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
12b1fdb4
KH
1072 * register target. Returns -EINVAL if the hwmod is in the wrong
1073 * state or passes along the return value of _wait_target_ready().
63c85238 1074 */
84824022 1075int _omap_hwmod_enable(struct omap_hwmod *oh)
63c85238
PW
1076{
1077 int r;
1078
1079 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
1080 oh->_state != _HWMOD_STATE_IDLE &&
1081 oh->_state != _HWMOD_STATE_DISABLED) {
1082 WARN(1, "omap_hwmod: %s: enabled state can only be entered "
1083 "from initialized, idle, or disabled state\n", oh->name);
1084 return -EINVAL;
1085 }
1086
1087 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
1088
5365efbe
BC
1089 /*
1090 * If an IP contains only one HW reset line, then de-assert it in order
1091 * to allow to enable the clocks. Otherwise the PRCM will return
1092 * Intransition status, and the init will failed.
1093 */
1094 if ((oh->_state == _HWMOD_STATE_INITIALIZED ||
1095 oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
1096 _deassert_hardreset(oh, oh->rst_lines[0].name);
1097
63c85238
PW
1098 /* XXX mux balls */
1099
1100 _add_initiator_dep(oh, mpu_oh);
1101 _enable_clocks(oh);
1102
63c85238 1103 r = _wait_target_ready(oh);
9a23dfe1 1104 if (!r) {
63c85238
PW
1105 oh->_state = _HWMOD_STATE_ENABLED;
1106
9a23dfe1
BC
1107 /* Access the sysconfig only if the target is ready */
1108 if (oh->class->sysc) {
1109 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
1110 _update_sysc_cache(oh);
1111 _sysc_enable(oh);
1112 }
1113 } else {
1114 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
1115 oh->name, r);
1116 }
1117
63c85238
PW
1118 return r;
1119}
1120
1121/**
1122 * _idle - idle an omap_hwmod
1123 * @oh: struct omap_hwmod *
1124 *
1125 * Idles an omap_hwmod @oh. This should be called once the hwmod has
1126 * no further work. Returns -EINVAL if the hwmod is in the wrong
1127 * state or returns 0.
1128 */
84824022 1129int _omap_hwmod_idle(struct omap_hwmod *oh)
63c85238
PW
1130{
1131 if (oh->_state != _HWMOD_STATE_ENABLED) {
1132 WARN(1, "omap_hwmod: %s: idle state can only be entered from "
1133 "enabled state\n", oh->name);
1134 return -EINVAL;
1135 }
1136
1137 pr_debug("omap_hwmod: %s: idling\n", oh->name);
1138
43b40992 1139 if (oh->class->sysc)
63c85238
PW
1140 _sysc_idle(oh);
1141 _del_initiator_dep(oh, mpu_oh);
1142 _disable_clocks(oh);
1143
1144 oh->_state = _HWMOD_STATE_IDLE;
1145
1146 return 0;
1147}
1148
1149/**
1150 * _shutdown - shutdown an omap_hwmod
1151 * @oh: struct omap_hwmod *
1152 *
1153 * Shut down an omap_hwmod @oh. This should be called when the driver
1154 * used for the hwmod is removed or unloaded or if the driver is not
1155 * used by the system. Returns -EINVAL if the hwmod is in the wrong
1156 * state or returns 0.
1157 */
1158static int _shutdown(struct omap_hwmod *oh)
1159{
1160 if (oh->_state != _HWMOD_STATE_IDLE &&
1161 oh->_state != _HWMOD_STATE_ENABLED) {
1162 WARN(1, "omap_hwmod: %s: disabled state can only be entered "
1163 "from idle, or enabled state\n", oh->name);
1164 return -EINVAL;
1165 }
1166
1167 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
1168
43b40992 1169 if (oh->class->sysc)
63c85238 1170 _sysc_shutdown(oh);
3827f949 1171
5365efbe
BC
1172 /*
1173 * If an IP contains only one HW reset line, then assert it
1174 * before disabling the clocks and shutting down the IP.
1175 */
1176 if (oh->rst_lines_cnt == 1)
1177 _assert_hardreset(oh, oh->rst_lines[0].name);
1178
3827f949
BC
1179 /* clocks and deps are already disabled in idle */
1180 if (oh->_state == _HWMOD_STATE_ENABLED) {
1181 _del_initiator_dep(oh, mpu_oh);
1182 /* XXX what about the other system initiators here? dma, dsp */
1183 _disable_clocks(oh);
1184 }
63c85238
PW
1185 /* XXX Should this code also force-disable the optional clocks? */
1186
1187 /* XXX mux any associated balls to safe mode */
1188
1189 oh->_state = _HWMOD_STATE_DISABLED;
1190
1191 return 0;
1192}
1193
63c85238
PW
1194/**
1195 * _setup - do initial configuration of omap_hwmod
1196 * @oh: struct omap_hwmod *
97d60162 1197 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
63c85238
PW
1198 *
1199 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
12b1fdb4
KH
1200 * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
1201 * a system that will not call omap_hwmod_enable() to enable devices
1202 * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
1203 * is in the wrong state or returns 0.
63c85238 1204 */
97d60162 1205static int _setup(struct omap_hwmod *oh, void *data)
63c85238 1206{
9a23dfe1 1207 int i, r;
97d60162 1208 u8 skip_setup_idle;
63c85238 1209
97d60162 1210 if (!oh || !data)
63c85238
PW
1211 return -EINVAL;
1212
97d60162
PW
1213 skip_setup_idle = *(u8 *)data;
1214
63c85238
PW
1215 /* Set iclk autoidle mode */
1216 if (oh->slaves_cnt > 0) {
682fdc96
BC
1217 for (i = 0; i < oh->slaves_cnt; i++) {
1218 struct omap_hwmod_ocp_if *os = oh->slaves[i];
63c85238
PW
1219 struct clk *c = os->_clk;
1220
4d3ae5a9 1221 if (!c)
63c85238
PW
1222 continue;
1223
1224 if (os->flags & OCPIF_SWSUP_IDLE) {
1225 /* XXX omap_iclk_deny_idle(c); */
1226 } else {
1227 /* XXX omap_iclk_allow_idle(c); */
1228 clk_enable(c);
1229 }
1230 }
1231 }
1232
12b1fdb4 1233 mutex_init(&oh->_mutex);
63c85238
PW
1234 oh->_state = _HWMOD_STATE_INITIALIZED;
1235
5365efbe
BC
1236 /*
1237 * In the case of hwmod with hardreset that should not be
1238 * de-assert at boot time, we have to keep the module
1239 * initialized, because we cannot enable it properly with the
1240 * reset asserted. Exit without warning because that behavior is
1241 * expected.
1242 */
1243 if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
1244 return 0;
1245
84824022 1246 r = _omap_hwmod_enable(oh);
9a23dfe1
BC
1247 if (r) {
1248 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
1249 oh->name, oh->_state);
1250 return 0;
1251 }
63c85238 1252
b835d014 1253 if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
76e5589e
BC
1254 _reset(oh);
1255
b835d014 1256 /*
76e5589e
BC
1257 * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
1258 * The _omap_hwmod_enable() function should be split to
1259 * avoid the rewrite of the OCP_SYSCONFIG register.
b835d014 1260 */
43b40992 1261 if (oh->class->sysc) {
b835d014
PW
1262 _update_sysc_cache(oh);
1263 _sysc_enable(oh);
1264 }
1265 }
63c85238 1266
97d60162 1267 if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
84824022 1268 _omap_hwmod_idle(oh);
63c85238
PW
1269
1270 return 0;
1271}
1272
1273
1274
1275/* Public functions */
1276
1277u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
1278{
db2a60bf 1279 return __raw_readl(oh->_mpu_rt_va + reg_offs);
63c85238
PW
1280}
1281
1282void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
1283{
db2a60bf 1284 __raw_writel(v, oh->_mpu_rt_va + reg_offs);
63c85238
PW
1285}
1286
887adeac
PW
1287/**
1288 * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
1289 * @oh: struct omap_hwmod *
1290 * @idlemode: SIDLEMODE field bits (shifted to bit 0)
1291 *
1292 * Sets the IP block's OCP slave idlemode in hardware, and updates our
1293 * local copy. Intended to be used by drivers that have some erratum
1294 * that requires direct manipulation of the SIDLEMODE bits. Returns
1295 * -EINVAL if @oh is null, or passes along the return value from
1296 * _set_slave_idlemode().
1297 *
1298 * XXX Does this function have any current users? If not, we should
1299 * remove it; it is better to let the rest of the hwmod code handle this.
1300 * Any users of this function should be scrutinized carefully.
1301 */
46273e6f
KH
1302int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
1303{
1304 u32 v;
1305 int retval = 0;
1306
1307 if (!oh)
1308 return -EINVAL;
1309
1310 v = oh->_sysc_cache;
1311
1312 retval = _set_slave_idlemode(oh, idlemode, &v);
1313 if (!retval)
1314 _write_sysconfig(v, oh);
1315
1316 return retval;
1317}
1318
63c85238
PW
1319/**
1320 * omap_hwmod_register - register a struct omap_hwmod
1321 * @oh: struct omap_hwmod *
1322 *
43b40992
PW
1323 * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod
1324 * already has been registered by the same name; -EINVAL if the
1325 * omap_hwmod is in the wrong state, if @oh is NULL, if the
1326 * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
1327 * name, or if the omap_hwmod's class is missing a name; or 0 upon
1328 * success.
63c85238
PW
1329 *
1330 * XXX The data should be copied into bootmem, so the original data
1331 * should be marked __initdata and freed after init. This would allow
1332 * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note
1333 * that the copy process would be relatively complex due to the large number
1334 * of substructures.
1335 */
1336int omap_hwmod_register(struct omap_hwmod *oh)
1337{
1338 int ret, ms_id;
1339
43b40992
PW
1340 if (!oh || !oh->name || !oh->class || !oh->class->name ||
1341 (oh->_state != _HWMOD_STATE_UNKNOWN))
63c85238
PW
1342 return -EINVAL;
1343
1344 mutex_lock(&omap_hwmod_mutex);
1345
1346 pr_debug("omap_hwmod: %s: registering\n", oh->name);
1347
1348 if (_lookup(oh->name)) {
1349 ret = -EEXIST;
1350 goto ohr_unlock;
1351 }
1352
1353 ms_id = _find_mpu_port_index(oh);
1354 if (!IS_ERR_VALUE(ms_id)) {
1355 oh->_mpu_port_index = ms_id;
db2a60bf 1356 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
63c85238
PW
1357 } else {
1358 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1359 }
1360
1361 list_add_tail(&oh->node, &omap_hwmod_list);
1362
1363 oh->_state = _HWMOD_STATE_REGISTERED;
1364
1365 ret = 0;
1366
1367ohr_unlock:
1368 mutex_unlock(&omap_hwmod_mutex);
1369 return ret;
1370}
1371
1372/**
1373 * omap_hwmod_lookup - look up a registered omap_hwmod by name
1374 * @name: name of the omap_hwmod to look up
1375 *
1376 * Given a @name of an omap_hwmod, return a pointer to the registered
1377 * struct omap_hwmod *, or NULL upon error.
1378 */
1379struct omap_hwmod *omap_hwmod_lookup(const char *name)
1380{
1381 struct omap_hwmod *oh;
1382
1383 if (!name)
1384 return NULL;
1385
1386 mutex_lock(&omap_hwmod_mutex);
1387 oh = _lookup(name);
1388 mutex_unlock(&omap_hwmod_mutex);
1389
1390 return oh;
1391}
1392
1393/**
1394 * omap_hwmod_for_each - call function for each registered omap_hwmod
1395 * @fn: pointer to a callback function
97d60162 1396 * @data: void * data to pass to callback function
63c85238
PW
1397 *
1398 * Call @fn for each registered omap_hwmod, passing @data to each
1399 * function. @fn must return 0 for success or any other value for
1400 * failure. If @fn returns non-zero, the iteration across omap_hwmods
1401 * will stop and the non-zero return value will be passed to the
1402 * caller of omap_hwmod_for_each(). @fn is called with
1403 * omap_hwmod_for_each() held.
1404 */
97d60162
PW
1405int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
1406 void *data)
63c85238
PW
1407{
1408 struct omap_hwmod *temp_oh;
1409 int ret;
1410
1411 if (!fn)
1412 return -EINVAL;
1413
1414 mutex_lock(&omap_hwmod_mutex);
1415 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
97d60162 1416 ret = (*fn)(temp_oh, data);
63c85238
PW
1417 if (ret)
1418 break;
1419 }
1420 mutex_unlock(&omap_hwmod_mutex);
1421
1422 return ret;
1423}
1424
1425
1426/**
1427 * omap_hwmod_init - init omap_hwmod code and register hwmods
1428 * @ohs: pointer to an array of omap_hwmods to register
1429 *
1430 * Intended to be called early in boot before the clock framework is
1431 * initialized. If @ohs is not null, will register all omap_hwmods
1432 * listed in @ohs that are valid for this chip. Returns -EINVAL if
1433 * omap_hwmod_init() has already been called or 0 otherwise.
1434 */
1435int omap_hwmod_init(struct omap_hwmod **ohs)
1436{
1437 struct omap_hwmod *oh;
1438 int r;
1439
1440 if (inited)
1441 return -EINVAL;
1442
1443 inited = 1;
1444
1445 if (!ohs)
1446 return 0;
1447
1448 oh = *ohs;
1449 while (oh) {
1450 if (omap_chip_is(oh->omap_chip)) {
1451 r = omap_hwmod_register(oh);
1452 WARN(r, "omap_hwmod: %s: omap_hwmod_register returned "
1453 "%d\n", oh->name, r);
1454 }
1455 oh = *++ohs;
1456 }
1457
1458 return 0;
1459}
1460
1461/**
1462 * omap_hwmod_late_init - do some post-clock framework initialization
97d60162 1463 * @skip_setup_idle: if 1, do not idle hwmods in _setup()
63c85238
PW
1464 *
1465 * Must be called after omap2_clk_init(). Resolves the struct clk names
1466 * to struct clk pointers for each registered omap_hwmod. Also calls
1467 * _setup() on each hwmod. Returns 0.
1468 */
97d60162 1469int omap_hwmod_late_init(u8 skip_setup_idle)
63c85238
PW
1470{
1471 int r;
1472
1473 /* XXX check return value */
97d60162 1474 r = omap_hwmod_for_each(_init_clocks, NULL);
63c85238
PW
1475 WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
1476
1477 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
1478 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
1479 MPU_INITIATOR_NAME);
1480
97d60162
PW
1481 if (skip_setup_idle)
1482 pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
1483
1484 omap_hwmod_for_each(_setup, &skip_setup_idle);
63c85238
PW
1485
1486 return 0;
1487}
1488
1489/**
1490 * omap_hwmod_unregister - unregister an omap_hwmod
1491 * @oh: struct omap_hwmod *
1492 *
1493 * Unregisters a previously-registered omap_hwmod @oh. There's probably
1494 * no use case for this, so it is likely to be removed in a later version.
1495 *
1496 * XXX Free all of the bootmem-allocated structures here when that is
1497 * implemented. Make it clear that core code is the only code that is
1498 * expected to unregister modules.
1499 */
1500int omap_hwmod_unregister(struct omap_hwmod *oh)
1501{
1502 if (!oh)
1503 return -EINVAL;
1504
1505 pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
1506
1507 mutex_lock(&omap_hwmod_mutex);
db2a60bf 1508 iounmap(oh->_mpu_rt_va);
63c85238
PW
1509 list_del(&oh->node);
1510 mutex_unlock(&omap_hwmod_mutex);
1511
1512 return 0;
1513}
1514
1515/**
1516 * omap_hwmod_enable - enable an omap_hwmod
1517 * @oh: struct omap_hwmod *
1518 *
1519 * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable().
1520 * Returns -EINVAL on error or passes along the return value from _enable().
1521 */
1522int omap_hwmod_enable(struct omap_hwmod *oh)
1523{
1524 int r;
1525
1526 if (!oh)
1527 return -EINVAL;
1528
12b1fdb4 1529 mutex_lock(&oh->_mutex);
84824022 1530 r = _omap_hwmod_enable(oh);
12b1fdb4 1531 mutex_unlock(&oh->_mutex);
63c85238
PW
1532
1533 return r;
1534}
1535
84824022 1536
63c85238
PW
1537/**
1538 * omap_hwmod_idle - idle an omap_hwmod
1539 * @oh: struct omap_hwmod *
1540 *
1541 * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle().
1542 * Returns -EINVAL on error or passes along the return value from _idle().
1543 */
1544int omap_hwmod_idle(struct omap_hwmod *oh)
1545{
1546 if (!oh)
1547 return -EINVAL;
1548
12b1fdb4 1549 mutex_lock(&oh->_mutex);
84824022 1550 _omap_hwmod_idle(oh);
12b1fdb4 1551 mutex_unlock(&oh->_mutex);
63c85238
PW
1552
1553 return 0;
1554}
1555
1556/**
1557 * omap_hwmod_shutdown - shutdown an omap_hwmod
1558 * @oh: struct omap_hwmod *
1559 *
1560 * Shutdown an omap_hwomd @oh. Intended to be called by
1561 * omap_device_shutdown(). Returns -EINVAL on error or passes along
1562 * the return value from _shutdown().
1563 */
1564int omap_hwmod_shutdown(struct omap_hwmod *oh)
1565{
1566 if (!oh)
1567 return -EINVAL;
1568
12b1fdb4 1569 mutex_lock(&oh->_mutex);
63c85238 1570 _shutdown(oh);
12b1fdb4 1571 mutex_unlock(&oh->_mutex);
63c85238
PW
1572
1573 return 0;
1574}
1575
1576/**
1577 * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
1578 * @oh: struct omap_hwmod *oh
1579 *
1580 * Intended to be called by the omap_device code.
1581 */
1582int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1583{
12b1fdb4 1584 mutex_lock(&oh->_mutex);
63c85238 1585 _enable_clocks(oh);
12b1fdb4 1586 mutex_unlock(&oh->_mutex);
63c85238
PW
1587
1588 return 0;
1589}
1590
1591/**
1592 * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
1593 * @oh: struct omap_hwmod *oh
1594 *
1595 * Intended to be called by the omap_device code.
1596 */
1597int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
1598{
12b1fdb4 1599 mutex_lock(&oh->_mutex);
63c85238 1600 _disable_clocks(oh);
12b1fdb4 1601 mutex_unlock(&oh->_mutex);
63c85238
PW
1602
1603 return 0;
1604}
1605
1606/**
1607 * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
1608 * @oh: struct omap_hwmod *oh
1609 *
1610 * Intended to be called by drivers and core code when all posted
1611 * writes to a device must complete before continuing further
1612 * execution (for example, after clearing some device IRQSTATUS
1613 * register bits)
1614 *
1615 * XXX what about targets with multiple OCP threads?
1616 */
1617void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
1618{
1619 BUG_ON(!oh);
1620
43b40992 1621 if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
63c85238
PW
1622 WARN(1, "omap_device: %s: OCP barrier impossible due to "
1623 "device configuration\n", oh->name);
1624 return;
1625 }
1626
1627 /*
1628 * Forces posted writes to complete on the OCP thread handling
1629 * register writes
1630 */
43b40992 1631 omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
63c85238
PW
1632}
1633
1634/**
1635 * omap_hwmod_reset - reset the hwmod
1636 * @oh: struct omap_hwmod *
1637 *
1638 * Under some conditions, a driver may wish to reset the entire device.
1639 * Called from omap_device code. Returns -EINVAL on error or passes along
9b579114 1640 * the return value from _reset().
63c85238
PW
1641 */
1642int omap_hwmod_reset(struct omap_hwmod *oh)
1643{
1644 int r;
1645
9b579114 1646 if (!oh)
63c85238
PW
1647 return -EINVAL;
1648
12b1fdb4 1649 mutex_lock(&oh->_mutex);
63c85238 1650 r = _reset(oh);
12b1fdb4 1651 mutex_unlock(&oh->_mutex);
63c85238
PW
1652
1653 return r;
1654}
1655
1656/**
1657 * omap_hwmod_count_resources - count number of struct resources needed by hwmod
1658 * @oh: struct omap_hwmod *
1659 * @res: pointer to the first element of an array of struct resource to fill
1660 *
1661 * Count the number of struct resource array elements necessary to
1662 * contain omap_hwmod @oh resources. Intended to be called by code
1663 * that registers omap_devices. Intended to be used to determine the
1664 * size of a dynamically-allocated struct resource array, before
1665 * calling omap_hwmod_fill_resources(). Returns the number of struct
1666 * resource array elements needed.
1667 *
1668 * XXX This code is not optimized. It could attempt to merge adjacent
1669 * resource IDs.
1670 *
1671 */
1672int omap_hwmod_count_resources(struct omap_hwmod *oh)
1673{
1674 int ret, i;
1675
9ee9fff9 1676 ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt;
63c85238
PW
1677
1678 for (i = 0; i < oh->slaves_cnt; i++)
682fdc96 1679 ret += oh->slaves[i]->addr_cnt;
63c85238
PW
1680
1681 return ret;
1682}
1683
1684/**
1685 * omap_hwmod_fill_resources - fill struct resource array with hwmod data
1686 * @oh: struct omap_hwmod *
1687 * @res: pointer to the first element of an array of struct resource to fill
1688 *
1689 * Fill the struct resource array @res with resource data from the
1690 * omap_hwmod @oh. Intended to be called by code that registers
1691 * omap_devices. See also omap_hwmod_count_resources(). Returns the
1692 * number of array elements filled.
1693 */
1694int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
1695{
1696 int i, j;
1697 int r = 0;
1698
1699 /* For each IRQ, DMA, memory area, fill in array.*/
1700
1701 for (i = 0; i < oh->mpu_irqs_cnt; i++) {
718bfd76
PW
1702 (res + r)->name = (oh->mpu_irqs + i)->name;
1703 (res + r)->start = (oh->mpu_irqs + i)->irq;
1704 (res + r)->end = (oh->mpu_irqs + i)->irq;
63c85238
PW
1705 (res + r)->flags = IORESOURCE_IRQ;
1706 r++;
1707 }
1708
9ee9fff9
BC
1709 for (i = 0; i < oh->sdma_reqs_cnt; i++) {
1710 (res + r)->name = (oh->sdma_reqs + i)->name;
1711 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
1712 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
63c85238
PW
1713 (res + r)->flags = IORESOURCE_DMA;
1714 r++;
1715 }
1716
1717 for (i = 0; i < oh->slaves_cnt; i++) {
1718 struct omap_hwmod_ocp_if *os;
1719
682fdc96 1720 os = oh->slaves[i];
63c85238
PW
1721
1722 for (j = 0; j < os->addr_cnt; j++) {
1723 (res + r)->start = (os->addr + j)->pa_start;
1724 (res + r)->end = (os->addr + j)->pa_end;
1725 (res + r)->flags = IORESOURCE_MEM;
1726 r++;
1727 }
1728 }
1729
1730 return r;
1731}
1732
1733/**
1734 * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain
1735 * @oh: struct omap_hwmod *
1736 *
1737 * Return the powerdomain pointer associated with the OMAP module
1738 * @oh's main clock. If @oh does not have a main clk, return the
1739 * powerdomain associated with the interface clock associated with the
1740 * module's MPU port. (XXX Perhaps this should use the SDMA port
1741 * instead?) Returns NULL on error, or a struct powerdomain * on
1742 * success.
1743 */
1744struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
1745{
1746 struct clk *c;
1747
1748 if (!oh)
1749 return NULL;
1750
1751 if (oh->_clk) {
1752 c = oh->_clk;
1753 } else {
1754 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1755 return NULL;
1756 c = oh->slaves[oh->_mpu_port_index]->_clk;
1757 }
1758
d5647c18
TG
1759 if (!c->clkdm)
1760 return NULL;
1761
63c85238
PW
1762 return c->clkdm->pwrdm.ptr;
1763
1764}
1765
db2a60bf
PW
1766/**
1767 * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
1768 * @oh: struct omap_hwmod *
1769 *
1770 * Returns the virtual address corresponding to the beginning of the
1771 * module's register target, in the address range that is intended to
1772 * be used by the MPU. Returns the virtual address upon success or NULL
1773 * upon error.
1774 */
1775void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
1776{
1777 if (!oh)
1778 return NULL;
1779
1780 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1781 return NULL;
1782
1783 if (oh->_state == _HWMOD_STATE_UNKNOWN)
1784 return NULL;
1785
1786 return oh->_mpu_rt_va;
1787}
1788
63c85238
PW
1789/**
1790 * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
1791 * @oh: struct omap_hwmod *
1792 * @init_oh: struct omap_hwmod * (initiator)
1793 *
1794 * Add a sleep dependency between the initiator @init_oh and @oh.
1795 * Intended to be called by DSP/Bridge code via platform_data for the
1796 * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
1797 * code needs to add/del initiator dependencies dynamically
1798 * before/after accessing a device. Returns the return value from
1799 * _add_initiator_dep().
1800 *
1801 * XXX Keep a usecount in the clockdomain code
1802 */
1803int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
1804 struct omap_hwmod *init_oh)
1805{
1806 return _add_initiator_dep(oh, init_oh);
1807}
1808
1809/*
1810 * XXX what about functions for drivers to save/restore ocp_sysconfig
1811 * for context save/restore operations?
1812 */
1813
1814/**
1815 * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
1816 * @oh: struct omap_hwmod *
1817 * @init_oh: struct omap_hwmod * (initiator)
1818 *
1819 * Remove a sleep dependency between the initiator @init_oh and @oh.
1820 * Intended to be called by DSP/Bridge code via platform_data for the
1821 * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
1822 * code needs to add/del initiator dependencies dynamically
1823 * before/after accessing a device. Returns the return value from
1824 * _del_initiator_dep().
1825 *
1826 * XXX Keep a usecount in the clockdomain code
1827 */
1828int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
1829 struct omap_hwmod *init_oh)
1830{
1831 return _del_initiator_dep(oh, init_oh);
1832}
1833
63c85238
PW
1834/**
1835 * omap_hwmod_enable_wakeup - allow device to wake up the system
1836 * @oh: struct omap_hwmod *
1837 *
1838 * Sets the module OCP socket ENAWAKEUP bit to allow the module to
1839 * send wakeups to the PRCM. Eventually this should sets PRCM wakeup
1840 * registers to cause the PRCM to receive wakeup events from the
1841 * module. Does not set any wakeup routing registers beyond this
1842 * point - if the module is to wake up any other module or subsystem,
1843 * that must be set separately. Called by omap_device code. Returns
1844 * -EINVAL on error or 0 upon success.
1845 */
1846int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
1847{
43b40992
PW
1848 if (!oh->class->sysc ||
1849 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
63c85238
PW
1850 return -EINVAL;
1851
12b1fdb4 1852 mutex_lock(&oh->_mutex);
63c85238 1853 _enable_wakeup(oh);
12b1fdb4 1854 mutex_unlock(&oh->_mutex);
63c85238
PW
1855
1856 return 0;
1857}
1858
1859/**
1860 * omap_hwmod_disable_wakeup - prevent device from waking the system
1861 * @oh: struct omap_hwmod *
1862 *
1863 * Clears the module OCP socket ENAWAKEUP bit to prevent the module
1864 * from sending wakeups to the PRCM. Eventually this should clear
1865 * PRCM wakeup registers to cause the PRCM to ignore wakeup events
1866 * from the module. Does not set any wakeup routing registers beyond
1867 * this point - if the module is to wake up any other module or
1868 * subsystem, that must be set separately. Called by omap_device
1869 * code. Returns -EINVAL on error or 0 upon success.
1870 */
1871int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
1872{
43b40992
PW
1873 if (!oh->class->sysc ||
1874 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
63c85238
PW
1875 return -EINVAL;
1876
12b1fdb4 1877 mutex_lock(&oh->_mutex);
63c85238 1878 _disable_wakeup(oh);
12b1fdb4 1879 mutex_unlock(&oh->_mutex);
63c85238
PW
1880
1881 return 0;
1882}
43b40992 1883
aee48e3c
PW
1884/**
1885 * omap_hwmod_assert_hardreset - assert the HW reset line of submodules
1886 * contained in the hwmod module.
1887 * @oh: struct omap_hwmod *
1888 * @name: name of the reset line to lookup and assert
1889 *
1890 * Some IP like dsp, ipu or iva contain processor that require
1891 * an HW reset line to be assert / deassert in order to enable fully
1892 * the IP. Returns -EINVAL if @oh is null or if the operation is not
1893 * yet supported on this OMAP; otherwise, passes along the return value
1894 * from _assert_hardreset().
1895 */
1896int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
1897{
1898 int ret;
1899
1900 if (!oh)
1901 return -EINVAL;
1902
1903 mutex_lock(&oh->_mutex);
1904 ret = _assert_hardreset(oh, name);
1905 mutex_unlock(&oh->_mutex);
1906
1907 return ret;
1908}
1909
1910/**
1911 * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules
1912 * contained in the hwmod module.
1913 * @oh: struct omap_hwmod *
1914 * @name: name of the reset line to look up and deassert
1915 *
1916 * Some IP like dsp, ipu or iva contain processor that require
1917 * an HW reset line to be assert / deassert in order to enable fully
1918 * the IP. Returns -EINVAL if @oh is null or if the operation is not
1919 * yet supported on this OMAP; otherwise, passes along the return value
1920 * from _deassert_hardreset().
1921 */
1922int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
1923{
1924 int ret;
1925
1926 if (!oh)
1927 return -EINVAL;
1928
1929 mutex_lock(&oh->_mutex);
1930 ret = _deassert_hardreset(oh, name);
1931 mutex_unlock(&oh->_mutex);
1932
1933 return ret;
1934}
1935
1936/**
1937 * omap_hwmod_read_hardreset - read the HW reset line state of submodules
1938 * contained in the hwmod module
1939 * @oh: struct omap_hwmod *
1940 * @name: name of the reset line to look up and read
1941 *
1942 * Return the current state of the hwmod @oh's reset line named @name:
1943 * returns -EINVAL upon parameter error or if this operation
1944 * is unsupported on the current OMAP; otherwise, passes along the return
1945 * value from _read_hardreset().
1946 */
1947int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
1948{
1949 int ret;
1950
1951 if (!oh)
1952 return -EINVAL;
1953
1954 mutex_lock(&oh->_mutex);
1955 ret = _read_hardreset(oh, name);
1956 mutex_unlock(&oh->_mutex);
1957
1958 return ret;
1959}
1960
1961
43b40992
PW
1962/**
1963 * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
1964 * @classname: struct omap_hwmod_class name to search for
1965 * @fn: callback function pointer to call for each hwmod in class @classname
1966 * @user: arbitrary context data to pass to the callback function
1967 *
1968 * For each omap_hwmod of class @classname, call @fn. Takes
1969 * omap_hwmod_mutex to prevent the hwmod list from changing during the
1970 * iteration. If the callback function returns something other than
1971 * zero, the iterator is terminated, and the callback function's return
1972 * value is passed back to the caller. Returns 0 upon success, -EINVAL
1973 * if @classname or @fn are NULL, or passes back the error code from @fn.
1974 */
1975int omap_hwmod_for_each_by_class(const char *classname,
1976 int (*fn)(struct omap_hwmod *oh,
1977 void *user),
1978 void *user)
1979{
1980 struct omap_hwmod *temp_oh;
1981 int ret = 0;
1982
1983 if (!classname || !fn)
1984 return -EINVAL;
1985
1986 pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
1987 __func__, classname);
1988
1989 mutex_lock(&omap_hwmod_mutex);
1990
1991 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1992 if (!strcmp(temp_oh->class->name, classname)) {
1993 pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
1994 __func__, temp_oh->name);
1995 ret = (*fn)(temp_oh, user);
1996 if (ret)
1997 break;
1998 }
1999 }
2000
2001 mutex_unlock(&omap_hwmod_mutex);
2002
2003 if (ret)
2004 pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
2005 __func__, ret);
2006
2007 return ret;
2008}
2009
This page took 0.192535 seconds and 5 git commands to generate.