From owner-svn-src-head@freebsd.org Sun Mar 5 07:13:30 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 75397CFA292; Sun, 5 Mar 2017 07:13:30 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4FCB51286; Sun, 5 Mar 2017 07:13:30 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v257DT6W028604; Sun, 5 Mar 2017 07:13:29 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v257DT3s028601; Sun, 5 Mar 2017 07:13:29 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201703050713.v257DT3s028601@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Sun, 5 Mar 2017 07:13:29 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Mar 2017 07:13:30 -0000 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...clocks for each clock domain containing all the clocks that they provide. Each clocks are exported under the node 'clock.' 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 #include #include +#include #include #include #include @@ -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[];