Index: sys/dev/extres/clk/clk.h =================================================================== --- sys/dev/extres/clk/clk.h +++ sys/dev/extres/clk/clk.h @@ -115,6 +115,8 @@ int clknode_get_freq(struct clknode *clknode, uint64_t *freq); int clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, int enablecnt); +int clknode_try_freq(struct clknode *clknode, uint64_t *freq, int flags, + int enablecnt); int clknode_enable(struct clknode *clknode); int clknode_disable(struct clknode *clknode); int clknode_stop(struct clknode *clknode, int depth); Index: sys/dev/extres/clk/clk.c =================================================================== --- sys/dev/extres/clk/clk.c +++ sys/dev/extres/clk/clk.c @@ -965,8 +965,8 @@ return (0); } -int -clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, +static int +_clknode_set_freq(struct clknode *clknode, uint64_t *freq, int flags, int enablecnt) { int rv, done; @@ -976,7 +976,7 @@ CLK_TOPO_XASSERT(); /* Check for no change */ - if (clknode->freq == freq) + if (clknode->freq == *freq) return (0); parent_freq = 0; @@ -1003,7 +1003,7 @@ } /* Set frequency for this clock. */ - rv = CLKNODE_SET_FREQ(clknode, parent_freq, &freq, flags, &done); + rv = CLKNODE_SET_FREQ(clknode, parent_freq, freq, flags, &done); if (rv != 0) { printf("Cannot set frequency for clk: %s, error: %d\n", clknode->name, rv); @@ -1015,7 +1015,7 @@ if (done) { /* Success - invalidate frequency cache for all children. */ if ((flags & CLK_SET_DRYRUN) == 0) { - clknode->freq = freq; + clknode->freq = *freq; /* Clock might have reparent during set_freq */ if (clknode->parent_cnt > 0) { rv = clknode_get_freq(clknode->parent, @@ -1028,7 +1028,8 @@ } } else if (clknode->parent != NULL) { /* Nothing changed, pass request to parent. */ - rv = clknode_set_freq(clknode->parent, freq, flags, enablecnt); + rv = _clknode_set_freq(clknode->parent, freq, flags, + enablecnt); } else { /* End of chain without action. */ printf("Cannot set frequency for clk: %s, end of chain\n", @@ -1039,6 +1040,23 @@ return (rv); } +int +clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, + int enablecnt) +{ + + return (_clknode_set_freq(clknode, &freq, flags, enablecnt)); +} + +int +clknode_try_freq(struct clknode *clknode, uint64_t *freq, int flags, + int enablecnt) +{ + + return (_clknode_set_freq(clknode, freq, flags | CLK_SET_DRYRUN, + enablecnt)); +} + int clknode_enable(struct clknode *clknode) {