• Home
  • Raw
  • Download

Lines Matching +full:sleep +full:- +full:hardware +full:- +full:state

4  * Copyright (C) 2008-2011 Texas Instruments, Inc.
5 * Copyright (C) 2008-2011 Nokia Corporation
25 #include <linux/clk-provider.h>
59 if (!strcmp(name, temp_clkdm->name)) { in _clkdm_lookup()
69 * _clkdm_register - register a clockdomain
73 * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
80 if (!clkdm || !clkdm->name) in _clkdm_register()
81 return -EINVAL; in _clkdm_register()
83 pwrdm = pwrdm_lookup(clkdm->pwrdm.name); in _clkdm_register()
86 clkdm->name, clkdm->pwrdm.name); in _clkdm_register()
87 return -EINVAL; in _clkdm_register()
89 clkdm->pwrdm.ptr = pwrdm; in _clkdm_register()
92 if (_clkdm_lookup(clkdm->name)) in _clkdm_register()
93 return -EEXIST; in _clkdm_register()
95 list_add(&clkdm->node, &clkdm_list); in _clkdm_register()
99 pr_debug("clockdomain: registered %s\n", clkdm->name); in _clkdm_register()
104 /* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */
111 return ERR_PTR(-EINVAL); in _clkdm_deps_lookup()
113 for (cd = deps; cd->clkdm_name; cd++) { in _clkdm_deps_lookup()
114 if (!cd->clkdm && cd->clkdm_name) in _clkdm_deps_lookup()
115 cd->clkdm = _clkdm_lookup(cd->clkdm_name); in _clkdm_deps_lookup()
117 if (cd->clkdm == clkdm) in _clkdm_deps_lookup()
121 if (!cd->clkdm_name) in _clkdm_deps_lookup()
122 return ERR_PTR(-ENOENT); in _clkdm_deps_lookup()
128 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
133 * "autodep" is a clockdomain sleep/wakeup dependency that is
136 * clockdomain is in hardware-supervised mode. Meant to be called
150 clkdm = clkdm_lookup(autodep->clkdm.name); in _autodep_lookup()
153 autodep->clkdm.name); in _autodep_lookup()
154 clkdm = ERR_PTR(-ENOENT); in _autodep_lookup()
156 autodep->clkdm.ptr = clkdm; in _autodep_lookup()
160 * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
173 for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { in _resolve_clkdm_deps()
174 if (cd->clkdm) in _resolve_clkdm_deps()
176 cd->clkdm = _clkdm_lookup(cd->clkdm_name); in _resolve_clkdm_deps()
178 …WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should n… in _resolve_clkdm_deps()
179 clkdm->name, cd->clkdm_name); in _resolve_clkdm_deps()
184 * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless)
189 * @clkdm1. Implemented in hardware on the OMAP, this feature is
191 * Returns -EINVAL if presented with invalid clockdomain pointers,
192 * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
202 return -EINVAL; in _clkdm_add_wkdep()
204 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in _clkdm_add_wkdep()
208 if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) in _clkdm_add_wkdep()
209 ret = -EINVAL; in _clkdm_add_wkdep()
212 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", in _clkdm_add_wkdep()
213 clkdm1->name, clkdm2->name); in _clkdm_add_wkdep()
217 cd->wkdep_usecount++; in _clkdm_add_wkdep()
218 if (cd->wkdep_usecount == 1) { in _clkdm_add_wkdep()
219 pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", in _clkdm_add_wkdep()
220 clkdm1->name, clkdm2->name); in _clkdm_add_wkdep()
222 ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); in _clkdm_add_wkdep()
229 * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless)
234 * wakes up. Returns -EINVAL if presented with invalid clockdomain
235 * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
245 return -EINVAL; in _clkdm_del_wkdep()
247 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in _clkdm_del_wkdep()
251 if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) in _clkdm_del_wkdep()
252 ret = -EINVAL; in _clkdm_del_wkdep()
255 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", in _clkdm_del_wkdep()
256 clkdm1->name, clkdm2->name); in _clkdm_del_wkdep()
260 cd->wkdep_usecount--; in _clkdm_del_wkdep()
261 if (cd->wkdep_usecount == 0) { in _clkdm_del_wkdep()
262 pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", in _clkdm_del_wkdep()
263 clkdm1->name, clkdm2->name); in _clkdm_del_wkdep()
265 ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); in _clkdm_del_wkdep()
272 * _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless)
277 * retention or off) if @clkdm2 is active. Returns -EINVAL if
279 * that does not support software-configurable hardware sleep
280 * dependencies, -ENOENT if the specified dependency cannot be set in
281 * hardware, or 0 upon success.
290 return -EINVAL; in _clkdm_add_sleepdep()
292 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); in _clkdm_add_sleepdep()
296 if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) in _clkdm_add_sleepdep()
297 ret = -EINVAL; in _clkdm_add_sleepdep()
300 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", in _clkdm_add_sleepdep()
301 clkdm1->name, clkdm2->name); in _clkdm_add_sleepdep()
305 cd->sleepdep_usecount++; in _clkdm_add_sleepdep()
306 if (cd->sleepdep_usecount == 1) { in _clkdm_add_sleepdep()
308 clkdm1->name, clkdm2->name); in _clkdm_add_sleepdep()
310 ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); in _clkdm_add_sleepdep()
317 * _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless)
322 * off), independent of the activity state of @clkdm2. Returns -EINVAL
324 * that does not support software-configurable hardware sleep dependencies,
325 * -ENOENT if the specified dependency cannot be cleared in hardware, or
335 return -EINVAL; in _clkdm_del_sleepdep()
337 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); in _clkdm_del_sleepdep()
341 if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) in _clkdm_del_sleepdep()
342 ret = -EINVAL; in _clkdm_del_sleepdep()
345 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", in _clkdm_del_sleepdep()
346 clkdm1->name, clkdm2->name); in _clkdm_del_sleepdep()
350 cd->sleepdep_usecount--; in _clkdm_del_sleepdep()
351 if (cd->sleepdep_usecount == 0) { in _clkdm_del_sleepdep()
353 clkdm1->name, clkdm2->name); in _clkdm_del_sleepdep()
355 ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); in _clkdm_del_sleepdep()
364 * clkdm_register_platform_funcs - register clockdomain implementation fns
369 * before any other clkdm_register*() function. Returns -EINVAL if
370 * @co is null, -EEXIST if platform functions have already been
376 return -EINVAL; in clkdm_register_platform_funcs()
379 return -EEXIST; in clkdm_register_platform_funcs()
387 * clkdm_register_clkdms - register SoC clockdomains
392 * multiple times. Returns -EACCES if called before
393 * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is
401 return -EACCES; in clkdm_register_clkdms()
404 return -EINVAL; in clkdm_register_clkdms()
413 * clkdm_register_autodeps - register autodeps (if required)
417 * clockdomain wakeup and sleep dependencies that are automatically
432 * Returns -EACCES if called before any clockdomains have been
433 * registered, -EINVAL if called with a null @ia argument, -EEXIST if
441 return -EACCES; in clkdm_register_autodeps()
444 return -EINVAL; in clkdm_register_autodeps()
447 return -EEXIST; in clkdm_register_autodeps()
450 for (a = autodeps; a->clkdm.ptr; a++) in clkdm_register_autodeps()
473 * clkdm_complete_init - set up the clockdomain layer
475 * Put all clockdomains into software-supervised mode; PM code should
476 * later enable hardware-supervised mode as appropriate. Must be
477 * called after clkdm_register_clkdms(). Returns -EACCES if called
486 return -EACCES; in clkdm_complete_init()
491 _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs); in clkdm_complete_init()
494 _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); in clkdm_complete_init()
498 /* Only AM43XX can lose clkdm context during rtc-ddr suspend */ in clkdm_complete_init()
508 * clkdm_lookup - look up a clockdomain by name, return a pointer
524 if (!strcmp(name, temp_clkdm->name)) { in clkdm_lookup()
534 * clkdm_for_each - call function on each registered clockdomain
541 * functions should be called from the callback, although hardware
544 * anything else to indicate failure; or -EINVAL if the function pointer
554 return -EINVAL; in clkdm_for_each()
567 * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in
578 return clkdm->pwrdm.ptr; in clkdm_get_pwrdm()
582 /* Hardware clockdomain control */
585 * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1
590 * @clkdm1. Implemented in hardware on the OMAP, this feature is
592 * Returns -EINVAL if presented with invalid clockdomain pointers,
593 * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
602 return -EINVAL; in clkdm_add_wkdep()
604 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in clkdm_add_wkdep()
608 pwrdm_lock(cd->clkdm->pwrdm.ptr); in clkdm_add_wkdep()
610 pwrdm_unlock(cd->clkdm->pwrdm.ptr); in clkdm_add_wkdep()
616 * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1
621 * wakes up. Returns -EINVAL if presented with invalid clockdomain
622 * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
631 return -EINVAL; in clkdm_del_wkdep()
633 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in clkdm_del_wkdep()
637 pwrdm_lock(cd->clkdm->pwrdm.ptr); in clkdm_del_wkdep()
639 pwrdm_unlock(cd->clkdm->pwrdm.ptr); in clkdm_del_wkdep()
645 * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1
649 * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be
650 * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL
651 * if either clockdomain pointer is invalid; or -ENOENT if the hardware
654 * REVISIT: Currently this function only represents software-controllable
655 * wakeup dependencies. Wakeup dependencies fixed in hardware are not
664 return -EINVAL; in clkdm_read_wkdep()
666 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in clkdm_read_wkdep()
670 if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep) in clkdm_read_wkdep()
671 ret = -EINVAL; in clkdm_read_wkdep()
674 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", in clkdm_read_wkdep()
675 clkdm1->name, clkdm2->name); in clkdm_read_wkdep()
680 return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); in clkdm_read_wkdep()
684 * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm
687 * Remove all inter-clockdomain wakeup dependencies that could cause
689 * PRCM to a known state, after all clockdomains are put into swsup idle
690 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
696 return -EINVAL; in clkdm_clear_all_wkdeps()
698 if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps) in clkdm_clear_all_wkdeps()
699 return -EINVAL; in clkdm_clear_all_wkdeps()
701 return arch_clkdm->clkdm_clear_all_wkdeps(clkdm); in clkdm_clear_all_wkdeps()
705 * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1
710 * retention or off) if @clkdm2 is active. Returns -EINVAL if
712 * that does not support software-configurable hardware sleep
713 * dependencies, -ENOENT if the specified dependency cannot be set in
714 * hardware, or 0 upon success.
722 return -EINVAL; in clkdm_add_sleepdep()
724 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in clkdm_add_sleepdep()
728 pwrdm_lock(cd->clkdm->pwrdm.ptr); in clkdm_add_sleepdep()
730 pwrdm_unlock(cd->clkdm->pwrdm.ptr); in clkdm_add_sleepdep()
736 * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1
741 * off), independent of the activity state of @clkdm2. Returns -EINVAL
743 * that does not support software-configurable hardware sleep dependencies,
744 * -ENOENT if the specified dependency cannot be cleared in hardware, or
753 return -EINVAL; in clkdm_del_sleepdep()
755 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); in clkdm_del_sleepdep()
759 pwrdm_lock(cd->clkdm->pwrdm.ptr); in clkdm_del_sleepdep()
761 pwrdm_unlock(cd->clkdm->pwrdm.ptr); in clkdm_del_sleepdep()
767 * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1
771 * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will
773 * 0 if @clkdm1's automatic power state inactivity transition is independent
774 * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called
775 * on a machine that does not support software-configurable hardware sleep
776 * dependencies; or -ENOENT if the hardware is incapable.
778 * REVISIT: Currently this function only represents software-controllable
779 * sleep dependencies. Sleep dependencies fixed in hardware are not
788 return -EINVAL; in clkdm_read_sleepdep()
790 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); in clkdm_read_sleepdep()
794 if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep) in clkdm_read_sleepdep()
795 ret = -EINVAL; in clkdm_read_sleepdep()
798 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", in clkdm_read_sleepdep()
799 clkdm1->name, clkdm2->name); in clkdm_read_sleepdep()
804 return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); in clkdm_read_sleepdep()
808 * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm
809 * @clkdm: struct clockdomain * to remove all sleep dependencies from
811 * Remove all inter-clockdomain sleep dependencies that could prevent
813 * PRCM to a known state, after all clockdomains are put into swsup idle
814 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
820 return -EINVAL; in clkdm_clear_all_sleepdeps()
822 if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps) in clkdm_clear_all_sleepdeps()
823 return -EINVAL; in clkdm_clear_all_sleepdeps()
825 return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm); in clkdm_clear_all_sleepdeps()
829 * clkdm_sleep_nolock - force clockdomain sleep transition (lockless)
832 * Instruct the CM to force a sleep transition on the specified
834 * -EINVAL if @clkdm is NULL or if clockdomain does not support
835 * software-initiated sleep; 0 upon success.
842 return -EINVAL; in clkdm_sleep_nolock()
844 if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { in clkdm_sleep_nolock()
845 pr_debug("clockdomain: %s does not support forcing sleep via software\n", in clkdm_sleep_nolock()
846 clkdm->name); in clkdm_sleep_nolock()
847 return -EINVAL; in clkdm_sleep_nolock()
850 if (!arch_clkdm || !arch_clkdm->clkdm_sleep) in clkdm_sleep_nolock()
851 return -EINVAL; in clkdm_sleep_nolock()
853 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); in clkdm_sleep_nolock()
855 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; in clkdm_sleep_nolock()
856 ret = arch_clkdm->clkdm_sleep(clkdm); in clkdm_sleep_nolock()
857 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_sleep_nolock()
863 * clkdm_sleep - force clockdomain sleep transition
866 * Instruct the CM to force a sleep transition on the specified
867 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if
868 * clockdomain does not support software-initiated sleep; 0 upon
875 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_sleep()
877 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_sleep()
883 * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless)
888 * -EINVAL if @clkdm is NULL or if the clockdomain does not support
889 * software-controlled wakeup; 0 upon success.
896 return -EINVAL; in clkdm_wakeup_nolock()
898 if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { in clkdm_wakeup_nolock()
900 clkdm->name); in clkdm_wakeup_nolock()
901 return -EINVAL; in clkdm_wakeup_nolock()
904 if (!arch_clkdm || !arch_clkdm->clkdm_wakeup) in clkdm_wakeup_nolock()
905 return -EINVAL; in clkdm_wakeup_nolock()
907 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); in clkdm_wakeup_nolock()
909 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; in clkdm_wakeup_nolock()
910 ret = arch_clkdm->clkdm_wakeup(clkdm); in clkdm_wakeup_nolock()
911 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_wakeup_nolock()
917 * clkdm_wakeup - force clockdomain wakeup transition
921 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the
922 * clockdomain does not support software-controlled wakeup; 0 upon
929 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_wakeup()
931 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_wakeup()
937 * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm
940 * Allow the hardware to automatically switch the clockdomain @clkdm
952 if (!WARN_ON(!clkdm->forcewake_count)) in clkdm_allow_idle_nolock()
953 clkdm->forcewake_count--; in clkdm_allow_idle_nolock()
955 if (clkdm->forcewake_count) in clkdm_allow_idle_nolock()
958 if (!clkdm->usecount && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) in clkdm_allow_idle_nolock()
961 if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) in clkdm_allow_idle_nolock()
964 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) in clkdm_allow_idle_nolock()
967 if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle) in clkdm_allow_idle_nolock()
971 clkdm->name); in clkdm_allow_idle_nolock()
973 clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; in clkdm_allow_idle_nolock()
974 arch_clkdm->clkdm_allow_idle(clkdm); in clkdm_allow_idle_nolock()
975 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_allow_idle_nolock()
979 * clkdm_allow_idle - enable hwsup idle transitions for clkdm
982 * Allow the hardware to automatically switch the clockdomain @clkdm into
990 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_allow_idle()
992 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_allow_idle()
996 * clkdm_deny_idle - disable hwsup idle transitions for clkdm
999 * Prevent the hardware from automatically switching the clockdomain
1010 if (clkdm->forcewake_count++) in clkdm_deny_idle_nolock()
1013 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) in clkdm_deny_idle_nolock()
1016 if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) in clkdm_deny_idle_nolock()
1019 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) in clkdm_deny_idle_nolock()
1022 if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle) in clkdm_deny_idle_nolock()
1026 clkdm->name); in clkdm_deny_idle_nolock()
1028 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; in clkdm_deny_idle_nolock()
1029 arch_clkdm->clkdm_deny_idle(clkdm); in clkdm_deny_idle_nolock()
1030 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_deny_idle_nolock()
1034 * clkdm_deny_idle - disable hwsup idle transitions for clkdm
1037 * Prevent the hardware from automatically switching the clockdomain
1044 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_deny_idle()
1046 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_deny_idle()
1050 * clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled?
1054 * hardware-supervised idle enabled, or false if it does not or if
1057 * bits from the hardware; it instead tests an in-memory flag that is
1058 * changed whenever the clockdomain code changes the auto-idle mode.
1067 ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; in clkdm_in_hwsup()
1073 * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
1086 return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; in clkdm_missing_idle_reporting()
1092 * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
1095 * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
1096 * in hardware-supervised mode. Meant to be called from clock framework
1106 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) in clkdm_add_autodeps()
1109 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { in clkdm_add_autodeps()
1110 if (IS_ERR(autodep->clkdm.ptr)) in clkdm_add_autodeps()
1114 clkdm->name, autodep->clkdm.ptr->name); in clkdm_add_autodeps()
1116 _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); in clkdm_add_autodeps()
1117 _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); in clkdm_add_autodeps()
1122 * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm
1125 * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
1126 * in hardware-supervised mode. Meant to be called from clock framework
1136 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) in clkdm_del_autodeps()
1139 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { in clkdm_del_autodeps()
1140 if (IS_ERR(autodep->clkdm.ptr)) in clkdm_del_autodeps()
1144 clkdm->name, autodep->clkdm.ptr->name); in clkdm_del_autodeps()
1146 _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); in clkdm_del_autodeps()
1147 _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); in clkdm_del_autodeps()
1151 /* Clockdomain-to-clock/hwmod framework interface code */
1155 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) in _clkdm_clk_hwmod_enable()
1156 return -EINVAL; in _clkdm_clk_hwmod_enable()
1158 pwrdm_lock(clkdm->pwrdm.ptr); in _clkdm_clk_hwmod_enable()
1165 clkdm->usecount++; in _clkdm_clk_hwmod_enable()
1166 if (clkdm->usecount > 1 && autodeps) { in _clkdm_clk_hwmod_enable()
1167 pwrdm_unlock(clkdm->pwrdm.ptr); in _clkdm_clk_hwmod_enable()
1171 arch_clkdm->clkdm_clk_enable(clkdm); in _clkdm_clk_hwmod_enable()
1172 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in _clkdm_clk_hwmod_enable()
1173 pwrdm_unlock(clkdm->pwrdm.ptr); in _clkdm_clk_hwmod_enable()
1175 pr_debug("clockdomain: %s: enabled\n", clkdm->name); in _clkdm_clk_hwmod_enable()
1181 * clkdm_clk_enable - add an enabled downstream clock to this clkdm
1187 * clk_enable() code. If the clockdomain is in software-supervised
1189 * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
1191 * by on-chip processors. Returns -EINVAL if passed null pointers;
1202 return -EINVAL; in clkdm_clk_enable()
1208 * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
1214 * clockdomain usecount goes to 0, put the clockdomain to sleep
1215 * (software-supervised mode) or remove the clkdm autodependencies
1216 * (hardware-supervised mode). Returns -EINVAL if passed null
1217 * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0
1222 if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) in clkdm_clk_disable()
1223 return -EINVAL; in clkdm_clk_disable()
1225 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_clk_disable()
1228 if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0) in clkdm_clk_disable()
1231 if (clkdm->usecount == 0) { in clkdm_clk_disable()
1232 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_clk_disable()
1234 return -ERANGE; in clkdm_clk_disable()
1237 clkdm->usecount--; in clkdm_clk_disable()
1238 if (clkdm->usecount > 0) { in clkdm_clk_disable()
1239 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_clk_disable()
1243 arch_clkdm->clkdm_clk_disable(clkdm); in clkdm_clk_disable()
1244 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_clk_disable()
1246 pr_debug("clockdomain: %s: disabled\n", clkdm->name); in clkdm_clk_disable()
1249 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_clk_disable()
1255 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
1262 * If the clockdomain is in software-supervised idle mode, force the
1263 * clockdomain to wake. If the clockdomain is in hardware-supervised idle
1264 * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the
1265 * clockdomain can be read from/written to by on-chip processors.
1266 * Returns -EINVAL if passed null pointers;
1281 return -EINVAL; in clkdm_hwmod_enable()
1287 * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm
1293 * If the clockdomain usecount goes to 0, put the clockdomain to sleep
1294 * (software-supervised mode) or remove the clkdm autodependencies
1295 * (hardware-supervised mode).
1296 * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount
1311 if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) in clkdm_hwmod_disable()
1312 return -EINVAL; in clkdm_hwmod_disable()
1314 pwrdm_lock(clkdm->pwrdm.ptr); in clkdm_hwmod_disable()
1316 if (clkdm->usecount == 0) { in clkdm_hwmod_disable()
1317 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_hwmod_disable()
1319 return -ERANGE; in clkdm_hwmod_disable()
1322 clkdm->usecount--; in clkdm_hwmod_disable()
1323 if (clkdm->usecount > 0) { in clkdm_hwmod_disable()
1324 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_hwmod_disable()
1328 arch_clkdm->clkdm_clk_disable(clkdm); in clkdm_hwmod_disable()
1329 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); in clkdm_hwmod_disable()
1330 pwrdm_unlock(clkdm->pwrdm.ptr); in clkdm_hwmod_disable()
1332 pr_debug("clockdomain: %s: disabled\n", clkdm->name); in clkdm_hwmod_disable()
1338 * _clkdm_save_context - save the context for the control of this clkdm
1340 * Due to a suspend or hibernation operation, the state of the registers
1345 if (!arch_clkdm || !arch_clkdm->clkdm_save_context) in _clkdm_save_context()
1346 return -EINVAL; in _clkdm_save_context()
1348 return arch_clkdm->clkdm_save_context(clkdm); in _clkdm_save_context()
1352 * _clkdm_restore_context - restore context for control of this clkdm
1358 if (!arch_clkdm || !arch_clkdm->clkdm_restore_context) in _clkdm_restore_context()
1359 return -EINVAL; in _clkdm_restore_context()
1361 return arch_clkdm->clkdm_restore_context(clkdm); in _clkdm_restore_context()
1365 * clkdm_save_context - Saves the context for each registered clkdm
1375 * clkdm_restore_context - Restores the context for each registered clkdm