Index: sys/dev/extres/clk/clk.h =================================================================== --- sys/dev/extres/clk/clk.h +++ sys/dev/extres/clk/clk.h @@ -112,6 +112,7 @@ device_t clknode_get_device(struct clknode *clk); struct clknode *clknode_find_by_name(const char *name); struct clknode *clknode_find_by_id(struct clkdom *clkdom, intptr_t id); +int clknode_list_freq(struct clknode *clknode, uint64_t *freq, int *freq_count); int clknode_get_freq(struct clknode *clknode, uint64_t *freq); int clknode_set_freq(struct clknode *clknode, uint64_t freq, int flags, int enablecnt); @@ -127,6 +128,7 @@ int clk_get_by_name(device_t dev, const char *name, clk_t *clk); int clk_get_by_id(device_t dev, struct clkdom *clkdom, intptr_t id, clk_t *clk); int clk_release(clk_t clk); +int clk_list_freq(clk_t clk, uint64_t *freq, int *freq_count); int clk_get_freq(clk_t clk, uint64_t *freq); int clk_set_freq(clk_t clk, uint64_t freq, int flags); int clk_test_freq(clk_t clk, uint64_t freq, int flags); Index: sys/dev/extres/clk/clk.c =================================================================== --- sys/dev/extres/clk/clk.c +++ sys/dev/extres/clk/clk.c @@ -65,6 +65,8 @@ /* Default clock methods. */ static int clknode_method_init(struct clknode *clk, device_t dev); +static int clknode_method_list_freq(struct clknode *clknode, uint64_t *freq, + int *count); static int clknode_method_recalc_freq(struct clknode *clk, uint64_t *freq); static int clknode_method_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout, int flags, int *stop); @@ -76,6 +78,7 @@ */ static clknode_method_t clknode_methods[] = { CLKNODEMETHOD(clknode_init, clknode_method_init), + CLKNODEMETHOD(clknode_list_freq, clknode_method_list_freq), CLKNODEMETHOD(clknode_recalc_freq, clknode_method_recalc_freq), CLKNODEMETHOD(clknode_set_freq, clknode_method_set_freq), CLKNODEMETHOD(clknode_set_gate, clknode_method_set_gate), @@ -205,6 +208,13 @@ return (0); } +static int +clknode_method_list_freq(struct clknode *clknode, uint64_t *freq, int *count) +{ + + return (0); +} + static int clknode_method_recalc_freq(struct clknode *clknode, uint64_t *freq) { @@ -929,6 +939,20 @@ /* * Real consumers executive */ +int +clknode_list_freq(struct clknode *clknode, uint64_t *freq, int *freq_count) +{ + int rv; + + CLK_TOPO_ASSERT(); + + CLKNODE_XLOCK(clknode); + rv = CLKNODE_LIST_FREQ(clknode, freq, freq_count); + CLKNODE_UNLOCK(clknode); + + return (rv); +} + int clknode_get_freq(struct clknode *clknode, uint64_t *freq) { @@ -1186,6 +1210,20 @@ return (rv); } +int +clk_list_freq(clk_t clk, uint64_t *freq, int *freq_count) +{ + int rv; + struct clknode *clknode; + + clknode = clk->clknode; + + CLK_TOPO_XLOCK(); + rv = clknode_list_freq(clknode, freq, freq_count); + CLK_TOPO_UNLOCK(); + return (rv); +} + int clk_set_freq(clk_t clk, uint64_t freq, int flags) { Index: sys/dev/extres/clk/clknode_if.m =================================================================== --- sys/dev/extres/clk/clknode_if.m +++ sys/dev/extres/clk/clknode_if.m @@ -40,6 +40,15 @@ device_t dev; }; +# +# List all possible frequencies. +# +METHOD int list_freq { + struct clknode *clk; + uint64_t *freq; + int *freq_count; +}; + # # Recalculate frequency # req - in/out recalulated frequency