Lines Matching refs:clknode
62 typedef TAILQ_HEAD(clknode_list, clknode) clknode_list_t;
66 static int clknode_method_init(struct clknode *clk, device_t dev);
67 static int clknode_method_recalc_freq(struct clknode *clk, uint64_t *freq);
68 static int clknode_method_set_freq(struct clknode *clk, uint64_t fin,
70 static int clknode_method_set_gate(struct clknode *clk, bool enable);
71 static int clknode_method_set_mux(struct clknode *clk, int idx);
85 DEFINE_CLASS_0(clknode, clknode_class, clknode_methods, 0);
92 struct clknode { struct
97 TAILQ_ENTRY(clknode) clkdom_link; /* Domain list entry */ argument
98 TAILQ_ENTRY(clknode) clklist_link; /* Global list entry */
106 struct clknode **parents; /* Array of potential parents */ argument
107 struct clknode *parent; /* Current parent */ argument
111 TAILQ_ENTRY(clknode) sibling_link; /* Our entry in parent's list */
134 struct clknode *clknode; argument
181 static void clknode_adjust_parent(struct clknode *clknode, int idx);
196 clknode_method_init(struct clknode *clknode, device_t dev) in clknode_method_init() argument
203 clknode_method_recalc_freq(struct clknode *clknode, uint64_t *freq) in clknode_method_recalc_freq() argument
210 clknode_method_set_freq(struct clknode *clknode, uint64_t fin, uint64_t *fout, in clknode_method_set_freq() argument
219 clknode_method_set_gate(struct clknode *clk, bool enable) in clknode_method_set_gate()
226 clknode_method_set_mux(struct clknode *clk, int idx) in clknode_method_set_mux()
278 clknode_refresh_cache(struct clknode *clknode, uint64_t freq) in clknode_refresh_cache() argument
281 struct clknode *entry; in clknode_refresh_cache()
286 rv = CLKNODE_RECALC_FREQ(clknode, &freq); in clknode_refresh_cache()
293 clknode->name); in clknode_refresh_cache()
297 clknode->freq = freq; in clknode_refresh_cache()
300 TAILQ_FOREACH(entry, &(clknode->children), sibling_link) { in clknode_refresh_cache()
312 struct clknode *
315 struct clknode *entry; in clknode_find_by_name()
326 struct clknode *
329 struct clknode *entry; in clknode_find_by_id()
366 phandle_t *cells, struct clknode **clk) in clknode_default_ofw_map()
432 struct clknode *clknode; in clkdom_finit() local
454 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_finit()
455 TAILQ_INSERT_TAIL(&clknode_list, clknode, clklist_link); in clkdom_finit()
461 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_finit()
462 if (clknode->parent_cnt == 0) in clkdom_finit()
464 for (i = 0; i < clknode->parent_cnt; i++) { in clkdom_finit()
465 if (clknode->parents[i] != NULL) in clkdom_finit()
467 if (clknode->parent_names[i] == NULL) in clkdom_finit()
469 clknode->parents[i] = clknode_find_by_name( in clkdom_finit()
470 clknode->parent_names[i]); in clkdom_finit()
471 if (clknode->parents[i] == NULL) { in clkdom_finit()
474 clknode->name, clknode->parent_names[i]); in clkdom_finit()
480 if (clknode->parent_idx == CLKNODE_IDX_NONE) { in clkdom_finit()
483 clknode->name); in clkdom_finit()
487 if (clknode->parents[clknode->parent_idx] == NULL) { in clkdom_finit()
490 clknode->name, clknode->parent_idx, in clkdom_finit()
491 clknode->parent_names[clknode->parent_idx]); in clkdom_finit()
495 clknode_adjust_parent(clknode, clknode->parent_idx); in clkdom_finit()
505 struct clknode *clknode; in clkdom_dump() local
510 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_dump()
511 rv = clknode_get_freq(clknode, &freq); in clkdom_dump()
512 printf("Clock: %s, parent: %s(%d), freq: %ju\n", clknode->name, in clkdom_dump()
513 clknode->parent == NULL ? "(NULL)" : clknode->parent->name, in clkdom_dump()
514 clknode->parent_idx, in clkdom_dump()
523 struct clknode *
527 struct clknode *clknode; in clknode_create() local
540 clknode = malloc(sizeof(struct clknode), M_CLOCK, M_WAITOK | M_ZERO); in clknode_create()
541 kobj_init((kobj_t)clknode, (kobj_class_t)clknode_class); in clknode_create()
542 sx_init(&clknode->lock, "Clocknode lock"); in clknode_create()
546 clknode->softc = malloc(clknode_class->size, in clknode_create()
551 clknode->parents = malloc(sizeof(struct clknode *) * def->parent_cnt, in clknode_create()
556 clknode->name = def->name; in clknode_create()
557 clknode->parent_names = def->parent_names; in clknode_create()
559 clknode->name = strdup(def->name, M_CLOCK); in clknode_create()
560 clknode->parent_names = in clknode_create()
565 clknode->id = def->id; in clknode_create()
566 clknode->clkdom = clkdom; in clknode_create()
567 clknode->flags = def->flags; in clknode_create()
568 clknode->parent_cnt = def->parent_cnt; in clknode_create()
569 clknode->parent = NULL; in clknode_create()
570 clknode->parent_idx = CLKNODE_IDX_NONE; in clknode_create()
571 TAILQ_INIT(&clknode->children); in clknode_create()
573 sysctl_ctx_init(&clknode->sysctl_ctx); in clknode_create()
574 clknode_oid = SYSCTL_ADD_NODE(&clknode->sysctl_ctx, in clknode_create()
576 OID_AUTO, clknode->name, in clknode_create()
579 SYSCTL_ADD_U64(&clknode->sysctl_ctx, in clknode_create()
582 CTLFLAG_RD, &clknode->freq, 0, "The clock frequency"); in clknode_create()
583 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
587 clknode, CLKNODE_SYSCTL_PARENT, clknode_sysctl, in clknode_create()
590 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
594 clknode, CLKNODE_SYSCTL_PARENTS_LIST, clknode_sysctl, in clknode_create()
597 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
601 clknode, CLKNODE_SYSCTL_CHILDREN_LIST, clknode_sysctl, in clknode_create()
604 SYSCTL_ADD_INT(&clknode->sysctl_ctx, in clknode_create()
607 CTLFLAG_RD, &clknode->enable_cnt, 0, "The clock enable counter"); in clknode_create()
609 return (clknode); in clknode_create()
615 struct clknode *
616 clknode_register(struct clkdom * clkdom, struct clknode *clknode) in clknode_register() argument
620 rv = CLKNODE_INIT(clknode, clknode_get_device(clknode)); in clknode_register()
626 TAILQ_INSERT_TAIL(&clkdom->clknode_list, clknode, clkdom_link); in clknode_register()
628 return (clknode); in clknode_register()
639 clknode_adjust_parent(struct clknode *clknode, int idx) in clknode_adjust_parent() argument
644 if (clknode->parent_cnt == 0) in clknode_adjust_parent()
646 if ((idx == CLKNODE_IDX_NONE) || (idx >= clknode->parent_cnt)) in clknode_adjust_parent()
648 __func__, idx, clknode->name); in clknode_adjust_parent()
650 if (clknode->parents[idx] == NULL) in clknode_adjust_parent()
652 __func__, idx, clknode->name); in clknode_adjust_parent()
655 if (clknode->parent != NULL) { in clknode_adjust_parent()
656 TAILQ_REMOVE(&clknode->parent->children, clknode, sibling_link); in clknode_adjust_parent()
660 clknode->parent_idx = idx; in clknode_adjust_parent()
661 clknode->parent = clknode->parents[idx]; in clknode_adjust_parent()
662 TAILQ_INSERT_TAIL(&clknode->parent->children, clknode, sibling_link); in clknode_adjust_parent()
669 clknode_init_parent_idx(struct clknode *clknode, int idx) in clknode_init_parent_idx() argument
672 if (clknode->parent_cnt == 0) { in clknode_init_parent_idx()
673 clknode->parent_idx = CLKNODE_IDX_NONE; in clknode_init_parent_idx()
674 clknode->parent = NULL; in clknode_init_parent_idx()
678 (idx >= clknode->parent_cnt) || in clknode_init_parent_idx()
679 (clknode->parent_names[idx] == NULL)) in clknode_init_parent_idx()
681 __func__, idx, clknode->name); in clknode_init_parent_idx()
682 clknode->parent_idx = idx; in clknode_init_parent_idx()
686 clknode_set_parent_by_idx(struct clknode *clknode, int idx) in clknode_set_parent_by_idx() argument
695 if (clknode->parent_cnt == 0) in clknode_set_parent_by_idx()
698 if (clknode->parent_idx == idx) in clknode_set_parent_by_idx()
701 oldidx = clknode->parent_idx; in clknode_set_parent_by_idx()
702 clknode_adjust_parent(clknode, idx); in clknode_set_parent_by_idx()
703 rv = CLKNODE_SET_MUX(clknode, idx); in clknode_set_parent_by_idx()
705 clknode_adjust_parent(clknode, oldidx); in clknode_set_parent_by_idx()
708 rv = clknode_get_freq(clknode->parent, &freq); in clknode_set_parent_by_idx()
711 rv = clknode_refresh_cache(clknode, freq); in clknode_set_parent_by_idx()
716 clknode_set_parent_by_name(struct clknode *clknode, const char *name) in clknode_set_parent_by_name() argument
725 if (clknode->parent_cnt == 0) in clknode_set_parent_by_name()
734 if (clknode->parent_cnt == 1) { in clknode_set_parent_by_name()
735 rv = clknode_set_parent_by_name(clknode->parent, name); in clknode_set_parent_by_name()
739 for (idx = 0; idx < clknode->parent_cnt; idx++) { in clknode_set_parent_by_name()
740 if (clknode->parent_names[idx] == NULL) in clknode_set_parent_by_name()
742 if (strcmp(clknode->parent_names[idx], name) == 0) in clknode_set_parent_by_name()
745 if (idx >= clknode->parent_cnt) { in clknode_set_parent_by_name()
748 if (clknode->parent_idx == idx) in clknode_set_parent_by_name()
751 oldidx = clknode->parent_idx; in clknode_set_parent_by_name()
752 clknode_adjust_parent(clknode, idx); in clknode_set_parent_by_name()
753 rv = CLKNODE_SET_MUX(clknode, idx); in clknode_set_parent_by_name()
755 clknode_adjust_parent(clknode, oldidx); in clknode_set_parent_by_name()
756 CLKNODE_UNLOCK(clknode); in clknode_set_parent_by_name()
759 rv = clknode_get_freq(clknode->parent, &freq); in clknode_set_parent_by_name()
762 rv = clknode_refresh_cache(clknode, freq); in clknode_set_parent_by_name()
766 struct clknode *
767 clknode_get_parent(struct clknode *clknode) in clknode_get_parent() argument
770 return (clknode->parent); in clknode_get_parent()
774 clknode_get_name(struct clknode *clknode) in clknode_get_name() argument
777 return (clknode->name); in clknode_get_name()
781 clknode_get_parent_names(struct clknode *clknode) in clknode_get_parent_names() argument
784 return (clknode->parent_names); in clknode_get_parent_names()
788 clknode_get_parents_num(struct clknode *clknode) in clknode_get_parents_num() argument
791 return (clknode->parent_cnt); in clknode_get_parents_num()
795 clknode_get_parent_idx(struct clknode *clknode) in clknode_get_parent_idx() argument
798 return (clknode->parent_idx); in clknode_get_parent_idx()
802 clknode_get_flags(struct clknode *clknode) in clknode_get_flags() argument
805 return (clknode->flags); in clknode_get_flags()
810 clknode_get_softc(struct clknode *clknode) in clknode_get_softc() argument
813 return (clknode->softc); in clknode_get_softc()
817 clknode_get_device(struct clknode *clknode) in clknode_get_device() argument
820 return (clknode->clkdom->dev); in clknode_get_device()
836 clknode_get_freq(struct clknode *clknode, uint64_t *freq) in clknode_get_freq() argument
843 *freq = clknode->freq; in clknode_get_freq()
848 if (clknode->parent_cnt > 0) { in clknode_get_freq()
849 rv = clknode_get_freq(clknode->parent, freq); in clknode_get_freq()
856 CLKNODE_XLOCK(clknode); in clknode_get_freq()
857 rv = CLKNODE_RECALC_FREQ(clknode, freq); in clknode_get_freq()
859 CLKNODE_UNLOCK(clknode); in clknode_get_freq()
861 clknode->name, rv); in clknode_get_freq()
866 clknode->freq = *freq; in clknode_get_freq()
867 CLKNODE_UNLOCK(clknode); in clknode_get_freq()
872 clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, in clknode_set_freq() argument
882 if (clknode->freq == freq) in clknode_set_freq()
894 clknode->enable_cnt > 1 && in clknode_set_freq()
895 clknode->enable_cnt > enablecnt && in clknode_set_freq()
896 (clknode->flags & CLK_NODE_GLITCH_FREE) == 0) { in clknode_set_freq()
901 if (clknode->parent_cnt > 0) { in clknode_set_freq()
902 rv = clknode_get_freq(clknode->parent, &parent_freq); in clknode_set_freq()
909 rv = CLKNODE_SET_FREQ(clknode, parent_freq, &freq, flags, &done); in clknode_set_freq()
912 clknode->name, rv); in clknode_set_freq()
914 clknode_refresh_cache(clknode, parent_freq); in clknode_set_freq()
921 clknode->freq = freq; in clknode_set_freq()
923 if (clknode->parent_cnt > 0) { in clknode_set_freq()
924 rv = clknode_get_freq(clknode->parent, in clknode_set_freq()
930 clknode_refresh_cache(clknode, parent_freq); in clknode_set_freq()
932 } else if (clknode->parent != NULL) { in clknode_set_freq()
934 rv = clknode_set_freq(clknode->parent, freq, flags, enablecnt); in clknode_set_freq()
938 clknode->name); in clknode_set_freq()
946 clknode_enable(struct clknode *clknode) in clknode_enable() argument
953 if (clknode->parent_cnt > 0) { in clknode_enable()
954 rv = clknode_enable(clknode->parent); in clknode_enable()
961 CLKNODE_XLOCK(clknode); in clknode_enable()
962 if (clknode->enable_cnt == 0) { in clknode_enable()
963 rv = CLKNODE_SET_GATE(clknode, 1); in clknode_enable()
965 CLKNODE_UNLOCK(clknode); in clknode_enable()
969 clknode->enable_cnt++; in clknode_enable()
970 CLKNODE_UNLOCK(clknode); in clknode_enable()
975 clknode_disable(struct clknode *clknode) in clknode_disable() argument
982 CLKNODE_XLOCK(clknode); in clknode_disable()
984 if ((clknode->enable_cnt == 1) && in clknode_disable()
985 ((clknode->flags & CLK_NODE_CANNOT_STOP) == 0)) { in clknode_disable()
986 rv = CLKNODE_SET_GATE(clknode, 0); in clknode_disable()
988 CLKNODE_UNLOCK(clknode); in clknode_disable()
992 clknode->enable_cnt--; in clknode_disable()
993 CLKNODE_UNLOCK(clknode); in clknode_disable()
995 if (clknode->parent_cnt > 0) { in clknode_disable()
996 rv = clknode_disable(clknode->parent); in clknode_disable()
1002 clknode_stop(struct clknode *clknode, int depth) in clknode_stop() argument
1009 CLKNODE_XLOCK(clknode); in clknode_stop()
1011 if ((clknode->enable_cnt != 0) && (depth == 0)) { in clknode_stop()
1012 CLKNODE_UNLOCK(clknode); in clknode_stop()
1016 if ((clknode->enable_cnt == 0) && in clknode_stop()
1017 ((clknode->flags & CLK_NODE_CANNOT_STOP) == 0)) { in clknode_stop()
1018 rv = CLKNODE_SET_GATE(clknode, 0); in clknode_stop()
1020 CLKNODE_UNLOCK(clknode); in clknode_stop()
1024 CLKNODE_UNLOCK(clknode); in clknode_stop()
1026 if (clknode->parent_cnt > 0) in clknode_stop()
1027 rv = clknode_stop(clknode->parent, depth + 1); in clknode_stop()
1038 clk_create(struct clknode *clknode, device_t dev) in clk_create() argument
1046 clk->clknode = clknode; in clk_create()
1048 clknode->ref_cnt++; in clk_create()
1057 struct clknode *clknode; in clk_get_freq() local
1059 clknode = clk->clknode; in clk_get_freq()
1060 KASSERT(clknode->ref_cnt > 0, in clk_get_freq()
1061 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_freq()
1064 rv = clknode_get_freq(clknode, freq); in clk_get_freq()
1073 struct clknode *clknode; in clk_set_freq() local
1076 clknode = clk->clknode; in clk_set_freq()
1077 KASSERT(clknode->ref_cnt > 0, in clk_set_freq()
1078 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_freq()
1081 rv = clknode_set_freq(clknode, freq, flags, clk->enable_cnt); in clk_set_freq()
1090 struct clknode *clknode; in clk_test_freq() local
1093 clknode = clk->clknode; in clk_test_freq()
1094 KASSERT(clknode->ref_cnt > 0, in clk_test_freq()
1095 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_test_freq()
1098 rv = clknode_set_freq(clknode, freq, flags | CLK_SET_DRYRUN, 0); in clk_test_freq()
1106 struct clknode *clknode; in clk_get_parent() local
1107 struct clknode *parentnode; in clk_get_parent()
1109 clknode = clk->clknode; in clk_get_parent()
1110 KASSERT(clknode->ref_cnt > 0, in clk_get_parent()
1111 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_parent()
1114 parentnode = clknode_get_parent(clknode); in clk_get_parent()
1128 struct clknode *clknode; in clk_set_parent_by_clk() local
1129 struct clknode *parentnode; in clk_set_parent_by_clk()
1131 clknode = clk->clknode; in clk_set_parent_by_clk()
1132 parentnode = parent->clknode; in clk_set_parent_by_clk()
1133 KASSERT(clknode->ref_cnt > 0, in clk_set_parent_by_clk()
1134 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_parent_by_clk()
1136 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_parent_by_clk()
1138 rv = clknode_set_parent_by_name(clknode, parentnode->name); in clk_set_parent_by_clk()
1147 struct clknode *clknode; in clk_enable() local
1149 clknode = clk->clknode; in clk_enable()
1150 KASSERT(clknode->ref_cnt > 0, in clk_enable()
1151 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_enable()
1153 rv = clknode_enable(clknode); in clk_enable()
1164 struct clknode *clknode; in clk_disable() local
1166 clknode = clk->clknode; in clk_disable()
1167 KASSERT(clknode->ref_cnt > 0, in clk_disable()
1168 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_disable()
1170 ("Attempt to disable already disabled clock: %s\n", clknode->name)); in clk_disable()
1172 rv = clknode_disable(clknode); in clk_disable()
1183 struct clknode *clknode; in clk_stop() local
1185 clknode = clk->clknode; in clk_stop()
1186 KASSERT(clknode->ref_cnt > 0, in clk_stop()
1187 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_stop()
1189 ("Attempt to stop already enabled clock: %s\n", clknode->name)); in clk_stop()
1192 rv = clknode_stop(clknode, 0); in clk_stop()
1200 struct clknode *clknode; in clk_release() local
1202 clknode = clk->clknode; in clk_release()
1203 KASSERT(clknode->ref_cnt > 0, in clk_release()
1204 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_release()
1207 clknode_disable(clknode); in clk_release()
1210 CLKNODE_XLOCK(clknode); in clk_release()
1211 clknode->ref_cnt--; in clk_release()
1212 CLKNODE_UNLOCK(clknode); in clk_release()
1223 struct clknode *clknode; in clk_get_name() local
1225 clknode = clk->clknode; in clk_get_name()
1226 KASSERT(clknode->ref_cnt > 0, in clk_get_name()
1227 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_name()
1228 name = clknode_get_name(clknode); in clk_get_name()
1235 struct clknode *clknode; in clk_get_by_name() local
1238 clknode = clknode_find_by_name(name); in clk_get_by_name()
1239 if (clknode == NULL) { in clk_get_by_name()
1243 *clk = clk_create(clknode, dev); in clk_get_by_name()
1251 struct clknode *clknode; in clk_get_by_id() local
1255 clknode = clknode_find_by_id(clkdom, id); in clk_get_by_id()
1256 if (clknode == NULL) { in clk_get_by_id()
1260 *clk = clk_create(clknode, dev); in clk_get_by_id()
1369 struct clknode *clknode; in clk_get_by_ofw_index_prop() local
1401 rv = clkdom->ofw_mapper(clkdom, ncells, cells, &clknode); in clk_get_by_ofw_index_prop()
1403 *clk = clk_create(clknode, dev); in clk_get_by_ofw_index_prop()
1513 struct clknode *clknode; in clkdom_sysctl() local
1522 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_sysctl()
1523 sbuf_printf(sb, "%s ", clknode->name); in clkdom_sysctl()
1535 struct clknode *clknode, *children; in clknode_sysctl() local
1541 clknode = arg1; in clknode_sysctl()
1549 if (clknode->parent) in clknode_sysctl()
1550 sbuf_printf(sb, "%s", clknode->parent->name); in clknode_sysctl()
1553 parent_names = clknode_get_parent_names(clknode); in clknode_sysctl()
1554 for (i = 0; i < clknode->parent_cnt; i++) in clknode_sysctl()
1558 TAILQ_FOREACH(children, &(clknode->children), sibling_link) { in clknode_sysctl()