Message ID | 20190418111211.10474-2-jonas.gorski@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | clk: make register endianness a run-time property | expand |
Quoting Jonas Gorski (2019-04-18 04:12:04) > Add a clock specific flag to switch register accesses to big endian, to > allow runtime configuration of big endian divider clocks. > > Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> > --- Applied to clk-next
Hi Jonas, On Thu, Apr 18, 2019 at 1:12 PM Jonas Gorski <jonas.gorski@gmail.com> wrote: > Add a clock specific flag to switch register accesses to big endian, to > allow runtime configuration of big endian divider clocks. > > Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> > --- > V2 -> V3: > * fix passed arguments to clk_div_readl found by kbuild > * drop unneeded else in clk_div_readl > V1 -> V2: > * switch from global to local flag > > drivers/clk/clk-divider.c | 26 ++++++++++++++++++++++---- > include/linux/clk-provider.h | 4 ++++ > 2 files changed, 26 insertions(+), 4 deletions(-) > > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c > index e5a17265cfaf..25c7404e376c 100644 > --- a/drivers/clk/clk-divider.c > +++ b/drivers/clk/clk-divider.c > @@ -25,6 +25,24 @@ > * parent - fixed parent. No clk_set_parent support > */ > > +static inline u32 clk_div_readl(struct clk_divider *divider) > +{ > + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) > + return ioread32be(divider->reg); > + > + return clk_readl(divider->reg); > +} > + > +static inline void clk_div_writel(struct clk_divider *divider, u32 val) > +{ > + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) > + iowrite32be(val, divider->reg); > + else > + clk_writel(val, divider->reg); > +} > + > +#define div_mask(width) ((1 << (width)) - 1) What's the purpose of adding this definition? It does not seem to be used. Gr{oetje,eeting}s, Geert
Hi Geert, On Tue, 23 Apr 2019 at 09:49, Geert Uytterhoeven <geert@linux-m68k.org> wrote: > > Hi Jonas, > > On Thu, Apr 18, 2019 at 1:12 PM Jonas Gorski <jonas.gorski@gmail.com> wrote: > > Add a clock specific flag to switch register accesses to big endian, to > > allow runtime configuration of big endian divider clocks. > > > > Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> > > --- > > V2 -> V3: > > * fix passed arguments to clk_div_readl found by kbuild > > * drop unneeded else in clk_div_readl > > V1 -> V2: > > * switch from global to local flag > > > > drivers/clk/clk-divider.c | 26 ++++++++++++++++++++++---- > > include/linux/clk-provider.h | 4 ++++ > > 2 files changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c > > index e5a17265cfaf..25c7404e376c 100644 > > --- a/drivers/clk/clk-divider.c > > +++ b/drivers/clk/clk-divider.c > > @@ -25,6 +25,24 @@ > > * parent - fixed parent. No clk_set_parent support > > */ > > > > +static inline u32 clk_div_readl(struct clk_divider *divider) > > +{ > > + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) > > + return ioread32be(divider->reg); > > + > > + return clk_readl(divider->reg); > > +} > > + > > +static inline void clk_div_writel(struct clk_divider *divider, u32 val) > > +{ > > + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) > > + iowrite32be(val, divider->reg); > > + else > > + clk_writel(val, divider->reg); > > +} > > + > > +#define div_mask(width) ((1 << (width)) - 1) > > What's the purpose of adding this definition? > It does not seem to be used. No purpose at all, it's an uncaught artifact from rebasing ._. Stephen, which one is your preferred way of fixing that? a) a new V4 patchset without this line b) a follow up patch that removes it c) just removing the line yourself Regards Jonas
Quoting Jonas Gorski (2019-04-23 03:39:59) > No purpose at all, it's an uncaught artifact from rebasing ._. > > Stephen, which one is your preferred way of fixing that? > > a) a new V4 patchset without this line > b) a follow up patch that removes it > c) just removing the line yourself I'll go for c and fix up things. Thanks for the catch Geert!
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index e5a17265cfaf..25c7404e376c 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -25,6 +25,24 @@ * parent - fixed parent. No clk_set_parent support */ +static inline u32 clk_div_readl(struct clk_divider *divider) +{ + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) + return ioread32be(divider->reg); + + return clk_readl(divider->reg); +} + +static inline void clk_div_writel(struct clk_divider *divider, u32 val) +{ + if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) + iowrite32be(val, divider->reg); + else + clk_writel(val, divider->reg); +} + +#define div_mask(width) ((1 << (width)) - 1) + static unsigned int _get_table_maxdiv(const struct clk_div_table *table, u8 width) { @@ -135,7 +153,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, struct clk_divider *divider = to_clk_divider(hw); unsigned int val; - val = clk_readl(divider->reg) >> divider->shift; + val = clk_div_readl(divider) >> divider->shift; val &= clk_div_mask(divider->width); return divider_recalc_rate(hw, parent_rate, val, divider->table, @@ -370,7 +388,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, if (divider->flags & CLK_DIVIDER_READ_ONLY) { u32 val; - val = clk_readl(divider->reg) >> divider->shift; + val = clk_div_readl(divider) >> divider->shift; val &= clk_div_mask(divider->width); return divider_ro_round_rate(hw, rate, prate, divider->table, @@ -420,11 +438,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { val = clk_div_mask(divider->width) << (divider->shift + 16); } else { - val = clk_readl(divider->reg); + val = clk_div_readl(divider); val &= ~(clk_div_mask(divider->width) << divider->shift); } val |= (u32)value << divider->shift; - clk_writel(val, divider->reg); + clk_div_writel(divider, val); if (divider->lock) spin_unlock_irqrestore(divider->lock, flags); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index db21437c77e2..7117b8cc0c0c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -416,6 +416,9 @@ struct clk_div_table { * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED * except when the value read from the register is zero, the divisor is * 2^width of the field. + * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used + * for the divider register. Setting this flag makes the register accesses + * big endian. */ struct clk_divider { struct clk_hw hw; @@ -437,6 +440,7 @@ struct clk_divider { #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) #define CLK_DIVIDER_READ_ONLY BIT(5) #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) +#define CLK_DIVIDER_BIG_ENDIAN BIT(7) extern const struct clk_ops clk_divider_ops; extern const struct clk_ops clk_divider_ro_ops;
Add a clock specific flag to switch register accesses to big endian, to allow runtime configuration of big endian divider clocks. Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> --- V2 -> V3: * fix passed arguments to clk_div_readl found by kbuild * drop unneeded else in clk_div_readl V1 -> V2: * switch from global to local flag drivers/clk/clk-divider.c | 26 ++++++++++++++++++++++---- include/linux/clk-provider.h | 4 ++++ 2 files changed, 26 insertions(+), 4 deletions(-)