1 /* 2 * OMAP2/3/4 clockdomain framework functions 3 * 4 * Copyright (C) 2008-2011 Texas Instruments, Inc. 5 * Copyright (C) 2008-2011 Nokia Corporation 6 * 7 * Written by Paul Walmsley and Jouni Högander 8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 #undef DEBUG 15 16 #include <linux/kernel.h> 17 #include <linux/device.h> 18 #include <linux/list.h> 19 #include <linux/errno.h> 20 #include <linux/string.h> 21 #include <linux/delay.h> 22 #include <linux/clk.h> 23 #include <linux/limits.h> 24 #include <linux/err.h> 25 26 #include <linux/io.h> 27 28 #include <linux/bitops.h> 29 30 #include "clock.h" 31 #include "clockdomain.h" 32 33 /* clkdm_list contains all registered struct clockdomains */ 34 static LIST_HEAD(clkdm_list); 35 36 /* array of clockdomain deps to be added/removed when clkdm in hwsup mode */ 37 static struct clkdm_autodep *autodeps; 38 39 static struct clkdm_ops *arch_clkdm; 40 41 /* Private functions */ 42 43 static struct clockdomain *_clkdm_lookup(const char *name) 44 { 45 struct clockdomain *clkdm, *temp_clkdm; 46 47 if (!name) 48 return NULL; 49 50 clkdm = NULL; 51 52 list_for_each_entry(temp_clkdm, &clkdm_list, node) { 53 if (!strcmp(name, temp_clkdm->name)) { 54 clkdm = temp_clkdm; 55 break; 56 } 57 } 58 59 return clkdm; 60 } 61 62 /** 63 * _clkdm_register - register a clockdomain 64 * @clkdm: struct clockdomain * to register 65 * 66 * Adds a clockdomain to the internal clockdomain list. 67 * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is 68 * already registered by the provided name, or 0 upon success. 69 */ 70 static int _clkdm_register(struct clockdomain *clkdm) 71 { 72 struct powerdomain *pwrdm; 73 74 if (!clkdm || !clkdm->name) 75 return -EINVAL; 76 77 pwrdm = pwrdm_lookup(clkdm->pwrdm.name); 78 if (!pwrdm) { 79 pr_err("clockdomain: %s: powerdomain %s does not exist\n", 80 clkdm->name, clkdm->pwrdm.name); 81 return -EINVAL; 82 } 83 clkdm->pwrdm.ptr = pwrdm; 84 85 /* Verify that the clockdomain is not already registered */ 86 if (_clkdm_lookup(clkdm->name)) 87 return -EEXIST; 88 89 list_add(&clkdm->node, &clkdm_list); 90 91 pwrdm_add_clkdm(pwrdm, clkdm); 92 93 spin_lock_init(&clkdm->lock); 94 95 pr_debug("clockdomain: registered %s\n", clkdm->name); 96 97 return 0; 98 } 99 100 /* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */ 101 static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm, 102 struct clkdm_dep *deps) 103 { 104 struct clkdm_dep *cd; 105 106 if (!clkdm || !deps) 107 return ERR_PTR(-EINVAL); 108 109 for (cd = deps; cd->clkdm_name; cd++) { 110 if (!cd->clkdm && cd->clkdm_name) 111 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 112 113 if (cd->clkdm == clkdm) 114 break; 115 } 116 117 if (!cd->clkdm_name) 118 return ERR_PTR(-ENOENT); 119 120 return cd; 121 } 122 123 /* 124 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store 125 * @autodep: struct clkdm_autodep * to resolve 126 * 127 * Resolve autodep clockdomain names to clockdomain pointers via 128 * clkdm_lookup() and store the pointers in the autodep structure. An 129 * "autodep" is a clockdomain sleep/wakeup dependency that is 130 * automatically added and removed whenever clocks in the associated 131 * clockdomain are enabled or disabled (respectively) when the 132 * clockdomain is in hardware-supervised mode. Meant to be called 133 * once at clockdomain layer initialization, since these should remain 134 * fixed for a particular architecture. No return value. 135 * 136 * XXX autodeps are deprecated and should be removed at the earliest 137 * opportunity 138 */ 139 static void _autodep_lookup(struct clkdm_autodep *autodep) 140 { 141 struct clockdomain *clkdm; 142 143 if (!autodep) 144 return; 145 146 clkdm = clkdm_lookup(autodep->clkdm.name); 147 if (!clkdm) { 148 pr_err("clockdomain: autodeps: clockdomain %s does not exist\n", 149 autodep->clkdm.name); 150 clkdm = ERR_PTR(-ENOENT); 151 } 152 autodep->clkdm.ptr = clkdm; 153 } 154 155 /* 156 * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable 157 * @clkdm: struct clockdomain * 158 * 159 * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' 160 * in hardware-supervised mode. Meant to be called from clock framework 161 * when a clock inside clockdomain 'clkdm' is enabled. No return value. 162 * 163 * XXX autodeps are deprecated and should be removed at the earliest 164 * opportunity 165 */ 166 void _clkdm_add_autodeps(struct clockdomain *clkdm) 167 { 168 struct clkdm_autodep *autodep; 169 170 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) 171 return; 172 173 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { 174 if (IS_ERR(autodep->clkdm.ptr)) 175 continue; 176 177 pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", 178 clkdm->name, autodep->clkdm.ptr->name); 179 180 clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); 181 clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); 182 } 183 } 184 185 /* 186 * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm 187 * @clkdm: struct clockdomain * 188 * 189 * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' 190 * in hardware-supervised mode. Meant to be called from clock framework 191 * when a clock inside clockdomain 'clkdm' is disabled. No return value. 192 * 193 * XXX autodeps are deprecated and should be removed at the earliest 194 * opportunity 195 */ 196 void _clkdm_del_autodeps(struct clockdomain *clkdm) 197 { 198 struct clkdm_autodep *autodep; 199 200 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) 201 return; 202 203 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { 204 if (IS_ERR(autodep->clkdm.ptr)) 205 continue; 206 207 pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", 208 clkdm->name, autodep->clkdm.ptr->name); 209 210 clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); 211 clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); 212 } 213 } 214 215 /** 216 * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms 217 * @clkdm: clockdomain that we are resolving dependencies for 218 * @clkdm_deps: ptr to array of struct clkdm_deps to resolve 219 * 220 * Iterates through @clkdm_deps, looking up the struct clockdomain named by 221 * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. 222 * No return value. 223 */ 224 static void _resolve_clkdm_deps(struct clockdomain *clkdm, 225 struct clkdm_dep *clkdm_deps) 226 { 227 struct clkdm_dep *cd; 228 229 for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { 230 if (cd->clkdm) 231 continue; 232 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 233 234 WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", 235 clkdm->name, cd->clkdm_name); 236 } 237 } 238 239 /* Public functions */ 240 241 /** 242 * clkdm_register_platform_funcs - register clockdomain implementation fns 243 * @co: func pointers for arch specific implementations 244 * 245 * Register the list of function pointers used to implement the 246 * clockdomain functions on different OMAP SoCs. Should be called 247 * before any other clkdm_register*() function. Returns -EINVAL if 248 * @co is null, -EEXIST if platform functions have already been 249 * registered, or 0 upon success. 250 */ 251 int clkdm_register_platform_funcs(struct clkdm_ops *co) 252 { 253 if (!co) 254 return -EINVAL; 255 256 if (arch_clkdm) 257 return -EEXIST; 258 259 arch_clkdm = co; 260 261 return 0; 262 }; 263 264 /** 265 * clkdm_register_clkdms - register SoC clockdomains 266 * @cs: pointer to an array of struct clockdomain to register 267 * 268 * Register the clockdomains available on a particular OMAP SoC. Must 269 * be called after clkdm_register_platform_funcs(). May be called 270 * multiple times. Returns -EACCES if called before 271 * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is 272 * null; or 0 upon success. 273 */ 274 int clkdm_register_clkdms(struct clockdomain **cs) 275 { 276 struct clockdomain **c = NULL; 277 278 if (!arch_clkdm) 279 return -EACCES; 280 281 if (!cs) 282 return -EINVAL; 283 284 for (c = cs; *c; c++) 285 _clkdm_register(*c); 286 287 return 0; 288 } 289 290 /** 291 * clkdm_register_autodeps - register autodeps (if required) 292 * @ia: pointer to a static array of struct clkdm_autodep to register 293 * 294 * Register clockdomain "automatic dependencies." These are 295 * clockdomain wakeup and sleep dependencies that are automatically 296 * added whenever the first clock inside a clockdomain is enabled, and 297 * removed whenever the last clock inside a clockdomain is disabled. 298 * These are currently only used on OMAP3 devices, and are deprecated, 299 * since they waste energy. However, until the OMAP2/3 IP block 300 * enable/disable sequence can be converted to match the OMAP4 301 * sequence, they are needed. 302 * 303 * Must be called only after all of the SoC clockdomains are 304 * registered, since the function will resolve autodep clockdomain 305 * names into clockdomain pointers. 306 * 307 * The struct clkdm_autodep @ia array must be static, as this function 308 * does not copy the array elements. 309 * 310 * Returns -EACCES if called before any clockdomains have been 311 * registered, -EINVAL if called with a null @ia argument, -EEXIST if 312 * autodeps have already been registered, or 0 upon success. 313 */ 314 int clkdm_register_autodeps(struct clkdm_autodep *ia) 315 { 316 struct clkdm_autodep *a = NULL; 317 318 if (list_empty(&clkdm_list)) 319 return -EACCES; 320 321 if (!ia) 322 return -EINVAL; 323 324 if (autodeps) 325 return -EEXIST; 326 327 autodeps = ia; 328 for (a = autodeps; a->clkdm.ptr; a++) 329 _autodep_lookup(a); 330 331 return 0; 332 } 333 334 /** 335 * clkdm_complete_init - set up the clockdomain layer 336 * 337 * Put all clockdomains into software-supervised mode; PM code should 338 * later enable hardware-supervised mode as appropriate. Must be 339 * called after clkdm_register_clkdms(). Returns -EACCES if called 340 * before clkdm_register_clkdms(), or 0 upon success. 341 */ 342 int clkdm_complete_init(void) 343 { 344 struct clockdomain *clkdm; 345 346 if (list_empty(&clkdm_list)) 347 return -EACCES; 348 349 list_for_each_entry(clkdm, &clkdm_list, node) { 350 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) 351 clkdm_wakeup(clkdm); 352 else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO) 353 clkdm_deny_idle(clkdm); 354 355 _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs); 356 clkdm_clear_all_wkdeps(clkdm); 357 358 _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); 359 clkdm_clear_all_sleepdeps(clkdm); 360 } 361 362 return 0; 363 } 364 365 /** 366 * clkdm_lookup - look up a clockdomain by name, return a pointer 367 * @name: name of clockdomain 368 * 369 * Find a registered clockdomain by its name @name. Returns a pointer 370 * to the struct clockdomain if found, or NULL otherwise. 371 */ 372 struct clockdomain *clkdm_lookup(const char *name) 373 { 374 struct clockdomain *clkdm, *temp_clkdm; 375 376 if (!name) 377 return NULL; 378 379 clkdm = NULL; 380 381 list_for_each_entry(temp_clkdm, &clkdm_list, node) { 382 if (!strcmp(name, temp_clkdm->name)) { 383 clkdm = temp_clkdm; 384 break; 385 } 386 } 387 388 return clkdm; 389 } 390 391 /** 392 * clkdm_for_each - call function on each registered clockdomain 393 * @fn: callback function * 394 * 395 * Call the supplied function @fn for each registered clockdomain. 396 * The callback function @fn can return anything but 0 to bail 397 * out early from the iterator. The callback function is called with 398 * the clkdm_mutex held, so no clockdomain structure manipulation 399 * functions should be called from the callback, although hardware 400 * clockdomain control functions are fine. Returns the last return 401 * value of the callback function, which should be 0 for success or 402 * anything else to indicate failure; or -EINVAL if the function pointer 403 * is null. 404 */ 405 int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), 406 void *user) 407 { 408 struct clockdomain *clkdm; 409 int ret = 0; 410 411 if (!fn) 412 return -EINVAL; 413 414 list_for_each_entry(clkdm, &clkdm_list, node) { 415 ret = (*fn)(clkdm, user); 416 if (ret) 417 break; 418 } 419 420 return ret; 421 } 422 423 424 /** 425 * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in 426 * @clkdm: struct clockdomain * 427 * 428 * Return a pointer to the struct powerdomain that the specified clockdomain 429 * @clkdm exists in, or returns NULL if @clkdm is NULL. 430 */ 431 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm) 432 { 433 if (!clkdm) 434 return NULL; 435 436 return clkdm->pwrdm.ptr; 437 } 438 439 440 /* Hardware clockdomain control */ 441 442 /** 443 * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 444 * @clkdm1: wake this struct clockdomain * up (dependent) 445 * @clkdm2: when this struct clockdomain * wakes up (source) 446 * 447 * When the clockdomain represented by @clkdm2 wakes up, wake up 448 * @clkdm1. Implemented in hardware on the OMAP, this feature is 449 * designed to reduce wakeup latency of the dependent clockdomain @clkdm1. 450 * Returns -EINVAL if presented with invalid clockdomain pointers, 451 * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon 452 * success. 453 */ 454 int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 455 { 456 struct clkdm_dep *cd; 457 int ret = 0; 458 459 if (!clkdm1 || !clkdm2) 460 return -EINVAL; 461 462 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 463 if (IS_ERR(cd)) 464 ret = PTR_ERR(cd); 465 466 if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) 467 ret = -EINVAL; 468 469 if (ret) { 470 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", 471 clkdm1->name, clkdm2->name); 472 return ret; 473 } 474 475 if (atomic_inc_return(&cd->wkdep_usecount) == 1) { 476 pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", 477 clkdm1->name, clkdm2->name); 478 479 ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); 480 } 481 482 return ret; 483 } 484 485 /** 486 * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1 487 * @clkdm1: wake this struct clockdomain * up (dependent) 488 * @clkdm2: when this struct clockdomain * wakes up (source) 489 * 490 * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 491 * wakes up. Returns -EINVAL if presented with invalid clockdomain 492 * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 493 * 0 upon success. 494 */ 495 int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 496 { 497 struct clkdm_dep *cd; 498 int ret = 0; 499 500 if (!clkdm1 || !clkdm2) 501 return -EINVAL; 502 503 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 504 if (IS_ERR(cd)) 505 ret = PTR_ERR(cd); 506 507 if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) 508 ret = -EINVAL; 509 510 if (ret) { 511 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", 512 clkdm1->name, clkdm2->name); 513 return ret; 514 } 515 516 if (atomic_dec_return(&cd->wkdep_usecount) == 0) { 517 pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", 518 clkdm1->name, clkdm2->name); 519 520 ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); 521 } 522 523 return ret; 524 } 525 526 /** 527 * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1 528 * @clkdm1: wake this struct clockdomain * up (dependent) 529 * @clkdm2: when this struct clockdomain * wakes up (source) 530 * 531 * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be 532 * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL 533 * if either clockdomain pointer is invalid; or -ENOENT if the hardware 534 * is incapable. 535 * 536 * REVISIT: Currently this function only represents software-controllable 537 * wakeup dependencies. Wakeup dependencies fixed in hardware are not 538 * yet handled here. 539 */ 540 int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 541 { 542 struct clkdm_dep *cd; 543 int ret = 0; 544 545 if (!clkdm1 || !clkdm2) 546 return -EINVAL; 547 548 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 549 if (IS_ERR(cd)) 550 ret = PTR_ERR(cd); 551 552 if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep) 553 ret = -EINVAL; 554 555 if (ret) { 556 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", 557 clkdm1->name, clkdm2->name); 558 return ret; 559 } 560 561 /* XXX It's faster to return the atomic wkdep_usecount */ 562 return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); 563 } 564 565 /** 566 * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm 567 * @clkdm: struct clockdomain * to remove all wakeup dependencies from 568 * 569 * Remove all inter-clockdomain wakeup dependencies that could cause 570 * @clkdm to wake. Intended to be used during boot to initialize the 571 * PRCM to a known state, after all clockdomains are put into swsup idle 572 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or 573 * 0 upon success. 574 */ 575 int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) 576 { 577 if (!clkdm) 578 return -EINVAL; 579 580 if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps) 581 return -EINVAL; 582 583 return arch_clkdm->clkdm_clear_all_wkdeps(clkdm); 584 } 585 586 /** 587 * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 588 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) 589 * @clkdm2: when this struct clockdomain * is active (source) 590 * 591 * Prevent @clkdm1 from automatically going inactive (and then to 592 * retention or off) if @clkdm2 is active. Returns -EINVAL if 593 * presented with invalid clockdomain pointers or called on a machine 594 * that does not support software-configurable hardware sleep 595 * dependencies, -ENOENT if the specified dependency cannot be set in 596 * hardware, or 0 upon success. 597 */ 598 int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 599 { 600 struct clkdm_dep *cd; 601 int ret = 0; 602 603 if (!clkdm1 || !clkdm2) 604 return -EINVAL; 605 606 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); 607 if (IS_ERR(cd)) 608 ret = PTR_ERR(cd); 609 610 if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) 611 ret = -EINVAL; 612 613 if (ret) { 614 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", 615 clkdm1->name, clkdm2->name); 616 return ret; 617 } 618 619 if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { 620 pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", 621 clkdm1->name, clkdm2->name); 622 623 ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); 624 } 625 626 return ret; 627 } 628 629 /** 630 * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1 631 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) 632 * @clkdm2: when this struct clockdomain * is active (source) 633 * 634 * Allow @clkdm1 to automatically go inactive (and then to retention or 635 * off), independent of the activity state of @clkdm2. Returns -EINVAL 636 * if presented with invalid clockdomain pointers or called on a machine 637 * that does not support software-configurable hardware sleep dependencies, 638 * -ENOENT if the specified dependency cannot be cleared in hardware, or 639 * 0 upon success. 640 */ 641 int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 642 { 643 struct clkdm_dep *cd; 644 int ret = 0; 645 646 if (!clkdm1 || !clkdm2) 647 return -EINVAL; 648 649 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); 650 if (IS_ERR(cd)) 651 ret = PTR_ERR(cd); 652 653 if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) 654 ret = -EINVAL; 655 656 if (ret) { 657 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", 658 clkdm1->name, clkdm2->name); 659 return ret; 660 } 661 662 if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { 663 pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", 664 clkdm1->name, clkdm2->name); 665 666 ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); 667 } 668 669 return ret; 670 } 671 672 /** 673 * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1 674 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) 675 * @clkdm2: when this struct clockdomain * is active (source) 676 * 677 * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will 678 * not be allowed to automatically go inactive if @clkdm2 is active; 679 * 0 if @clkdm1's automatic power state inactivity transition is independent 680 * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called 681 * on a machine that does not support software-configurable hardware sleep 682 * dependencies; or -ENOENT if the hardware is incapable. 683 * 684 * REVISIT: Currently this function only represents software-controllable 685 * sleep dependencies. Sleep dependencies fixed in hardware are not 686 * yet handled here. 687 */ 688 int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 689 { 690 struct clkdm_dep *cd; 691 int ret = 0; 692 693 if (!clkdm1 || !clkdm2) 694 return -EINVAL; 695 696 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); 697 if (IS_ERR(cd)) 698 ret = PTR_ERR(cd); 699 700 if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep) 701 ret = -EINVAL; 702 703 if (ret) { 704 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", 705 clkdm1->name, clkdm2->name); 706 return ret; 707 } 708 709 /* XXX It's faster to return the atomic sleepdep_usecount */ 710 return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); 711 } 712 713 /** 714 * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm 715 * @clkdm: struct clockdomain * to remove all sleep dependencies from 716 * 717 * Remove all inter-clockdomain sleep dependencies that could prevent 718 * @clkdm from idling. Intended to be used during boot to initialize the 719 * PRCM to a known state, after all clockdomains are put into swsup idle 720 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or 721 * 0 upon success. 722 */ 723 int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) 724 { 725 if (!clkdm) 726 return -EINVAL; 727 728 if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps) 729 return -EINVAL; 730 731 return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm); 732 } 733 734 /** 735 * clkdm_sleep - force clockdomain sleep transition 736 * @clkdm: struct clockdomain * 737 * 738 * Instruct the CM to force a sleep transition on the specified 739 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if 740 * clockdomain does not support software-initiated sleep; 0 upon 741 * success. 742 */ 743 int clkdm_sleep(struct clockdomain *clkdm) 744 { 745 int ret; 746 unsigned long flags; 747 748 if (!clkdm) 749 return -EINVAL; 750 751 if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { 752 pr_debug("clockdomain: %s does not support forcing sleep via software\n", 753 clkdm->name); 754 return -EINVAL; 755 } 756 757 if (!arch_clkdm || !arch_clkdm->clkdm_sleep) 758 return -EINVAL; 759 760 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); 761 762 spin_lock_irqsave(&clkdm->lock, flags); 763 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 764 ret = arch_clkdm->clkdm_sleep(clkdm); 765 spin_unlock_irqrestore(&clkdm->lock, flags); 766 return ret; 767 } 768 769 /** 770 * clkdm_wakeup - force clockdomain wakeup transition 771 * @clkdm: struct clockdomain * 772 * 773 * Instruct the CM to force a wakeup transition on the specified 774 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the 775 * clockdomain does not support software-controlled wakeup; 0 upon 776 * success. 777 */ 778 int clkdm_wakeup(struct clockdomain *clkdm) 779 { 780 int ret; 781 unsigned long flags; 782 783 if (!clkdm) 784 return -EINVAL; 785 786 if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { 787 pr_debug("clockdomain: %s does not support forcing wakeup via software\n", 788 clkdm->name); 789 return -EINVAL; 790 } 791 792 if (!arch_clkdm || !arch_clkdm->clkdm_wakeup) 793 return -EINVAL; 794 795 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); 796 797 spin_lock_irqsave(&clkdm->lock, flags); 798 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 799 ret = arch_clkdm->clkdm_wakeup(clkdm); 800 ret |= pwrdm_state_switch(clkdm->pwrdm.ptr); 801 spin_unlock_irqrestore(&clkdm->lock, flags); 802 return ret; 803 } 804 805 /** 806 * clkdm_allow_idle - enable hwsup idle transitions for clkdm 807 * @clkdm: struct clockdomain * 808 * 809 * Allow the hardware to automatically switch the clockdomain @clkdm into 810 * active or idle states, as needed by downstream clocks. If the 811 * clockdomain has any downstream clocks enabled in the clock 812 * framework, wkdep/sleepdep autodependencies are added; this is so 813 * device drivers can read and write to the device. No return value. 814 */ 815 void clkdm_allow_idle(struct clockdomain *clkdm) 816 { 817 unsigned long flags; 818 819 if (!clkdm) 820 return; 821 822 if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) { 823 pr_debug("clock: %s: automatic idle transitions cannot be enabled\n", 824 clkdm->name); 825 return; 826 } 827 828 if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle) 829 return; 830 831 pr_debug("clockdomain: enabling automatic idle transitions for %s\n", 832 clkdm->name); 833 834 spin_lock_irqsave(&clkdm->lock, flags); 835 clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; 836 arch_clkdm->clkdm_allow_idle(clkdm); 837 pwrdm_state_switch(clkdm->pwrdm.ptr); 838 spin_unlock_irqrestore(&clkdm->lock, flags); 839 } 840 841 /** 842 * clkdm_deny_idle - disable hwsup idle transitions for clkdm 843 * @clkdm: struct clockdomain * 844 * 845 * Prevent the hardware from automatically switching the clockdomain 846 * @clkdm into inactive or idle states. If the clockdomain has 847 * downstream clocks enabled in the clock framework, wkdep/sleepdep 848 * autodependencies are removed. No return value. 849 */ 850 void clkdm_deny_idle(struct clockdomain *clkdm) 851 { 852 unsigned long flags; 853 854 if (!clkdm) 855 return; 856 857 if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) { 858 pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n", 859 clkdm->name); 860 return; 861 } 862 863 if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle) 864 return; 865 866 pr_debug("clockdomain: disabling automatic idle transitions for %s\n", 867 clkdm->name); 868 869 spin_lock_irqsave(&clkdm->lock, flags); 870 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 871 arch_clkdm->clkdm_deny_idle(clkdm); 872 pwrdm_state_switch(clkdm->pwrdm.ptr); 873 spin_unlock_irqrestore(&clkdm->lock, flags); 874 } 875 876 /** 877 * clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled? 878 * @clkdm: struct clockdomain * 879 * 880 * Returns true if clockdomain @clkdm currently has 881 * hardware-supervised idle enabled, or false if it does not or if 882 * @clkdm is NULL. It is only valid to call this function after 883 * clkdm_init() has been called. This function does not actually read 884 * bits from the hardware; it instead tests an in-memory flag that is 885 * changed whenever the clockdomain code changes the auto-idle mode. 886 */ 887 bool clkdm_in_hwsup(struct clockdomain *clkdm) 888 { 889 bool ret; 890 unsigned long flags; 891 892 if (!clkdm) 893 return false; 894 895 spin_lock_irqsave(&clkdm->lock, flags); 896 ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; 897 spin_unlock_irqrestore(&clkdm->lock, flags); 898 899 return ret; 900 } 901 902 /** 903 * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use? 904 * @clkdm: struct clockdomain * 905 * 906 * Returns true if clockdomain @clkdm has the 907 * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is 908 * null. More information is available in the documentation for the 909 * CLKDM_MISSING_IDLE_REPORTING macro. 910 */ 911 bool clkdm_missing_idle_reporting(struct clockdomain *clkdm) 912 { 913 if (!clkdm) 914 return false; 915 916 return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; 917 } 918 919 /* Clockdomain-to-clock/hwmod framework interface code */ 920 921 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) 922 { 923 unsigned long flags; 924 925 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) 926 return -EINVAL; 927 928 /* 929 * For arch's with no autodeps, clkcm_clk_enable 930 * should be called for every clock instance or hwmod that is 931 * enabled, so the clkdm can be force woken up. 932 */ 933 if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) 934 return 0; 935 936 spin_lock_irqsave(&clkdm->lock, flags); 937 arch_clkdm->clkdm_clk_enable(clkdm); 938 pwrdm_state_switch(clkdm->pwrdm.ptr); 939 spin_unlock_irqrestore(&clkdm->lock, flags); 940 941 pr_debug("clockdomain: %s: enabled\n", clkdm->name); 942 943 return 0; 944 } 945 946 static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm) 947 { 948 unsigned long flags; 949 950 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) 951 return -EINVAL; 952 953 if (atomic_read(&clkdm->usecount) == 0) { 954 WARN_ON(1); /* underflow */ 955 return -ERANGE; 956 } 957 958 if (atomic_dec_return(&clkdm->usecount) > 0) 959 return 0; 960 961 spin_lock_irqsave(&clkdm->lock, flags); 962 arch_clkdm->clkdm_clk_disable(clkdm); 963 pwrdm_state_switch(clkdm->pwrdm.ptr); 964 spin_unlock_irqrestore(&clkdm->lock, flags); 965 966 pr_debug("clockdomain: %s: disabled\n", clkdm->name); 967 968 return 0; 969 } 970 971 /** 972 * clkdm_clk_enable - add an enabled downstream clock to this clkdm 973 * @clkdm: struct clockdomain * 974 * @clk: struct clk * of the enabled downstream clock 975 * 976 * Increment the usecount of the clockdomain @clkdm and ensure that it 977 * is awake before @clk is enabled. Intended to be called by 978 * clk_enable() code. If the clockdomain is in software-supervised 979 * idle mode, force the clockdomain to wake. If the clockdomain is in 980 * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to 981 * ensure that devices in the clockdomain can be read from/written to 982 * by on-chip processors. Returns -EINVAL if passed null pointers; 983 * returns 0 upon success or if the clockdomain is in hwsup idle mode. 984 */ 985 int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) 986 { 987 /* 988 * XXX Rewrite this code to maintain a list of enabled 989 * downstream clocks for debugging purposes? 990 */ 991 992 if (!clk) 993 return -EINVAL; 994 995 return _clkdm_clk_hwmod_enable(clkdm); 996 } 997 998 /** 999 * clkdm_clk_disable - remove an enabled downstream clock from this clkdm 1000 * @clkdm: struct clockdomain * 1001 * @clk: struct clk * of the disabled downstream clock 1002 * 1003 * Decrement the usecount of this clockdomain @clkdm when @clk is 1004 * disabled. Intended to be called by clk_disable() code. If the 1005 * clockdomain usecount goes to 0, put the clockdomain to sleep 1006 * (software-supervised mode) or remove the clkdm autodependencies 1007 * (hardware-supervised mode). Returns -EINVAL if passed null 1008 * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0 1009 * upon success or if the clockdomain is in hwsup idle mode. 1010 */ 1011 int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) 1012 { 1013 /* 1014 * XXX Rewrite this code to maintain a list of enabled 1015 * downstream clocks for debugging purposes? 1016 */ 1017 1018 if (!clk) 1019 return -EINVAL; 1020 1021 return _clkdm_clk_hwmod_disable(clkdm); 1022 } 1023 1024 /** 1025 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm 1026 * @clkdm: struct clockdomain * 1027 * @oh: struct omap_hwmod * of the enabled downstream hwmod 1028 * 1029 * Increment the usecount of the clockdomain @clkdm and ensure that it 1030 * is awake before @oh is enabled. Intended to be called by 1031 * module_enable() code. 1032 * If the clockdomain is in software-supervised idle mode, force the 1033 * clockdomain to wake. If the clockdomain is in hardware-supervised idle 1034 * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the 1035 * clockdomain can be read from/written to by on-chip processors. 1036 * Returns -EINVAL if passed null pointers; 1037 * returns 0 upon success or if the clockdomain is in hwsup idle mode. 1038 */ 1039 int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh) 1040 { 1041 /* The clkdm attribute does not exist yet prior OMAP4 */ 1042 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1043 return 0; 1044 1045 /* 1046 * XXX Rewrite this code to maintain a list of enabled 1047 * downstream hwmods for debugging purposes? 1048 */ 1049 1050 if (!oh) 1051 return -EINVAL; 1052 1053 return _clkdm_clk_hwmod_enable(clkdm); 1054 } 1055 1056 /** 1057 * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm 1058 * @clkdm: struct clockdomain * 1059 * @oh: struct omap_hwmod * of the disabled downstream hwmod 1060 * 1061 * Decrement the usecount of this clockdomain @clkdm when @oh is 1062 * disabled. Intended to be called by module_disable() code. 1063 * If the clockdomain usecount goes to 0, put the clockdomain to sleep 1064 * (software-supervised mode) or remove the clkdm autodependencies 1065 * (hardware-supervised mode). 1066 * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount 1067 * underflows; or returns 0 upon success or if the clockdomain is in hwsup 1068 * idle mode. 1069 */ 1070 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) 1071 { 1072 /* The clkdm attribute does not exist yet prior OMAP4 */ 1073 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1074 return 0; 1075 1076 /* 1077 * XXX Rewrite this code to maintain a list of enabled 1078 * downstream hwmods for debugging purposes? 1079 */ 1080 1081 if (!oh) 1082 return -EINVAL; 1083 1084 return _clkdm_clk_hwmod_disable(clkdm); 1085 } 1086 1087