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