Lines Matching refs:clkdm

37 /* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
48 struct clockdomain *clkdm, *temp_clkdm;
53 clkdm = NULL;
57 clkdm = temp_clkdm;
62 return clkdm;
67 * @clkdm: struct clockdomain * to register
73 static int _clkdm_register(struct clockdomain *clkdm)
77 if (!clkdm || !clkdm->name)
80 pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
83 clkdm->name, clkdm->pwrdm.name);
86 clkdm->pwrdm.ptr = pwrdm;
89 if (_clkdm_lookup(clkdm->name))
92 list_add(&clkdm->node, &clkdm_list);
94 pwrdm_add_clkdm(pwrdm, clkdm);
96 pr_debug("clockdomain: registered %s\n", clkdm->name);
101 /* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */
102 static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
107 if (!clkdm || !deps)
111 if (!cd->clkdm && cd->clkdm_name)
112 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
114 if (cd->clkdm == clkdm)
125 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
142 struct clockdomain *clkdm;
147 clkdm = clkdm_lookup(autodep->clkdm.name);
148 if (!clkdm) {
150 autodep->clkdm.name);
151 clkdm = ERR_PTR(-ENOENT);
153 autodep->clkdm.ptr = clkdm;
158 * @clkdm: clockdomain that we are resolving dependencies for
165 static void _resolve_clkdm_deps(struct clockdomain *clkdm,
171 if (cd->clkdm)
173 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
175 WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",
176 clkdm->name, cd->clkdm_name);
447 for (a = autodeps; a->clkdm.ptr; a++)
479 struct clockdomain *clkdm;
485 list_for_each_entry(clkdm, &clkdm_list, node) {
486 clkdm_deny_idle(clkdm);
488 _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
489 clkdm_clear_all_wkdeps(clkdm);
491 _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
492 clkdm_clear_all_sleepdeps(clkdm);
495 /* Only AM43XX can lose clkdm context during rtc-ddr suspend */
513 struct clockdomain *clkdm, *temp_clkdm;
518 clkdm = NULL;
522 clkdm = temp_clkdm;
527 return clkdm;
544 int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
547 struct clockdomain *clkdm;
553 list_for_each_entry(clkdm, &clkdm_list, node) {
554 ret = (*fn)(clkdm, user);
564 * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in
565 * @clkdm: struct clockdomain *
568 * @clkdm exists in, or returns NULL if @clkdm is NULL.
570 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
572 if (!clkdm)
575 return clkdm->pwrdm.ptr;
605 pwrdm_lock(cd->clkdm->pwrdm.ptr);
607 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
634 pwrdm_lock(cd->clkdm->pwrdm.ptr);
636 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
681 * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm
682 * @clkdm: struct clockdomain * to remove all wakeup dependencies from
685 * @clkdm to wake. Intended to be used during boot to initialize the
687 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
690 int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
692 if (!clkdm)
698 return arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
725 pwrdm_lock(cd->clkdm->pwrdm.ptr);
727 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
756 pwrdm_lock(cd->clkdm->pwrdm.ptr);
758 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
805 * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm
806 * @clkdm: struct clockdomain * to remove all sleep dependencies from
809 * @clkdm from idling. Intended to be used during boot to initialize the
811 * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
814 int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
816 if (!clkdm)
822 return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
827 * @clkdm: struct clockdomain *
830 * clockdomain @clkdm. Only for use by the powerdomain code. Returns
831 * -EINVAL if @clkdm is NULL or if clockdomain does not support
834 static int clkdm_sleep_nolock(struct clockdomain *clkdm)
838 if (!clkdm)
841 if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
843 clkdm->name);
850 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
852 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
853 ret = arch_clkdm->clkdm_sleep(clkdm);
854 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
861 * @clkdm: struct clockdomain *
864 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if
868 int clkdm_sleep(struct clockdomain *clkdm)
872 pwrdm_lock(clkdm->pwrdm.ptr);
873 ret = clkdm_sleep_nolock(clkdm);
874 pwrdm_unlock(clkdm->pwrdm.ptr);
881 * @clkdm: struct clockdomain *
884 * clockdomain @clkdm. Only for use by the powerdomain code. Returns
885 * -EINVAL if @clkdm is NULL or if the clockdomain does not support
888 static int clkdm_wakeup_nolock(struct clockdomain *clkdm)
892 if (!clkdm)
895 if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
897 clkdm->name);
904 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
906 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
907 ret = arch_clkdm->clkdm_wakeup(clkdm);
908 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
915 * @clkdm: struct clockdomain *
918 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the
922 int clkdm_wakeup(struct clockdomain *clkdm)
926 pwrdm_lock(clkdm->pwrdm.ptr);
927 ret = clkdm_wakeup_nolock(clkdm);
928 pwrdm_unlock(clkdm->pwrdm.ptr);
934 * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm
935 * @clkdm: struct clockdomain *
937 * Allow the hardware to automatically switch the clockdomain @clkdm
944 void clkdm_allow_idle_nolock(struct clockdomain *clkdm)
946 if (!clkdm)
949 if (!WARN_ON(!clkdm->forcewake_count))
950 clkdm->forcewake_count--;
952 if (clkdm->forcewake_count)
955 if (!clkdm->usecount && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
956 clkdm_sleep_nolock(clkdm);
958 if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO))
961 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
968 clkdm->name);
970 clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;
971 arch_clkdm->clkdm_allow_idle(clkdm);
972 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
976 * clkdm_allow_idle - enable hwsup idle transitions for clkdm
977 * @clkdm: struct clockdomain *
979 * Allow the hardware to automatically switch the clockdomain @clkdm into
985 void clkdm_allow_idle(struct clockdomain *clkdm)
987 pwrdm_lock(clkdm->pwrdm.ptr);
988 clkdm_allow_idle_nolock(clkdm);
989 pwrdm_unlock(clkdm->pwrdm.ptr);
993 * clkdm_deny_idle_nolock - disable hwsup idle transitions for clkdm
994 * @clkdm: struct clockdomain *
997 * @clkdm into inactive or idle states. If the clockdomain has
1002 void clkdm_deny_idle_nolock(struct clockdomain *clkdm)
1004 if (!clkdm)
1007 if (clkdm->forcewake_count++)
1010 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
1011 clkdm_wakeup_nolock(clkdm);
1013 if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO))
1016 if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
1023 clkdm->name);
1025 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
1026 arch_clkdm->clkdm_deny_idle(clkdm);
1027 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
1031 * clkdm_deny_idle - disable hwsup idle transitions for clkdm
1032 * @clkdm: struct clockdomain *
1035 * @clkdm into inactive or idle states. If the clockdomain has
1039 void clkdm_deny_idle(struct clockdomain *clkdm)
1041 pwrdm_lock(clkdm->pwrdm.ptr);
1042 clkdm_deny_idle_nolock(clkdm);
1043 pwrdm_unlock(clkdm->pwrdm.ptr);
1049 * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
1050 * @clkdm: struct clockdomain *
1052 * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
1054 * when a clock inside clockdomain 'clkdm' is enabled. No return value.
1059 void clkdm_add_autodeps(struct clockdomain *clkdm)
1063 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
1066 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
1067 if (IS_ERR(autodep->clkdm.ptr))
1071 clkdm->name, autodep->clkdm.ptr->name);
1073 _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
1074 _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
1079 * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm
1080 * @clkdm: struct clockdomain *
1082 * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
1084 * when a clock inside clockdomain 'clkdm' is disabled. No return value.
1089 void clkdm_del_autodeps(struct clockdomain *clkdm)
1093 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
1096 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
1097 if (IS_ERR(autodep->clkdm.ptr))
1101 clkdm->name, autodep->clkdm.ptr->name);
1103 _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
1104 _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
1111 * clkdm_clk_enable - add an enabled downstream clock to this clkdm
1112 * @clkdm: struct clockdomain *
1115 * Increment the usecount of the clockdomain @clkdm and ensure that it
1119 * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
1124 int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *unused)
1126 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
1129 pwrdm_lock(clkdm->pwrdm.ptr);
1134 * enabled, so the clkdm can be force woken up.
1136 clkdm->usecount++;
1137 if (clkdm->usecount > 1 && autodeps) {
1138 pwrdm_unlock(clkdm->pwrdm.ptr);
1142 arch_clkdm->clkdm_clk_enable(clkdm);
1143 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
1144 pwrdm_unlock(clkdm->pwrdm.ptr);
1146 pr_debug("clockdomain: %s: enabled\n", clkdm->name);
1152 * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
1153 * @clkdm: struct clockdomain *
1156 * Decrement the usecount of this clockdomain @clkdm when @clk is
1159 * (software-supervised mode) or remove the clkdm autodependencies
1161 * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0
1164 int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
1166 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
1169 pwrdm_lock(clkdm->pwrdm.ptr);
1172 if (clk && (__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
1175 if (clkdm->usecount == 0) {
1176 pwrdm_unlock(clkdm->pwrdm.ptr);
1181 clkdm->usecount--;
1182 if (clkdm->usecount > 0) {
1183 pwrdm_unlock(clkdm->pwrdm.ptr);
1187 arch_clkdm->clkdm_clk_disable(clkdm);
1188 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
1190 pr_debug("clockdomain: %s: disabled\n", clkdm->name);
1193 pwrdm_unlock(clkdm->pwrdm.ptr);
1199 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
1200 * @clkdm: struct clockdomain *
1203 * Increment the usecount of the clockdomain @clkdm and ensure that it
1208 * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the
1213 int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
1215 /* The clkdm attribute does not exist yet prior OMAP4 */
1227 return clkdm_clk_enable(clkdm, NULL);
1231 * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm
1232 * @clkdm: struct clockdomain *
1235 * Decrement the usecount of this clockdomain @clkdm when @oh is
1238 * (software-supervised mode) or remove the clkdm autodependencies
1240 * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount
1244 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
1246 /* The clkdm attribute does not exist yet prior OMAP4 */
1253 return clkdm_clk_disable(clkdm, NULL);
1257 * _clkdm_save_context - save the context for the control of this clkdm
1260 * controlling this clkdm will be lost, save their context.
1262 static int _clkdm_save_context(struct clockdomain *clkdm, void *unused)
1267 return arch_clkdm->clkdm_save_context(clkdm);
1271 * _clkdm_restore_context - restore context for control of this clkdm
1275 static int _clkdm_restore_context(struct clockdomain *clkdm, void *unused)
1280 return arch_clkdm->clkdm_restore_context(clkdm);
1284 * clkdm_save_context - Saves the context for each registered clkdm
1294 * clkdm_restore_context - Restores the context for each registered clkdm