Date: Sun, 5 Mar 2017 07:13:29 +0000 (UTC) From: Emmanuel Vadot <manu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r314699 - in head/sys: dev/extres/clk kern sys Message-ID: <201703050713.v257DT3s028601@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: manu Date: Sun Mar 5 07:13:29 2017 New Revision: 314699 URL: https://svnweb.freebsd.org/changeset/base/314699 Log: Export a sysctl dev.<clkdom>.<unit>.clocks for each clock domain containing all the clocks that they provide. Each clocks are exported under the node 'clock.<clkname>' and have the following children nodes : - frequency - parent (The selected parent, if any) - parents (The list of parents, if any) - childrens (The list of childrens, if any) - enable_cnt (The enabled counter) This give us the possibility to examine clocks at runtime and make graph of the clock flow. Reviewed by: mmel MFC after: 2 month Differential Revision: https://reviews.freebsd.org/D9833 Modified: head/sys/dev/extres/clk/clk.c head/sys/kern/kern_mib.c head/sys/sys/sysctl.h Modified: head/sys/dev/extres/clk/clk.c ============================================================================== --- head/sys/dev/extres/clk/clk.c Sun Mar 5 05:17:36 2017 (r314698) +++ head/sys/dev/extres/clk/clk.c Sun Mar 5 07:13:29 2017 (r314699) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <sys/limits.h> #include <sys/lock.h> +#include <sys/sbuf.h> #include <sys/sysctl.h> #include <sys/systm.h> #include <sys/sx.h> @@ -118,6 +119,8 @@ struct clknode { /* Cached values. */ uint64_t freq; /* Actual frequency */ + + struct sysctl_ctx_list sysctl_ctx; }; /* @@ -175,6 +178,15 @@ SX_SYSINIT(clock_topology, &clk_topo_loc static void clknode_adjust_parent(struct clknode *clknode, int idx); +enum clknode_sysctl_type { + CLKNODE_SYSCTL_PARENT, + CLKNODE_SYSCTL_PARENTS_LIST, + CLKNODE_SYSCTL_CHILDREN_LIST, +}; + +static int clknode_sysctl(SYSCTL_HANDLER_ARGS); +static int clkdom_sysctl(SYSCTL_HANDLER_ARGS); + /* * Default clock methods for base class. */ @@ -382,6 +394,14 @@ clkdom_create(device_t dev) clkdom->ofw_mapper = clknode_default_ofw_map; #endif + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "clocks", + CTLTYPE_STRING | CTLFLAG_RD, + clkdom, 0, clkdom_sysctl, + "A", + "Clock list for the domain"); + return (clkdom); } @@ -503,6 +523,7 @@ clknode_create(struct clkdom * clkdom, c const struct clknode_init_def *def) { struct clknode *clknode; + struct sysctl_oid *clknode_oid; KASSERT(def->name != NULL, ("clock name is NULL")); KASSERT(def->name[0] != '\0', ("clock name is empty")); @@ -547,6 +568,42 @@ clknode_create(struct clkdom * clkdom, c clknode->parent_idx = CLKNODE_IDX_NONE; TAILQ_INIT(&clknode->children); + sysctl_ctx_init(&clknode->sysctl_ctx); + clknode_oid = SYSCTL_ADD_NODE(&clknode->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_clock), + OID_AUTO, clknode->name, + CTLFLAG_RD, 0, "A clock node"); + + SYSCTL_ADD_U64(&clknode->sysctl_ctx, + SYSCTL_CHILDREN(clknode_oid), + OID_AUTO, "frequency", + CTLFLAG_RD, &clknode->freq, 0, "The clock frequency"); + SYSCTL_ADD_PROC(&clknode->sysctl_ctx, + SYSCTL_CHILDREN(clknode_oid), + OID_AUTO, "parent", + CTLTYPE_STRING | CTLFLAG_RD, + clknode, CLKNODE_SYSCTL_PARENT, clknode_sysctl, + "A", + "The clock parent"); + SYSCTL_ADD_PROC(&clknode->sysctl_ctx, + SYSCTL_CHILDREN(clknode_oid), + OID_AUTO, "parents", + CTLTYPE_STRING | CTLFLAG_RD, + clknode, CLKNODE_SYSCTL_PARENTS_LIST, clknode_sysctl, + "A", + "The clock parents list"); + SYSCTL_ADD_PROC(&clknode->sysctl_ctx, + SYSCTL_CHILDREN(clknode_oid), + OID_AUTO, "childrens", + CTLTYPE_STRING | CTLFLAG_RD, + clknode, CLKNODE_SYSCTL_CHILDREN_LIST, clknode_sysctl, + "A", + "The clock childrens list"); + SYSCTL_ADD_INT(&clknode->sysctl_ctx, + SYSCTL_CHILDREN(clknode_oid), + OID_AUTO, "enable_cnt", + CTLFLAG_RD, &clknode->enable_cnt, 0, "The clock enable counter"); + return (clknode); } @@ -1385,3 +1442,64 @@ clk_parse_ofw_clk_name(device_t dev, pha return (0); } #endif + +static int +clkdom_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct clkdom *clkdom = arg1; + struct clknode *clknode; + struct sbuf *sb; + int ret; + + sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); + if (sb == NULL) + return (ENOMEM); + + CLK_TOPO_SLOCK(); + TAILQ_FOREACH(clknode, &clkdom->clknode_list, clkdom_link) { + sbuf_printf(sb, "%s ", clknode->name); + } + CLK_TOPO_UNLOCK(); + + ret = sbuf_finish(sb); + sbuf_delete(sb); + return (ret); +} + +static int +clknode_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct clknode *clknode, *children; + enum clknode_sysctl_type type = arg2; + struct sbuf *sb; + const char **parent_names; + int ret, i; + + clknode = arg1; + sb = sbuf_new_for_sysctl(NULL, NULL, 512, req); + if (sb == NULL) + return (ENOMEM); + + CLK_TOPO_SLOCK(); + switch (type) { + case CLKNODE_SYSCTL_PARENT: + if (clknode->parent) + sbuf_printf(sb, "%s", clknode->parent->name); + break; + case CLKNODE_SYSCTL_PARENTS_LIST: + parent_names = clknode_get_parent_names(clknode); + for (i = 0; i < clknode->parent_cnt; i++) + sbuf_printf(sb, "%s ", parent_names[i]); + break; + case CLKNODE_SYSCTL_CHILDREN_LIST: + TAILQ_FOREACH(children, &(clknode->children), sibling_link) { + sbuf_printf(sb, "%s ", children->name); + } + break; + } + CLK_TOPO_UNLOCK(); + + ret = sbuf_finish(sb); + sbuf_delete(sb); + return (ret); +} Modified: head/sys/kern/kern_mib.c ============================================================================== --- head/sys/kern/kern_mib.c Sun Mar 5 05:17:36 2017 (r314698) +++ head/sys/kern/kern_mib.c Sun Mar 5 07:13:29 2017 (r314699) @@ -88,6 +88,11 @@ SYSCTL_ROOT_NODE(OID_AUTO, regression, C "Regression test MIB"); #endif +#ifdef EXT_RESOURCES +SYSCTL_ROOT_NODE(OID_AUTO, clock, CTLFLAG_RW, 0, + "Clocks"); +#endif + SYSCTL_STRING(_kern, OID_AUTO, ident, CTLFLAG_RD|CTLFLAG_MPSAFE, kern_ident, 0, "Kernel identifier"); Modified: head/sys/sys/sysctl.h ============================================================================== --- head/sys/sys/sysctl.h Sun Mar 5 05:17:36 2017 (r314698) +++ head/sys/sys/sysctl.h Sun Mar 5 07:13:29 2017 (r314699) @@ -1004,6 +1004,9 @@ SYSCTL_DECL(_compat); SYSCTL_DECL(_regression); SYSCTL_DECL(_security); SYSCTL_DECL(_security_bsd); +#ifdef EXT_RESOURCES +SYSCTL_DECL(_clock); +#endif extern char machine[]; extern char osrelease[];
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703050713.v257DT3s028601>