git: c8300031980e - main - EXTRES: Ignore index modifier flags for table based clock dividers.
Michal Meloun
mmel at FreeBSD.org
Sun Dec 27 16:47:44 UTC 2020
The branch main has been updated by mmel:
URL: https://cgit.FreeBSD.org/src/commit/?id=c8300031980e5647853a379aa518dd9e88a88619
commit c8300031980e5647853a379aa518dd9e88a88619
Author: Michal Meloun <strejda at users.noreply.github.com>
AuthorDate: 2018-01-04 12:12:39 +0000
Commit: Michal Meloun <mmel at FreeBSD.org>
CommitDate: 2020-12-27 16:47:19 +0000
EXTRES: Ignore index modifier flags for table based clock dividers.
The divider table already contains the correct HW divider value, it should
not be modified by other flags such as 'CLK_DIV_ZERO_BASED'.
MFC after: 4 weeks
---
sys/dev/extres/clk/clk_div.c | 45 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/sys/dev/extres/clk/clk_div.c b/sys/dev/extres/clk/clk_div.c
index bf2de85e7ad0..68b23c6cc45b 100644
--- a/sys/dev/extres/clk/clk_div.c
+++ b/sys/dev/extres/clk/clk_div.c
@@ -131,7 +131,8 @@ clknode_div_init(struct clknode *clk, device_t dev)
return (rv);
i_div = (reg >> sc->i_shift) & sc->i_mask;
- if (!(sc->div_flags & CLK_DIV_ZERO_BASED))
+ if (!(sc->div_flags & CLK_DIV_WITH_TABLE) &&
+ !(sc->div_flags & CLK_DIV_ZERO_BASED))
i_div++;
f_div = (reg >> sc->f_shift) & sc->f_mask;
sc->divider = i_div << sc->f_width | f_div;
@@ -166,7 +167,7 @@ clknode_div_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
{
struct clknode_div_sc *sc;
uint64_t divider, _fin, _fout;
- uint32_t div_value, reg, i_div, f_div, hw_i_div;
+ uint32_t reg, i_div, f_div, hw_i_div;
int rv;
sc = clknode_get_softc(clk);
@@ -192,23 +193,27 @@ clknode_div_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
return(EINVAL);
}
- hw_i_div = i_div;
- if (!(sc->div_flags & CLK_DIV_ZERO_BASED))
- hw_i_div--;
-
*stop = 1;
- if (hw_i_div > sc->i_mask &&
- ((sc->div_flags & CLK_DIV_WITH_TABLE) == 0)) {
- /* XXX Or only return error? */
- printf("%s: %s integer divider is too big: %u\n",
- clknode_get_name(clk), __func__, hw_i_div);
- hw_i_div = sc->i_mask;
- *stop = 0;
+ hw_i_div = i_div;
+ if (sc->div_flags & CLK_DIV_WITH_TABLE) {
+ if (clknode_div_table_get_value(sc, &hw_i_div) != 0)
+ return (ERANGE);
+ } else {
+ if (!(sc->div_flags & CLK_DIV_ZERO_BASED))
+ hw_i_div--;
+
+ if (i_div > sc->i_mask) {
+ /* XXX Pass to parent or return error? */
+ printf("%s: %s integer divider is too big: %u\n",
+ clknode_get_name(clk), __func__, i_div);
+ hw_i_div = sc->i_mask;
+ *stop = 0;
+ }
+ i_div = hw_i_div;
+ if (!(sc->div_flags & CLK_DIV_ZERO_BASED))
+ i_div++;
}
- i_div = hw_i_div;
- if (!(sc->div_flags & CLK_DIV_ZERO_BASED))
- i_div++;
divider = i_div << sc->f_width | f_div;
if ((flags & CLK_SET_DRYRUN) == 0) {
@@ -217,16 +222,10 @@ clknode_div_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
(*fout != (_fin / divider)))
return (ERANGE);
- div_value = divider;
- if (clknode_div_table_get_value(sc, &div_value) != 0)
- return (ERANGE);
- if (div_value != divider)
- i_div = div_value;
-
DEVICE_LOCK(clk);
rv = MD4(clk, sc->offset,
(sc->i_mask << sc->i_shift) | (sc->f_mask << sc->f_shift),
- (i_div << sc->i_shift) | (f_div << sc->f_shift));
+ (hw_i_div << sc->i_shift) | (f_div << sc->f_shift));
if (rv != 0) {
DEVICE_UNLOCK(clk);
return (rv);
More information about the dev-commits-src-main
mailing list