1 2#undef DEBUG 3 4#include <linux/kernel.h> 5#include <linux/errno.h> 6#include <linux/io.h> 7#include <linux/clk.h> 8#include <linux/delay.h> 9#include <linux/err.h> 10#include <linux/list.h> 11#include <linux/mutex.h> 12 13#include <plat/common.h> 14#include <plat/cpu.h> 15#include <plat/clockdomain.h> 16#include <plat/powerdomain.h> 17#include <plat/clock.h> 18#include <plat/omap_hwmod.h> 19 20#include "cm.h" 21 22/* Maximum microseconds to wait for OMAP module to reset */ 23#define MAX_MODULE_RESET_WAIT 10000 24 25/* Name of the OMAP hwmod for the MPU */ 26#define MPU_INITIATOR_NAME "mpu" 27 28/* omap_hwmod_list contains all registered struct omap_hwmods */ 29static LIST_HEAD(omap_hwmod_list); 30 31static DEFINE_MUTEX(omap_hwmod_mutex); 32 33/* mpu_oh: used to add/remove MPU initiator from sleepdep list */ 34static struct omap_hwmod *mpu_oh; 35 36/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */ 37static u8 inited; 38 39 40/* Private functions */ 41 42/** 43 * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy 44 * @oh: struct omap_hwmod * 45 * 46 * Load the current value of the hwmod OCP_SYSCONFIG register into the 47 * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no 48 * OCP_SYSCONFIG register or 0 upon success. 49 */ 50static int _update_sysc_cache(struct omap_hwmod *oh) 51{ 52 if (!oh->class->sysc) { 53 WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name); 54 return -EINVAL; 55 } 56 57 58 oh->_sysc_cache = omap_hwmod_readl(oh, oh->class->sysc->sysc_offs); 59 60 if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE)) 61 oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED; 62 63 return 0; 64} 65 66/** 67 * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register 68 * @v: OCP_SYSCONFIG value to write 69 * @oh: struct omap_hwmod * 70 * 71 * Write @v into the module class' OCP_SYSCONFIG register, if it has 72 * one. No return value. 73 */ 74static void _write_sysconfig(u32 v, struct omap_hwmod *oh) 75{ 76 if (!oh->class->sysc) { 77 WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name); 78 return; 79 } 80 81 82 if (oh->_sysc_cache != v) { 83 oh->_sysc_cache = v; 84 omap_hwmod_writel(v, oh, oh->class->sysc->sysc_offs); 85 } 86} 87 88/** 89 * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v 90 * @oh: struct omap_hwmod * 91 * @standbymode: MIDLEMODE field bits 92 * @v: pointer to register contents to modify 93 * 94 * Update the master standby mode bits in @v to be @standbymode for 95 * the @oh hwmod. Does not write to the hardware. Returns -EINVAL 96 * upon error or 0 upon success. 97 */ 98static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode, 99 u32 *v) 100{ 101 u32 mstandby_mask; 102 u8 mstandby_shift; 103 104 if (!oh->class->sysc || 105 !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE)) 106 return -EINVAL; 107 108 if (!oh->class->sysc->sysc_fields) { 109 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 110 return -EINVAL; 111 } 112 113 mstandby_shift = oh->class->sysc->sysc_fields->midle_shift; 114 mstandby_mask = (0x3 << mstandby_shift); 115 116 *v &= ~mstandby_mask; 117 *v |= __ffs(standbymode) << mstandby_shift; 118 119 return 0; 120} 121 122/** 123 * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v 124 * @oh: struct omap_hwmod * 125 * @idlemode: SIDLEMODE field bits 126 * @v: pointer to register contents to modify 127 * 128 * Update the slave idle mode bits in @v to be @idlemode for the @oh 129 * hwmod. Does not write to the hardware. Returns -EINVAL upon error 130 * or 0 upon success. 131 */ 132static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v) 133{ 134 u32 sidle_mask; 135 u8 sidle_shift; 136 137 if (!oh->class->sysc || 138 !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE)) 139 return -EINVAL; 140 141 if (!oh->class->sysc->sysc_fields) { 142 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 143 return -EINVAL; 144 } 145 146 sidle_shift = oh->class->sysc->sysc_fields->sidle_shift; 147 sidle_mask = (0x3 << sidle_shift); 148 149 *v &= ~sidle_mask; 150 *v |= __ffs(idlemode) << sidle_shift; 151 152 return 0; 153} 154 155/** 156 * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v 157 * @oh: struct omap_hwmod * 158 * @clockact: CLOCKACTIVITY field bits 159 * @v: pointer to register contents to modify 160 * 161 * Update the clockactivity mode bits in @v to be @clockact for the 162 * @oh hwmod. Used for additional powersaving on some modules. Does 163 * not write to the hardware. Returns -EINVAL upon error or 0 upon 164 * success. 165 */ 166static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) 167{ 168 u32 clkact_mask; 169 u8 clkact_shift; 170 171 if (!oh->class->sysc || 172 !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY)) 173 return -EINVAL; 174 175 if (!oh->class->sysc->sysc_fields) { 176 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 177 return -EINVAL; 178 } 179 180 clkact_shift = oh->class->sysc->sysc_fields->clkact_shift; 181 clkact_mask = (0x3 << clkact_shift); 182 183 *v &= ~clkact_mask; 184 *v |= clockact << clkact_shift; 185 186 return 0; 187} 188 189/** 190 * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v 191 * @oh: struct omap_hwmod * 192 * @v: pointer to register contents to modify 193 * 194 * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon 195 * error or 0 upon success. 196 */ 197static int _set_softreset(struct omap_hwmod *oh, u32 *v) 198{ 199 u32 softrst_mask; 200 201 if (!oh->class->sysc || 202 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) 203 return -EINVAL; 204 205 if (!oh->class->sysc->sysc_fields) { 206 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 207 return -EINVAL; 208 } 209 210 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); 211 212 *v |= softrst_mask; 213 214 return 0; 215} 216 217/** 218 * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v 219 * @oh: struct omap_hwmod * 220 * @autoidle: desired AUTOIDLE bitfield value (0 or 1) 221 * @v: pointer to register contents to modify 222 * 223 * Update the module autoidle bit in @v to be @autoidle for the @oh 224 * hwmod. The autoidle bit controls whether the module can gate 225 * internal clocks automatically when it isn't doing anything; the 226 * exact function of this bit varies on a per-module basis. This 227 * function does not write to the hardware. Returns -EINVAL upon 228 * error or 0 upon success. 229 */ 230static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, 231 u32 *v) 232{ 233 u32 autoidle_mask; 234 u8 autoidle_shift; 235 236 if (!oh->class->sysc || 237 !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE)) 238 return -EINVAL; 239 240 if (!oh->class->sysc->sysc_fields) { 241 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 242 return -EINVAL; 243 } 244 245 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift; 246 autoidle_mask = (0x3 << autoidle_shift); 247 248 *v &= ~autoidle_mask; 249 *v |= autoidle << autoidle_shift; 250 251 return 0; 252} 253 254/** 255 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware 256 * @oh: struct omap_hwmod * 257 * 258 * Allow the hardware module @oh to send wakeups. Returns -EINVAL 259 * upon error or 0 upon success. 260 */ 261static int _enable_wakeup(struct omap_hwmod *oh) 262{ 263 u32 v, wakeup_mask; 264 265 if (!oh->class->sysc || 266 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 267 return -EINVAL; 268 269 if (!oh->class->sysc->sysc_fields) { 270 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 271 return -EINVAL; 272 } 273 274 wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift); 275 276 v = oh->_sysc_cache; 277 v |= wakeup_mask; 278 _write_sysconfig(v, oh); 279 280 281 oh->_int_flags |= _HWMOD_WAKEUP_ENABLED; 282 283 return 0; 284} 285 286/** 287 * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware 288 * @oh: struct omap_hwmod * 289 * 290 * Prevent the hardware module @oh to send wakeups. Returns -EINVAL 291 * upon error or 0 upon success. 292 */ 293static int _disable_wakeup(struct omap_hwmod *oh) 294{ 295 u32 v, wakeup_mask; 296 297 if (!oh->class->sysc || 298 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 299 return -EINVAL; 300 301 if (!oh->class->sysc->sysc_fields) { 302 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); 303 return -EINVAL; 304 } 305 306 wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift); 307 308 v = oh->_sysc_cache; 309 v &= ~wakeup_mask; 310 _write_sysconfig(v, oh); 311 312 313 oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED; 314 315 return 0; 316} 317 318/** 319 * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active 320 * @oh: struct omap_hwmod * 321 * 322 * Prevent the hardware module @oh from entering idle while the 323 * hardare module initiator @init_oh is active. Useful when a module 324 * will be accessed by a particular initiator (e.g., if a module will 325 * be accessed by the IVA, there should be a sleepdep between the IVA 326 * initiator and the module). Only applies to modules in smart-idle 327 * mode. Returns -EINVAL upon error or passes along 328 * clkdm_add_sleepdep() value upon success. 329 */ 330static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 331{ 332 if (!oh->_clk) 333 return -EINVAL; 334 335 return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); 336} 337 338/** 339 * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active 340 * @oh: struct omap_hwmod * 341 * 342 * Allow the hardware module @oh to enter idle while the hardare 343 * module initiator @init_oh is active. Useful when a module will not 344 * be accessed by a particular initiator (e.g., if a module will not 345 * be accessed by the IVA, there should be no sleepdep between the IVA 346 * initiator and the module). Only applies to modules in smart-idle 347 * mode. Returns -EINVAL upon error or passes along 348 * clkdm_del_sleepdep() value upon success. 349 */ 350static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) 351{ 352 if (!oh->_clk) 353 return -EINVAL; 354 355 return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); 356} 357 358/** 359 * _init_main_clk - get a struct clk * for the the hwmod's main functional clk 360 * @oh: struct omap_hwmod * 361 * 362 * Called from _init_clocks(). Populates the @oh _clk (main 363 * functional clock pointer) if a main_clk is present. Returns 0 on 364 * success or -EINVAL on error. 365 */ 366static int _init_main_clk(struct omap_hwmod *oh) 367{ 368 int ret = 0; 369 370 if (!oh->main_clk) 371 return 0; 372 373 oh->_clk = omap_clk_get_by_name(oh->main_clk); 374 if (!oh->_clk) { 375 pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", 376 oh->name, oh->main_clk); 377 return -EINVAL; 378 } 379 380 if (!oh->_clk->clkdm) 381 pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n", 382 oh->main_clk, oh->_clk->name); 383 384 return ret; 385} 386 387/** 388 * _init_interface_clks - get a struct clk * for the the hwmod's interface clks 389 * @oh: struct omap_hwmod * 390 * 391 * Called from _init_clocks(). Populates the @oh OCP slave interface 392 * clock pointers. Returns 0 on success or -EINVAL on error. 393 */ 394static int _init_interface_clks(struct omap_hwmod *oh) 395{ 396 struct clk *c; 397 int i; 398 int ret = 0; 399 400 if (oh->slaves_cnt == 0) 401 return 0; 402 403 for (i = 0; i < oh->slaves_cnt; i++) { 404 struct omap_hwmod_ocp_if *os = oh->slaves[i]; 405 406 if (!os->clk) 407 continue; 408 409 c = omap_clk_get_by_name(os->clk); 410 if (!c) { 411 pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n", 412 oh->name, os->clk); 413 ret = -EINVAL; 414 } 415 os->_clk = c; 416 } 417 418 return ret; 419} 420 421/** 422 * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks 423 * @oh: struct omap_hwmod * 424 * 425 * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk 426 * clock pointers. Returns 0 on success or -EINVAL on error. 427 */ 428static int _init_opt_clks(struct omap_hwmod *oh) 429{ 430 struct omap_hwmod_opt_clk *oc; 431 struct clk *c; 432 int i; 433 int ret = 0; 434 435 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { 436 c = omap_clk_get_by_name(oc->clk); 437 if (!c) { 438 pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n", 439 oh->name, oc->clk); 440 ret = -EINVAL; 441 } 442 oc->_clk = c; 443 } 444 445 return ret; 446} 447 448/** 449 * _enable_clocks - enable hwmod main clock and interface clocks 450 * @oh: struct omap_hwmod * 451 * 452 * Enables all clocks necessary for register reads and writes to succeed 453 * on the hwmod @oh. Returns 0. 454 */ 455static int _enable_clocks(struct omap_hwmod *oh) 456{ 457 int i; 458 459 pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); 460 461 if (oh->_clk) 462 clk_enable(oh->_clk); 463 464 if (oh->slaves_cnt > 0) { 465 for (i = 0; i < oh->slaves_cnt; i++) { 466 struct omap_hwmod_ocp_if *os = oh->slaves[i]; 467 struct clk *c = os->_clk; 468 469 if (c && (os->flags & OCPIF_SWSUP_IDLE)) 470 clk_enable(c); 471 } 472 } 473 474 /* The opt clocks are controlled by the device driver. */ 475 476 return 0; 477} 478 479/** 480 * _disable_clocks - disable hwmod main clock and interface clocks 481 * @oh: struct omap_hwmod * 482 * 483 * Disables the hwmod @oh main functional and interface clocks. Returns 0. 484 */ 485static int _disable_clocks(struct omap_hwmod *oh) 486{ 487 int i; 488 489 pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); 490 491 if (oh->_clk) 492 clk_disable(oh->_clk); 493 494 if (oh->slaves_cnt > 0) { 495 for (i = 0; i < oh->slaves_cnt; i++) { 496 struct omap_hwmod_ocp_if *os = oh->slaves[i]; 497 struct clk *c = os->_clk; 498 499 if (c && (os->flags & OCPIF_SWSUP_IDLE)) 500 clk_disable(c); 501 } 502 } 503 504 /* The opt clocks are controlled by the device driver. */ 505 506 return 0; 507} 508 509/** 510 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use 511 * @oh: struct omap_hwmod * 512 * 513 * Returns the array index of the OCP slave port that the MPU 514 * addresses the device on, or -EINVAL upon error or not found. 515 */ 516static int _find_mpu_port_index(struct omap_hwmod *oh) 517{ 518 int i; 519 int found = 0; 520 521 if (!oh || oh->slaves_cnt == 0) 522 return -EINVAL; 523 524 for (i = 0; i < oh->slaves_cnt; i++) { 525 struct omap_hwmod_ocp_if *os = oh->slaves[i]; 526 527 if (os->user & OCP_USER_MPU) { 528 found = 1; 529 break; 530 } 531 } 532 533 if (found) 534 pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n", 535 oh->name, i); 536 else 537 pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n", 538 oh->name); 539 540 return (found) ? i : -EINVAL; 541} 542 543/** 544 * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU 545 * @oh: struct omap_hwmod * 546 * 547 * Return the virtual address of the base of the register target of 548 * device @oh, or NULL on error. 549 */ 550static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index) 551{ 552 struct omap_hwmod_ocp_if *os; 553 struct omap_hwmod_addr_space *mem; 554 int i; 555 int found = 0; 556 void __iomem *va_start; 557 558 if (!oh || oh->slaves_cnt == 0) 559 return NULL; 560 561 os = oh->slaves[index]; 562 563 for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) { 564 if (mem->flags & ADDR_TYPE_RT) { 565 found = 1; 566 break; 567 } 568 } 569 570 if (found) { 571 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); 572 if (!va_start) { 573 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); 574 return NULL; 575 } 576 pr_debug("omap_hwmod: %s: MPU register target at va %p\n", 577 oh->name, va_start); 578 } else { 579 pr_debug("omap_hwmod: %s: no MPU register target found\n", 580 oh->name); 581 } 582 583 return (found) ? va_start : NULL; 584} 585 586/** 587 * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG 588 * @oh: struct omap_hwmod * 589 * 590 * If module is marked as SWSUP_SIDLE, force the module out of slave 591 * idle; otherwise, configure it for smart-idle. If module is marked 592 * as SWSUP_MSUSPEND, force the module out of master standby; 593 * otherwise, configure it for smart-standby. No return value. 594 */ 595static void _sysc_enable(struct omap_hwmod *oh) 596{ 597 u8 idlemode, sf; 598 u32 v; 599 600 if (!oh->class->sysc) 601 return; 602 603 v = oh->_sysc_cache; 604 sf = oh->class->sysc->sysc_flags; 605 606 if (sf & SYSC_HAS_SIDLEMODE) { 607 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? 608 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; 609 _set_slave_idlemode(oh, idlemode, &v); 610 } 611 612 if (sf & SYSC_HAS_MIDLEMODE) { 613 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? 614 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; 615 _set_master_standbymode(oh, idlemode, &v); 616 } 617 618 if (sf & SYSC_HAS_AUTOIDLE) { 619 idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ? 620 0 : 1; 621 _set_module_autoidle(oh, idlemode, &v); 622 } 623 624 625 if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) && 626 (sf & SYSC_HAS_CLOCKACTIVITY)) 627 _set_clockactivity(oh, oh->class->sysc->clockact, &v); 628 629 _write_sysconfig(v, oh); 630} 631 632/** 633 * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG 634 * @oh: struct omap_hwmod * 635 * 636 * If module is marked as SWSUP_SIDLE, force the module into slave 637 * idle; otherwise, configure it for smart-idle. If module is marked 638 * as SWSUP_MSUSPEND, force the module into master standby; otherwise, 639 * configure it for smart-standby. No return value. 640 */ 641static void _sysc_idle(struct omap_hwmod *oh) 642{ 643 u8 idlemode, sf; 644 u32 v; 645 646 if (!oh->class->sysc) 647 return; 648 649 v = oh->_sysc_cache; 650 sf = oh->class->sysc->sysc_flags; 651 652 if (sf & SYSC_HAS_SIDLEMODE) { 653 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? 654 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; 655 _set_slave_idlemode(oh, idlemode, &v); 656 } 657 658 if (sf & SYSC_HAS_MIDLEMODE) { 659 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? 660 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; 661 _set_master_standbymode(oh, idlemode, &v); 662 } 663 664 _write_sysconfig(v, oh); 665} 666 667/** 668 * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG 669 * @oh: struct omap_hwmod * 670 * 671 * Force the module into slave idle and master suspend. No return 672 * value. 673 */ 674static void _sysc_shutdown(struct omap_hwmod *oh) 675{ 676 u32 v; 677 u8 sf; 678 679 if (!oh->class->sysc) 680 return; 681 682 v = oh->_sysc_cache; 683 sf = oh->class->sysc->sysc_flags; 684 685 if (sf & SYSC_HAS_SIDLEMODE) 686 _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v); 687 688 if (sf & SYSC_HAS_MIDLEMODE) 689 _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v); 690 691 if (sf & SYSC_HAS_AUTOIDLE) 692 _set_module_autoidle(oh, 1, &v); 693 694 _write_sysconfig(v, oh); 695} 696 697/** 698 * _lookup - find an omap_hwmod by name 699 * @name: find an omap_hwmod by name 700 * 701 * Return a pointer to an omap_hwmod by name, or NULL if not found. 702 * Caller must hold omap_hwmod_mutex. 703 */ 704static struct omap_hwmod *_lookup(const char *name) 705{ 706 struct omap_hwmod *oh, *temp_oh; 707 708 oh = NULL; 709 710 list_for_each_entry(temp_oh, &omap_hwmod_list, node) { 711 if (!strcmp(name, temp_oh->name)) { 712 oh = temp_oh; 713 break; 714 } 715 } 716 717 return oh; 718} 719 720/** 721 * _init_clocks - clk_get() all clocks associated with this hwmod 722 * @oh: struct omap_hwmod * 723 * @data: not used; pass NULL 724 * 725 * Called by omap_hwmod_late_init() (after omap2_clk_init()). 726 * Resolves all clock names embedded in the hwmod. Must be called 727 * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod 728 * has not yet been registered or if the clocks have already been 729 * initialized, 0 on success, or a non-zero error on failure. 730 */ 731static int _init_clocks(struct omap_hwmod *oh, void *data) 732{ 733 int ret = 0; 734 735 if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED)) 736 return -EINVAL; 737 738 pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); 739 740 ret |= _init_main_clk(oh); 741 ret |= _init_interface_clks(oh); 742 ret |= _init_opt_clks(oh); 743 744 if (!ret) 745 oh->_state = _HWMOD_STATE_CLKS_INITED; 746 747 return 0; 748} 749 750/** 751 * _wait_target_ready - wait for a module to leave slave idle 752 * @oh: struct omap_hwmod * 753 * 754 * Wait for a module @oh to leave slave idle. Returns 0 if the module 755 * does not have an IDLEST bit or if the module successfully leaves 756 * slave idle; otherwise, pass along the return value of the 757 * appropriate *_cm_wait_module_ready() function. 758 */ 759static int _wait_target_ready(struct omap_hwmod *oh) 760{ 761 struct omap_hwmod_ocp_if *os; 762 int ret; 763 764 if (!oh) 765 return -EINVAL; 766 767 if (oh->_int_flags & _HWMOD_NO_MPU_PORT) 768 return 0; 769 770 os = oh->slaves[oh->_mpu_port_index]; 771 772 if (oh->flags & HWMOD_NO_IDLEST) 773 return 0; 774 775 776 777 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 778 ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, 779 oh->prcm.omap2.idlest_reg_id, 780 oh->prcm.omap2.idlest_idle_bit); 781 } else if (cpu_is_omap44xx()) { 782 ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg); 783 } else { 784 BUG(); 785 }; 786 787 return ret; 788} 789 790/** 791 * _reset - reset an omap_hwmod 792 * @oh: struct omap_hwmod * 793 * 794 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be 795 * enabled for this to work. Must be called with omap_hwmod_mutex 796 * held. Returns -EINVAL if the hwmod cannot be reset this way or if 797 * the hwmod is in the wrong state, -ETIMEDOUT if the module did not 798 * reset in time, or 0 upon success. 799 */ 800static int _reset(struct omap_hwmod *oh) 801{ 802 u32 r, v; 803 int c = 0; 804 805 if (!oh->class->sysc || 806 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) || 807 (oh->class->sysc->sysc_flags & SYSS_MISSING)) 808 return -EINVAL; 809 810 /* clocks must be on for this operation */ 811 if (oh->_state != _HWMOD_STATE_ENABLED) { 812 WARN(1, "omap_hwmod: %s: reset can only be entered from " 813 "enabled state\n", oh->name); 814 return -EINVAL; 815 } 816 817 pr_debug("omap_hwmod: %s: resetting\n", oh->name); 818 819 v = oh->_sysc_cache; 820 r = _set_softreset(oh, &v); 821 if (r) 822 return r; 823 _write_sysconfig(v, oh); 824 825 omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) & 826 SYSS_RESETDONE_MASK), 827 MAX_MODULE_RESET_WAIT, c); 828 829 if (c == MAX_MODULE_RESET_WAIT) 830 WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n", 831 oh->name, MAX_MODULE_RESET_WAIT); 832 else 833 pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c); 834 835 836 return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0; 837} 838 839/** 840 * _omap_hwmod_enable - enable an omap_hwmod 841 * @oh: struct omap_hwmod * 842 * 843 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's 844 * register target. Must be called with omap_hwmod_mutex held. 845 * Returns -EINVAL if the hwmod is in the wrong state or passes along 846 * the return value of _wait_target_ready(). 847 */ 848int _omap_hwmod_enable(struct omap_hwmod *oh) 849{ 850 int r; 851 852 if (oh->_state != _HWMOD_STATE_INITIALIZED && 853 oh->_state != _HWMOD_STATE_IDLE && 854 oh->_state != _HWMOD_STATE_DISABLED) { 855 WARN(1, "omap_hwmod: %s: enabled state can only be entered " 856 "from initialized, idle, or disabled state\n", oh->name); 857 return -EINVAL; 858 } 859 860 pr_debug("omap_hwmod: %s: enabling\n", oh->name); 861 862 863 _add_initiator_dep(oh, mpu_oh); 864 _enable_clocks(oh); 865 866 r = _wait_target_ready(oh); 867 if (!r) { 868 oh->_state = _HWMOD_STATE_ENABLED; 869 870 /* Access the sysconfig only if the target is ready */ 871 if (oh->class->sysc) { 872 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) 873 _update_sysc_cache(oh); 874 _sysc_enable(oh); 875 } 876 } else { 877 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", 878 oh->name, r); 879 } 880 881 return r; 882} 883 884/** 885 * _idle - idle an omap_hwmod 886 * @oh: struct omap_hwmod * 887 * 888 * Idles an omap_hwmod @oh. This should be called once the hwmod has 889 * no further work. Returns -EINVAL if the hwmod is in the wrong 890 * state or returns 0. 891 */ 892int _omap_hwmod_idle(struct omap_hwmod *oh) 893{ 894 if (oh->_state != _HWMOD_STATE_ENABLED) { 895 WARN(1, "omap_hwmod: %s: idle state can only be entered from " 896 "enabled state\n", oh->name); 897 return -EINVAL; 898 } 899 900 pr_debug("omap_hwmod: %s: idling\n", oh->name); 901 902 if (oh->class->sysc) 903 _sysc_idle(oh); 904 _del_initiator_dep(oh, mpu_oh); 905 _disable_clocks(oh); 906 907 oh->_state = _HWMOD_STATE_IDLE; 908 909 return 0; 910} 911 912/** 913 * _shutdown - shutdown an omap_hwmod 914 * @oh: struct omap_hwmod * 915 * 916 * Shut down an omap_hwmod @oh. This should be called when the driver 917 * used for the hwmod is removed or unloaded or if the driver is not 918 * used by the system. Returns -EINVAL if the hwmod is in the wrong 919 * state or returns 0. 920 */ 921static int _shutdown(struct omap_hwmod *oh) 922{ 923 if (oh->_state != _HWMOD_STATE_IDLE && 924 oh->_state != _HWMOD_STATE_ENABLED) { 925 WARN(1, "omap_hwmod: %s: disabled state can only be entered " 926 "from idle, or enabled state\n", oh->name); 927 return -EINVAL; 928 } 929 930 pr_debug("omap_hwmod: %s: disabling\n", oh->name); 931 932 if (oh->class->sysc) 933 _sysc_shutdown(oh); 934 _del_initiator_dep(oh, mpu_oh); 935 _disable_clocks(oh); 936 937 938 oh->_state = _HWMOD_STATE_DISABLED; 939 940 return 0; 941} 942 943/** 944 * _setup - do initial configuration of omap_hwmod 945 * @oh: struct omap_hwmod * 946 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 947 * 948 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh 949 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held. 950 * @skip_setup_idle is intended to be used on a system that will not 951 * call omap_hwmod_enable() to enable devices (e.g., a system without 952 * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or 953 * returns 0. 954 */ 955static int _setup(struct omap_hwmod *oh, void *data) 956{ 957 int i, r; 958 u8 skip_setup_idle; 959 960 if (!oh || !data) 961 return -EINVAL; 962 963 skip_setup_idle = *(u8 *)data; 964 965 /* Set iclk autoidle mode */ 966 if (oh->slaves_cnt > 0) { 967 for (i = 0; i < oh->slaves_cnt; i++) { 968 struct omap_hwmod_ocp_if *os = oh->slaves[i]; 969 struct clk *c = os->_clk; 970 971 if (!c) 972 continue; 973 974 if (os->flags & OCPIF_SWSUP_IDLE) { 975 } else { 976 clk_enable(c); 977 } 978 } 979 } 980 981 oh->_state = _HWMOD_STATE_INITIALIZED; 982 983 r = _omap_hwmod_enable(oh); 984 if (r) { 985 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", 986 oh->name, oh->_state); 987 return 0; 988 } 989 990 if (!(oh->flags & HWMOD_INIT_NO_RESET)) { 991 if (oh->class->sysc) { 992 _update_sysc_cache(oh); 993 _sysc_enable(oh); 994 } 995 } 996 997 if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle) 998 _omap_hwmod_idle(oh); 999 1000 return 0; 1001} 1002 1003 1004 1005/* Public functions */ 1006 1007u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) 1008{ 1009 return __raw_readl(oh->_mpu_rt_va + reg_offs); 1010} 1011 1012void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs) 1013{ 1014 __raw_writel(v, oh->_mpu_rt_va + reg_offs); 1015} 1016 1017int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode) 1018{ 1019 u32 v; 1020 int retval = 0; 1021 1022 if (!oh) 1023 return -EINVAL; 1024 1025 v = oh->_sysc_cache; 1026 1027 retval = _set_slave_idlemode(oh, idlemode, &v); 1028 if (!retval) 1029 _write_sysconfig(v, oh); 1030 1031 return retval; 1032} 1033 1034int omap_hwmod_register(struct omap_hwmod *oh) 1035{ 1036 int ret, ms_id; 1037 1038 if (!oh || !oh->name || !oh->class || !oh->class->name || 1039 (oh->_state != _HWMOD_STATE_UNKNOWN)) 1040 return -EINVAL; 1041 1042 mutex_lock(&omap_hwmod_mutex); 1043 1044 pr_debug("omap_hwmod: %s: registering\n", oh->name); 1045 1046 if (_lookup(oh->name)) { 1047 ret = -EEXIST; 1048 goto ohr_unlock; 1049 } 1050 1051 ms_id = _find_mpu_port_index(oh); 1052 if (!IS_ERR_VALUE(ms_id)) { 1053 oh->_mpu_port_index = ms_id; 1054 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); 1055 } else { 1056 oh->_int_flags |= _HWMOD_NO_MPU_PORT; 1057 } 1058 1059 list_add_tail(&oh->node, &omap_hwmod_list); 1060 1061 oh->_state = _HWMOD_STATE_REGISTERED; 1062 1063 ret = 0; 1064 1065ohr_unlock: 1066 mutex_unlock(&omap_hwmod_mutex); 1067 return ret; 1068} 1069 1070/** 1071 * omap_hwmod_lookup - look up a registered omap_hwmod by name 1072 * @name: name of the omap_hwmod to look up 1073 * 1074 * Given a @name of an omap_hwmod, return a pointer to the registered 1075 * struct omap_hwmod *, or NULL upon error. 1076 */ 1077struct omap_hwmod *omap_hwmod_lookup(const char *name) 1078{ 1079 struct omap_hwmod *oh; 1080 1081 if (!name) 1082 return NULL; 1083 1084 mutex_lock(&omap_hwmod_mutex); 1085 oh = _lookup(name); 1086 mutex_unlock(&omap_hwmod_mutex); 1087 1088 return oh; 1089} 1090 1091/** 1092 * omap_hwmod_for_each - call function for each registered omap_hwmod 1093 * @fn: pointer to a callback function 1094 * @data: void * data to pass to callback function 1095 * 1096 * Call @fn for each registered omap_hwmod, passing @data to each 1097 * function. @fn must return 0 for success or any other value for 1098 * failure. If @fn returns non-zero, the iteration across omap_hwmods 1099 * will stop and the non-zero return value will be passed to the 1100 * caller of omap_hwmod_for_each(). @fn is called with 1101 * omap_hwmod_for_each() held. 1102 */ 1103int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), 1104 void *data) 1105{ 1106 struct omap_hwmod *temp_oh; 1107 int ret; 1108 1109 if (!fn) 1110 return -EINVAL; 1111 1112 mutex_lock(&omap_hwmod_mutex); 1113 list_for_each_entry(temp_oh, &omap_hwmod_list, node) { 1114 ret = (*fn)(temp_oh, data); 1115 if (ret) 1116 break; 1117 } 1118 mutex_unlock(&omap_hwmod_mutex); 1119 1120 return ret; 1121} 1122 1123 1124/** 1125 * omap_hwmod_init - init omap_hwmod code and register hwmods 1126 * @ohs: pointer to an array of omap_hwmods to register 1127 * 1128 * Intended to be called early in boot before the clock framework is 1129 * initialized. If @ohs is not null, will register all omap_hwmods 1130 * listed in @ohs that are valid for this chip. Returns -EINVAL if 1131 * omap_hwmod_init() has already been called or 0 otherwise. 1132 */ 1133int omap_hwmod_init(struct omap_hwmod **ohs) 1134{ 1135 struct omap_hwmod *oh; 1136 int r; 1137 1138 if (inited) 1139 return -EINVAL; 1140 1141 inited = 1; 1142 1143 if (!ohs) 1144 return 0; 1145 1146 oh = *ohs; 1147 while (oh) { 1148 if (omap_chip_is(oh->omap_chip)) { 1149 r = omap_hwmod_register(oh); 1150 WARN(r, "omap_hwmod: %s: omap_hwmod_register returned " 1151 "%d\n", oh->name, r); 1152 } 1153 oh = *++ohs; 1154 } 1155 1156 return 0; 1157} 1158 1159/** 1160 * omap_hwmod_late_init - do some post-clock framework initialization 1161 * @skip_setup_idle: if 1, do not idle hwmods in _setup() 1162 * 1163 * Must be called after omap2_clk_init(). Resolves the struct clk names 1164 * to struct clk pointers for each registered omap_hwmod. Also calls 1165 * _setup() on each hwmod. Returns 0. 1166 */ 1167int omap_hwmod_late_init(u8 skip_setup_idle) 1168{ 1169 int r; 1170 1171 r = omap_hwmod_for_each(_init_clocks, NULL); 1172 WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n"); 1173 1174 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); 1175 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", 1176 MPU_INITIATOR_NAME); 1177 1178 if (skip_setup_idle) 1179 pr_debug("omap_hwmod: will leave hwmods enabled during setup\n"); 1180 1181 omap_hwmod_for_each(_setup, &skip_setup_idle); 1182 1183 return 0; 1184} 1185 1186int omap_hwmod_unregister(struct omap_hwmod *oh) 1187{ 1188 if (!oh) 1189 return -EINVAL; 1190 1191 pr_debug("omap_hwmod: %s: unregistering\n", oh->name); 1192 1193 mutex_lock(&omap_hwmod_mutex); 1194 iounmap(oh->_mpu_rt_va); 1195 list_del(&oh->node); 1196 mutex_unlock(&omap_hwmod_mutex); 1197 1198 return 0; 1199} 1200 1201/** 1202 * omap_hwmod_enable - enable an omap_hwmod 1203 * @oh: struct omap_hwmod * 1204 * 1205 * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable(). 1206 * Returns -EINVAL on error or passes along the return value from _enable(). 1207 */ 1208int omap_hwmod_enable(struct omap_hwmod *oh) 1209{ 1210 int r; 1211 1212 if (!oh) 1213 return -EINVAL; 1214 1215 mutex_lock(&omap_hwmod_mutex); 1216 r = _omap_hwmod_enable(oh); 1217 mutex_unlock(&omap_hwmod_mutex); 1218 1219 return r; 1220} 1221 1222 1223/** 1224 * omap_hwmod_idle - idle an omap_hwmod 1225 * @oh: struct omap_hwmod * 1226 * 1227 * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle(). 1228 * Returns -EINVAL on error or passes along the return value from _idle(). 1229 */ 1230int omap_hwmod_idle(struct omap_hwmod *oh) 1231{ 1232 if (!oh) 1233 return -EINVAL; 1234 1235 mutex_lock(&omap_hwmod_mutex); 1236 _omap_hwmod_idle(oh); 1237 mutex_unlock(&omap_hwmod_mutex); 1238 1239 return 0; 1240} 1241 1242/** 1243 * omap_hwmod_shutdown - shutdown an omap_hwmod 1244 * @oh: struct omap_hwmod * 1245 * 1246 * Shutdown an omap_hwomd @oh. Intended to be called by 1247 * omap_device_shutdown(). Returns -EINVAL on error or passes along 1248 * the return value from _shutdown(). 1249 */ 1250int omap_hwmod_shutdown(struct omap_hwmod *oh) 1251{ 1252 if (!oh) 1253 return -EINVAL; 1254 1255 mutex_lock(&omap_hwmod_mutex); 1256 _shutdown(oh); 1257 mutex_unlock(&omap_hwmod_mutex); 1258 1259 return 0; 1260} 1261 1262/** 1263 * omap_hwmod_enable_clocks - enable main_clk, all interface clocks 1264 * @oh: struct omap_hwmod *oh 1265 * 1266 * Intended to be called by the omap_device code. 1267 */ 1268int omap_hwmod_enable_clocks(struct omap_hwmod *oh) 1269{ 1270 mutex_lock(&omap_hwmod_mutex); 1271 _enable_clocks(oh); 1272 mutex_unlock(&omap_hwmod_mutex); 1273 1274 return 0; 1275} 1276 1277/** 1278 * omap_hwmod_disable_clocks - disable main_clk, all interface clocks 1279 * @oh: struct omap_hwmod *oh 1280 * 1281 * Intended to be called by the omap_device code. 1282 */ 1283int omap_hwmod_disable_clocks(struct omap_hwmod *oh) 1284{ 1285 mutex_lock(&omap_hwmod_mutex); 1286 _disable_clocks(oh); 1287 mutex_unlock(&omap_hwmod_mutex); 1288 1289 return 0; 1290} 1291 1292void omap_hwmod_ocp_barrier(struct omap_hwmod *oh) 1293{ 1294 BUG_ON(!oh); 1295 1296 if (!oh->class->sysc || !oh->class->sysc->sysc_flags) { 1297 WARN(1, "omap_device: %s: OCP barrier impossible due to " 1298 "device configuration\n", oh->name); 1299 return; 1300 } 1301 1302 /* 1303 * Forces posted writes to complete on the OCP thread handling 1304 * register writes 1305 */ 1306 omap_hwmod_readl(oh, oh->class->sysc->sysc_offs); 1307} 1308 1309/** 1310 * omap_hwmod_reset - reset the hwmod 1311 * @oh: struct omap_hwmod * 1312 * 1313 * Under some conditions, a driver may wish to reset the entire device. 1314 * Called from omap_device code. Returns -EINVAL on error or passes along 1315 * the return value from _reset()/_enable(). 1316 */ 1317int omap_hwmod_reset(struct omap_hwmod *oh) 1318{ 1319 int r; 1320 1321 if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED)) 1322 return -EINVAL; 1323 1324 mutex_lock(&omap_hwmod_mutex); 1325 r = _reset(oh); 1326 if (!r) 1327 r = _omap_hwmod_enable(oh); 1328 mutex_unlock(&omap_hwmod_mutex); 1329 1330 return r; 1331} 1332 1333int omap_hwmod_count_resources(struct omap_hwmod *oh) 1334{ 1335 int ret, i; 1336 1337 ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt; 1338 1339 for (i = 0; i < oh->slaves_cnt; i++) 1340 ret += oh->slaves[i]->addr_cnt; 1341 1342 return ret; 1343} 1344 1345/** 1346 * omap_hwmod_fill_resources - fill struct resource array with hwmod data 1347 * @oh: struct omap_hwmod * 1348 * @res: pointer to the first element of an array of struct resource to fill 1349 * 1350 * Fill the struct resource array @res with resource data from the 1351 * omap_hwmod @oh. Intended to be called by code that registers 1352 * omap_devices. See also omap_hwmod_count_resources(). Returns the 1353 * number of array elements filled. 1354 */ 1355int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) 1356{ 1357 int i, j; 1358 int r = 0; 1359 1360 /* For each IRQ, DMA, memory area, fill in array.*/ 1361 1362 for (i = 0; i < oh->mpu_irqs_cnt; i++) { 1363 (res + r)->name = (oh->mpu_irqs + i)->name; 1364 (res + r)->start = (oh->mpu_irqs + i)->irq; 1365 (res + r)->end = (oh->mpu_irqs + i)->irq; 1366 (res + r)->flags = IORESOURCE_IRQ; 1367 r++; 1368 } 1369 1370 for (i = 0; i < oh->sdma_chs_cnt; i++) { 1371 (res + r)->name = (oh->sdma_chs + i)->name; 1372 (res + r)->start = (oh->sdma_chs + i)->dma_ch; 1373 (res + r)->end = (oh->sdma_chs + i)->dma_ch; 1374 (res + r)->flags = IORESOURCE_DMA; 1375 r++; 1376 } 1377 1378 for (i = 0; i < oh->slaves_cnt; i++) { 1379 struct omap_hwmod_ocp_if *os; 1380 1381 os = oh->slaves[i]; 1382 1383 for (j = 0; j < os->addr_cnt; j++) { 1384 (res + r)->start = (os->addr + j)->pa_start; 1385 (res + r)->end = (os->addr + j)->pa_end; 1386 (res + r)->flags = IORESOURCE_MEM; 1387 r++; 1388 } 1389 } 1390 1391 return r; 1392} 1393 1394struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) 1395{ 1396 struct clk *c; 1397 1398 if (!oh) 1399 return NULL; 1400 1401 if (oh->_clk) { 1402 c = oh->_clk; 1403 } else { 1404 if (oh->_int_flags & _HWMOD_NO_MPU_PORT) 1405 return NULL; 1406 c = oh->slaves[oh->_mpu_port_index]->_clk; 1407 } 1408 1409 if (!c->clkdm) 1410 return NULL; 1411 1412 return c->clkdm->pwrdm.ptr; 1413 1414} 1415 1416/** 1417 * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU) 1418 * @oh: struct omap_hwmod * 1419 * 1420 * Returns the virtual address corresponding to the beginning of the 1421 * module's register target, in the address range that is intended to 1422 * be used by the MPU. Returns the virtual address upon success or NULL 1423 * upon error. 1424 */ 1425void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh) 1426{ 1427 if (!oh) 1428 return NULL; 1429 1430 if (oh->_int_flags & _HWMOD_NO_MPU_PORT) 1431 return NULL; 1432 1433 if (oh->_state == _HWMOD_STATE_UNKNOWN) 1434 return NULL; 1435 1436 return oh->_mpu_rt_va; 1437} 1438 1439int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, 1440 struct omap_hwmod *init_oh) 1441{ 1442 return _add_initiator_dep(oh, init_oh); 1443} 1444 1445 1446int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, 1447 struct omap_hwmod *init_oh) 1448{ 1449 return _del_initiator_dep(oh, init_oh); 1450} 1451 1452/** 1453 * omap_hwmod_enable_wakeup - allow device to wake up the system 1454 * @oh: struct omap_hwmod * 1455 * 1456 * Sets the module OCP socket ENAWAKEUP bit to allow the module to 1457 * send wakeups to the PRCM. Eventually this should sets PRCM wakeup 1458 * registers to cause the PRCM to receive wakeup events from the 1459 * module. Does not set any wakeup routing registers beyond this 1460 * point - if the module is to wake up any other module or subsystem, 1461 * that must be set separately. Called by omap_device code. Returns 1462 * -EINVAL on error or 0 upon success. 1463 */ 1464int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) 1465{ 1466 if (!oh->class->sysc || 1467 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1468 return -EINVAL; 1469 1470 mutex_lock(&omap_hwmod_mutex); 1471 _enable_wakeup(oh); 1472 mutex_unlock(&omap_hwmod_mutex); 1473 1474 return 0; 1475} 1476 1477/** 1478 * omap_hwmod_disable_wakeup - prevent device from waking the system 1479 * @oh: struct omap_hwmod * 1480 * 1481 * Clears the module OCP socket ENAWAKEUP bit to prevent the module 1482 * from sending wakeups to the PRCM. Eventually this should clear 1483 * PRCM wakeup registers to cause the PRCM to ignore wakeup events 1484 * from the module. Does not set any wakeup routing registers beyond 1485 * this point - if the module is to wake up any other module or 1486 * subsystem, that must be set separately. Called by omap_device 1487 * code. Returns -EINVAL on error or 0 upon success. 1488 */ 1489int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) 1490{ 1491 if (!oh->class->sysc || 1492 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1493 return -EINVAL; 1494 1495 mutex_lock(&omap_hwmod_mutex); 1496 _disable_wakeup(oh); 1497 mutex_unlock(&omap_hwmod_mutex); 1498 1499 return 0; 1500} 1501 1502/** 1503 * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname 1504 * @classname: struct omap_hwmod_class name to search for 1505 * @fn: callback function pointer to call for each hwmod in class @classname 1506 * @user: arbitrary context data to pass to the callback function 1507 * 1508 * For each omap_hwmod of class @classname, call @fn. Takes 1509 * omap_hwmod_mutex to prevent the hwmod list from changing during the 1510 * iteration. If the callback function returns something other than 1511 * zero, the iterator is terminated, and the callback function's return 1512 * value is passed back to the caller. Returns 0 upon success, -EINVAL 1513 * if @classname or @fn are NULL, or passes back the error code from @fn. 1514 */ 1515int omap_hwmod_for_each_by_class(const char *classname, 1516 int (*fn)(struct omap_hwmod *oh, 1517 void *user), 1518 void *user) 1519{ 1520 struct omap_hwmod *temp_oh; 1521 int ret = 0; 1522 1523 if (!classname || !fn) 1524 return -EINVAL; 1525 1526 pr_debug("omap_hwmod: %s: looking for modules of class %s\n", 1527 __func__, classname); 1528 1529 mutex_lock(&omap_hwmod_mutex); 1530 1531 list_for_each_entry(temp_oh, &omap_hwmod_list, node) { 1532 if (!strcmp(temp_oh->class->name, classname)) { 1533 pr_debug("omap_hwmod: %s: %s: calling callback fn\n", 1534 __func__, temp_oh->name); 1535 ret = (*fn)(temp_oh, user); 1536 if (ret) 1537 break; 1538 } 1539 } 1540 1541 mutex_unlock(&omap_hwmod_mutex); 1542 1543 if (ret) 1544 pr_debug("omap_hwmod: %s: iterator terminated early: %d\n", 1545 __func__, ret); 1546 1547 return ret; 1548} 1549