Lines Matching refs:clknode

63 typedef TAILQ_HEAD(clknode_list, clknode) clknode_list_t;
67 static int clknode_method_init(struct clknode *clk, device_t dev);
68 static int clknode_method_recalc_freq(struct clknode *clk, uint64_t *freq);
69 static int clknode_method_set_freq(struct clknode *clk, uint64_t fin,
71 static int clknode_method_set_gate(struct clknode *clk, bool enable);
72 static int clknode_method_set_mux(struct clknode *clk, int idx);
86 DEFINE_CLASS_0(clknode, clknode_class, clknode_methods, 0);
93 struct clknode { struct
98 TAILQ_ENTRY(clknode) clkdom_link; /* Domain list entry */ argument
99 TAILQ_ENTRY(clknode) clklist_link; /* Global list entry */
107 struct clknode **parents; /* Array of potential parents */ argument
108 struct clknode *parent; /* Current parent */ argument
112 TAILQ_ENTRY(clknode) sibling_link; /* Our entry in parent's list */
135 struct clknode *clknode; argument
182 static void clknode_adjust_parent(struct clknode *clknode, int idx);
202 clknode_method_init(struct clknode *clknode, device_t dev) in clknode_method_init() argument
209 clknode_method_recalc_freq(struct clknode *clknode, uint64_t *freq) in clknode_method_recalc_freq() argument
216 clknode_method_set_freq(struct clknode *clknode, uint64_t fin, uint64_t *fout, in clknode_method_set_freq() argument
225 clknode_method_set_gate(struct clknode *clk, bool enable) in clknode_method_set_gate()
232 clknode_method_set_mux(struct clknode *clk, int idx) in clknode_method_set_mux()
284 clknode_refresh_cache(struct clknode *clknode, uint64_t freq) in clknode_refresh_cache() argument
287 struct clknode *entry; in clknode_refresh_cache()
292 rv = CLKNODE_RECALC_FREQ(clknode, &freq); in clknode_refresh_cache()
299 clknode->name); in clknode_refresh_cache()
303 clknode->freq = freq; in clknode_refresh_cache()
306 TAILQ_FOREACH(entry, &(clknode->children), sibling_link) { in clknode_refresh_cache()
318 struct clknode *
321 struct clknode *entry; in clknode_find_by_name()
332 struct clknode *
335 struct clknode *entry; in clknode_find_by_id()
372 phandle_t *cells, struct clknode **clk) in clknode_default_ofw_map()
437 struct clknode *clknode; in clkdom_finit() local
459 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_finit()
460 TAILQ_INSERT_TAIL(&clknode_list, clknode, clklist_link); in clkdom_finit()
466 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_finit()
467 if (clknode->parent_cnt == 0) in clkdom_finit()
469 for (i = 0; i < clknode->parent_cnt; i++) { in clkdom_finit()
470 if (clknode->parents[i] != NULL) in clkdom_finit()
472 if (clknode->parent_names[i] == NULL) in clkdom_finit()
474 clknode->parents[i] = clknode_find_by_name( in clkdom_finit()
475 clknode->parent_names[i]); in clkdom_finit()
476 if (clknode->parents[i] == NULL) { in clkdom_finit()
479 clknode->name, clknode->parent_names[i]); in clkdom_finit()
485 if (clknode->parent_idx == CLKNODE_IDX_NONE) { in clkdom_finit()
488 clknode->name); in clkdom_finit()
492 if (clknode->parents[clknode->parent_idx] == NULL) { in clkdom_finit()
495 clknode->name, clknode->parent_idx, in clkdom_finit()
496 clknode->parent_names[clknode->parent_idx]); in clkdom_finit()
500 clknode_adjust_parent(clknode, clknode->parent_idx); in clkdom_finit()
510 struct clknode *clknode; in clkdom_dump() local
515 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_dump()
516 rv = clknode_get_freq(clknode, &freq); in clkdom_dump()
517 printf("Clock: %s, parent: %s(%d), freq: %ju\n", clknode->name, in clkdom_dump()
518 clknode->parent == NULL ? "(NULL)" : clknode->parent->name, in clkdom_dump()
519 clknode->parent_idx, in clkdom_dump()
528 struct clknode *
532 struct clknode *clknode; in clknode_create() local
549 clknode = clknode_find_by_name(def->name); in clknode_create()
551 if (clknode != NULL) { in clknode_create()
552 if (!(clknode->flags & CLK_NODE_LINKED) && in clknode_create()
559 return (clknode); in clknode_create()
560 } else if (clknode->flags & CLK_NODE_LINKED && in clknode_create()
573 KASSERT(clkdom != clknode->clkdom, in clknode_create()
576 TAILQ_REMOVE(&clkdom->clknode_list, clknode, in clknode_create()
578 TAILQ_REMOVE(&clknode_list, clknode, clklist_link); in clknode_create()
580 } else if (clknode->flags & CLK_NODE_LINKED && in clknode_create()
586 return (clknode); in clknode_create()
593 clknode = malloc(sizeof(struct clknode), M_CLOCK, in clknode_create()
595 sx_init(&clknode->lock, "Clocknode lock"); in clknode_create()
596 TAILQ_INIT(&clknode->children); in clknode_create()
600 kobj_init((kobj_t)clknode, (kobj_class_t)clknode_class); in clknode_create()
604 clknode->softc = malloc(clknode_class->size, in clknode_create()
609 clknode->parents = malloc(sizeof(struct clknode *) * def->parent_cnt, in clknode_create()
614 clknode->name = def->name; in clknode_create()
615 clknode->parent_names = def->parent_names; in clknode_create()
617 clknode->name = strdup(def->name, M_CLOCK); in clknode_create()
618 clknode->parent_names = in clknode_create()
623 clknode->id = def->id; in clknode_create()
624 clknode->clkdom = clkdom; in clknode_create()
625 clknode->flags = def->flags; in clknode_create()
626 clknode->parent_cnt = def->parent_cnt; in clknode_create()
627 clknode->parent = NULL; in clknode_create()
628 clknode->parent_idx = CLKNODE_IDX_NONE; in clknode_create()
631 return (clknode); in clknode_create()
633 sysctl_ctx_init(&clknode->sysctl_ctx); in clknode_create()
634 clknode_oid = SYSCTL_ADD_NODE(&clknode->sysctl_ctx, in clknode_create()
636 OID_AUTO, clknode->name, in clknode_create()
639 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
643 clknode, CLKNODE_SYSCTL_FREQUENCY, clknode_sysctl, in clknode_create()
649 kobj_method = kobj_lookup_method(((kobj_t)clknode)->ops->cls, NULL, in clknode_create()
653 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
657 clknode, CLKNODE_SYSCTL_GATE, clknode_sysctl, in clknode_create()
662 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
666 clknode, CLKNODE_SYSCTL_PARENT, clknode_sysctl, in clknode_create()
669 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
673 clknode, CLKNODE_SYSCTL_PARENTS_LIST, clknode_sysctl, in clknode_create()
676 SYSCTL_ADD_PROC(&clknode->sysctl_ctx, in clknode_create()
680 clknode, CLKNODE_SYSCTL_CHILDREN_LIST, clknode_sysctl, in clknode_create()
683 SYSCTL_ADD_INT(&clknode->sysctl_ctx, in clknode_create()
686 CTLFLAG_RD, &clknode->enable_cnt, 0, "The clock enable counter"); in clknode_create()
688 return (clknode); in clknode_create()
694 struct clknode *
695 clknode_register(struct clkdom * clkdom, struct clknode *clknode) in clknode_register() argument
700 if (clknode->flags & CLK_NODE_REGISTERED) in clknode_register()
701 return(clknode); in clknode_register()
703 rv = CLKNODE_INIT(clknode, clknode_get_device(clknode)); in clknode_register()
709 TAILQ_INSERT_TAIL(&clkdom->clknode_list, clknode, clkdom_link); in clknode_register()
710 clknode->flags |= CLK_NODE_REGISTERED; in clknode_register()
711 return (clknode); in clknode_register()
718 struct clknode *clknode; in clknode_finish() local
721 TAILQ_FOREACH(clknode, &clknode_list, clklist_link) { in clknode_finish()
722 if (clknode->flags & CLK_NODE_LINKED) in clknode_finish()
724 clknode->name); in clknode_finish()
736 clknode_adjust_parent(struct clknode *clknode, int idx) in clknode_adjust_parent() argument
741 if (clknode->parent_cnt == 0) in clknode_adjust_parent()
743 if ((idx == CLKNODE_IDX_NONE) || (idx >= clknode->parent_cnt)) in clknode_adjust_parent()
745 __func__, idx, clknode->name); in clknode_adjust_parent()
747 if (clknode->parents[idx] == NULL) in clknode_adjust_parent()
749 __func__, idx, clknode->name); in clknode_adjust_parent()
752 if (clknode->parent != NULL) { in clknode_adjust_parent()
753 TAILQ_REMOVE(&clknode->parent->children, clknode, sibling_link); in clknode_adjust_parent()
757 clknode->parent_idx = idx; in clknode_adjust_parent()
758 clknode->parent = clknode->parents[idx]; in clknode_adjust_parent()
759 TAILQ_INSERT_TAIL(&clknode->parent->children, clknode, sibling_link); in clknode_adjust_parent()
766 clknode_init_parent_idx(struct clknode *clknode, int idx) in clknode_init_parent_idx() argument
769 if (clknode->parent_cnt == 0) { in clknode_init_parent_idx()
770 clknode->parent_idx = CLKNODE_IDX_NONE; in clknode_init_parent_idx()
771 clknode->parent = NULL; in clknode_init_parent_idx()
775 (idx >= clknode->parent_cnt) || in clknode_init_parent_idx()
776 (clknode->parent_names[idx] == NULL)) in clknode_init_parent_idx()
778 __func__, idx, clknode->name); in clknode_init_parent_idx()
779 clknode->parent_idx = idx; in clknode_init_parent_idx()
783 clknode_set_parent_by_idx(struct clknode *clknode, int idx) in clknode_set_parent_by_idx() argument
792 if (clknode->parent_cnt == 0) in clknode_set_parent_by_idx()
795 if (clknode->parent_idx == idx) in clknode_set_parent_by_idx()
798 oldidx = clknode->parent_idx; in clknode_set_parent_by_idx()
799 clknode_adjust_parent(clknode, idx); in clknode_set_parent_by_idx()
800 rv = CLKNODE_SET_MUX(clknode, idx); in clknode_set_parent_by_idx()
802 clknode_adjust_parent(clknode, oldidx); in clknode_set_parent_by_idx()
805 rv = clknode_get_freq(clknode->parent, &freq); in clknode_set_parent_by_idx()
808 rv = clknode_refresh_cache(clknode, freq); in clknode_set_parent_by_idx()
813 clknode_set_parent_by_name(struct clknode *clknode, const char *name) in clknode_set_parent_by_name() argument
822 if (clknode->parent_cnt == 0) in clknode_set_parent_by_name()
831 if (clknode->parent_cnt == 1) { in clknode_set_parent_by_name()
832 rv = clknode_set_parent_by_name(clknode->parent, name); in clknode_set_parent_by_name()
836 for (idx = 0; idx < clknode->parent_cnt; idx++) { in clknode_set_parent_by_name()
837 if (clknode->parent_names[idx] == NULL) in clknode_set_parent_by_name()
839 if (strcmp(clknode->parent_names[idx], name) == 0) in clknode_set_parent_by_name()
842 if (idx >= clknode->parent_cnt) { in clknode_set_parent_by_name()
845 if (clknode->parent_idx == idx) in clknode_set_parent_by_name()
848 oldidx = clknode->parent_idx; in clknode_set_parent_by_name()
849 clknode_adjust_parent(clknode, idx); in clknode_set_parent_by_name()
850 rv = CLKNODE_SET_MUX(clknode, idx); in clknode_set_parent_by_name()
852 clknode_adjust_parent(clknode, oldidx); in clknode_set_parent_by_name()
853 CLKNODE_UNLOCK(clknode); in clknode_set_parent_by_name()
856 rv = clknode_get_freq(clknode->parent, &freq); in clknode_set_parent_by_name()
859 rv = clknode_refresh_cache(clknode, freq); in clknode_set_parent_by_name()
863 struct clknode *
864 clknode_get_parent(struct clknode *clknode) in clknode_get_parent() argument
867 return (clknode->parent); in clknode_get_parent()
871 clknode_get_name(struct clknode *clknode) in clknode_get_name() argument
874 return (clknode->name); in clknode_get_name()
878 clknode_get_parent_names(struct clknode *clknode) in clknode_get_parent_names() argument
881 return (clknode->parent_names); in clknode_get_parent_names()
885 clknode_get_parents_num(struct clknode *clknode) in clknode_get_parents_num() argument
888 return (clknode->parent_cnt); in clknode_get_parents_num()
892 clknode_get_parent_idx(struct clknode *clknode) in clknode_get_parent_idx() argument
895 return (clknode->parent_idx); in clknode_get_parent_idx()
899 clknode_get_flags(struct clknode *clknode) in clknode_get_flags() argument
902 return (clknode->flags); in clknode_get_flags()
907 clknode_get_softc(struct clknode *clknode) in clknode_get_softc() argument
910 return (clknode->softc); in clknode_get_softc()
914 clknode_get_device(struct clknode *clknode) in clknode_get_device() argument
917 return (clknode->clkdom->dev); in clknode_get_device()
933 clknode_get_freq(struct clknode *clknode, uint64_t *freq) in clknode_get_freq() argument
940 *freq = clknode->freq; in clknode_get_freq()
945 if (clknode->parent_cnt > 0) { in clknode_get_freq()
946 rv = clknode_get_freq(clknode->parent, freq); in clknode_get_freq()
953 CLKNODE_XLOCK(clknode); in clknode_get_freq()
954 rv = CLKNODE_RECALC_FREQ(clknode, freq); in clknode_get_freq()
956 CLKNODE_UNLOCK(clknode); in clknode_get_freq()
958 clknode->name, rv); in clknode_get_freq()
963 clknode->freq = *freq; in clknode_get_freq()
964 CLKNODE_UNLOCK(clknode); in clknode_get_freq()
969 clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, in clknode_set_freq() argument
979 if (clknode->freq == freq) in clknode_set_freq()
991 clknode->enable_cnt > 1 && in clknode_set_freq()
992 clknode->enable_cnt > enablecnt && in clknode_set_freq()
993 (clknode->flags & CLK_NODE_GLITCH_FREE) == 0) { in clknode_set_freq()
998 if (clknode->parent_cnt > 0) { in clknode_set_freq()
999 rv = clknode_get_freq(clknode->parent, &parent_freq); in clknode_set_freq()
1006 rv = CLKNODE_SET_FREQ(clknode, parent_freq, &freq, flags, &done); in clknode_set_freq()
1009 clknode->name, rv); in clknode_set_freq()
1011 clknode_refresh_cache(clknode, parent_freq); in clknode_set_freq()
1018 clknode->freq = freq; in clknode_set_freq()
1020 if (clknode->parent_cnt > 0) { in clknode_set_freq()
1021 rv = clknode_get_freq(clknode->parent, in clknode_set_freq()
1027 clknode_refresh_cache(clknode, parent_freq); in clknode_set_freq()
1029 } else if (clknode->parent != NULL) { in clknode_set_freq()
1031 rv = clknode_set_freq(clknode->parent, freq, flags, enablecnt); in clknode_set_freq()
1035 clknode->name); in clknode_set_freq()
1043 clknode_enable(struct clknode *clknode) in clknode_enable() argument
1050 if (clknode->parent_cnt > 0) { in clknode_enable()
1051 rv = clknode_enable(clknode->parent); in clknode_enable()
1058 CLKNODE_XLOCK(clknode); in clknode_enable()
1059 if (clknode->enable_cnt == 0) { in clknode_enable()
1060 rv = CLKNODE_SET_GATE(clknode, 1); in clknode_enable()
1062 CLKNODE_UNLOCK(clknode); in clknode_enable()
1066 clknode->enable_cnt++; in clknode_enable()
1067 CLKNODE_UNLOCK(clknode); in clknode_enable()
1072 clknode_disable(struct clknode *clknode) in clknode_disable() argument
1079 CLKNODE_XLOCK(clknode); in clknode_disable()
1081 if ((clknode->enable_cnt == 1) && in clknode_disable()
1082 ((clknode->flags & CLK_NODE_CANNOT_STOP) == 0)) { in clknode_disable()
1083 rv = CLKNODE_SET_GATE(clknode, 0); in clknode_disable()
1085 CLKNODE_UNLOCK(clknode); in clknode_disable()
1089 clknode->enable_cnt--; in clknode_disable()
1090 CLKNODE_UNLOCK(clknode); in clknode_disable()
1092 if (clknode->parent_cnt > 0) { in clknode_disable()
1093 rv = clknode_disable(clknode->parent); in clknode_disable()
1099 clknode_stop(struct clknode *clknode, int depth) in clknode_stop() argument
1106 CLKNODE_XLOCK(clknode); in clknode_stop()
1108 if ((clknode->enable_cnt != 0) && (depth == 0)) { in clknode_stop()
1109 CLKNODE_UNLOCK(clknode); in clknode_stop()
1113 if ((clknode->enable_cnt == 0) && in clknode_stop()
1114 ((clknode->flags & CLK_NODE_CANNOT_STOP) == 0)) { in clknode_stop()
1115 rv = CLKNODE_SET_GATE(clknode, 0); in clknode_stop()
1117 CLKNODE_UNLOCK(clknode); in clknode_stop()
1121 CLKNODE_UNLOCK(clknode); in clknode_stop()
1123 if (clknode->parent_cnt > 0) in clknode_stop()
1124 rv = clknode_stop(clknode->parent, depth + 1); in clknode_stop()
1135 clk_create(struct clknode *clknode, device_t dev) in clk_create() argument
1143 clk->clknode = clknode; in clk_create()
1145 clknode->ref_cnt++; in clk_create()
1154 struct clknode *clknode; in clk_get_freq() local
1156 clknode = clk->clknode; in clk_get_freq()
1157 KASSERT(clknode->ref_cnt > 0, in clk_get_freq()
1158 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_freq()
1161 rv = clknode_get_freq(clknode, freq); in clk_get_freq()
1170 struct clknode *clknode; in clk_set_freq() local
1173 clknode = clk->clknode; in clk_set_freq()
1174 KASSERT(clknode->ref_cnt > 0, in clk_set_freq()
1175 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_freq()
1178 rv = clknode_set_freq(clknode, freq, flags, clk->enable_cnt); in clk_set_freq()
1187 struct clknode *clknode; in clk_test_freq() local
1190 clknode = clk->clknode; in clk_test_freq()
1191 KASSERT(clknode->ref_cnt > 0, in clk_test_freq()
1192 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_test_freq()
1195 rv = clknode_set_freq(clknode, freq, flags | CLK_SET_DRYRUN, 0); in clk_test_freq()
1203 struct clknode *clknode; in clk_get_parent() local
1204 struct clknode *parentnode; in clk_get_parent()
1206 clknode = clk->clknode; in clk_get_parent()
1207 KASSERT(clknode->ref_cnt > 0, in clk_get_parent()
1208 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_parent()
1211 parentnode = clknode_get_parent(clknode); in clk_get_parent()
1225 struct clknode *clknode; in clk_set_parent_by_clk() local
1226 struct clknode *parentnode; in clk_set_parent_by_clk()
1228 clknode = clk->clknode; in clk_set_parent_by_clk()
1229 parentnode = parent->clknode; in clk_set_parent_by_clk()
1230 KASSERT(clknode->ref_cnt > 0, in clk_set_parent_by_clk()
1231 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_parent_by_clk()
1233 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_set_parent_by_clk()
1235 rv = clknode_set_parent_by_name(clknode, parentnode->name); in clk_set_parent_by_clk()
1244 struct clknode *clknode; in clk_enable() local
1246 clknode = clk->clknode; in clk_enable()
1247 KASSERT(clknode->ref_cnt > 0, in clk_enable()
1248 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_enable()
1250 rv = clknode_enable(clknode); in clk_enable()
1261 struct clknode *clknode; in clk_disable() local
1263 clknode = clk->clknode; in clk_disable()
1264 KASSERT(clknode->ref_cnt > 0, in clk_disable()
1265 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_disable()
1267 ("Attempt to disable already disabled clock: %s\n", clknode->name)); in clk_disable()
1269 rv = clknode_disable(clknode); in clk_disable()
1280 struct clknode *clknode; in clk_stop() local
1282 clknode = clk->clknode; in clk_stop()
1283 KASSERT(clknode->ref_cnt > 0, in clk_stop()
1284 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_stop()
1286 ("Attempt to stop already enabled clock: %s\n", clknode->name)); in clk_stop()
1289 rv = clknode_stop(clknode, 0); in clk_stop()
1297 struct clknode *clknode; in clk_release() local
1299 clknode = clk->clknode; in clk_release()
1300 KASSERT(clknode->ref_cnt > 0, in clk_release()
1301 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_release()
1304 clknode_disable(clknode); in clk_release()
1307 CLKNODE_XLOCK(clknode); in clk_release()
1308 clknode->ref_cnt--; in clk_release()
1309 CLKNODE_UNLOCK(clknode); in clk_release()
1320 struct clknode *clknode; in clk_get_name() local
1322 clknode = clk->clknode; in clk_get_name()
1323 KASSERT(clknode->ref_cnt > 0, in clk_get_name()
1324 ("Attempt to access unreferenced clock: %s\n", clknode->name)); in clk_get_name()
1325 name = clknode_get_name(clknode); in clk_get_name()
1332 struct clknode *clknode; in clk_get_by_name() local
1335 clknode = clknode_find_by_name(name); in clk_get_by_name()
1336 if (clknode == NULL) { in clk_get_by_name()
1340 *clk = clk_create(clknode, dev); in clk_get_by_name()
1348 struct clknode *clknode; in clk_get_by_id() local
1352 clknode = clknode_find_by_id(clkdom, id); in clk_get_by_id()
1353 if (clknode == NULL) { in clk_get_by_id()
1357 *clk = clk_create(clknode, dev); in clk_get_by_id()
1468 struct clknode *clknode; in clk_get_by_ofw_index_prop() local
1500 rv = clkdom->ofw_mapper(clkdom, ncells, cells, &clknode); in clk_get_by_ofw_index_prop()
1502 *clk = clk_create(clknode, dev); in clk_get_by_ofw_index_prop()
1612 struct clknode *clknode; in clkdom_sysctl() local
1621 TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { in clkdom_sysctl()
1622 sbuf_printf(sb, "%s ", clknode->name); in clkdom_sysctl()
1634 struct clknode *clknode, *children; in clknode_sysctl() local
1642 clknode = arg1; in clknode_sysctl()
1650 if (clknode->parent) in clknode_sysctl()
1651 sbuf_printf(sb, "%s", clknode->parent->name); in clknode_sysctl()
1654 parent_names = clknode_get_parent_names(clknode); in clknode_sysctl()
1655 for (i = 0; i < clknode->parent_cnt; i++) in clknode_sysctl()
1659 TAILQ_FOREACH(children, &(clknode->children), sibling_link) { in clknode_sysctl()
1664 ret = clknode_get_freq(clknode, &freq); in clknode_sysctl()
1671 ret = CLKNODE_GET_GATE(clknode, &enable); in clknode_sysctl()