diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2019-04-18 07:12:05 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-04-23 13:57:48 -0400 |
commit | 58a2b4c9bdf98452fec95bb1a5eeed60c01f621a (patch) | |
tree | e06cbcfd3d31c29777a948ac83baa2375bf418ae | |
parent | 434d69fad63b443d7afc8aa99264359c9b4e2d3a (diff) |
clk: fractional-divider: add explicit big endian support
Add a clock specific flag to switch register accesses to big endian, to
allow runtime configuration of big endian fractional divider clocks.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r-- | drivers/clk/clk-fractional-divider.c | 22 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 4 |
2 files changed, 23 insertions, 3 deletions
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index fdfe2e423d15..f88df265e787 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c | |||
@@ -13,6 +13,22 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/rational.h> | 14 | #include <linux/rational.h> |
15 | 15 | ||
16 | static inline u32 clk_fd_readl(struct clk_fractional_divider *fd) | ||
17 | { | ||
18 | if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN) | ||
19 | return ioread32be(fd->reg); | ||
20 | |||
21 | return clk_readl(fd->reg); | ||
22 | } | ||
23 | |||
24 | static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val) | ||
25 | { | ||
26 | if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN) | ||
27 | iowrite32be(val, fd->reg); | ||
28 | else | ||
29 | clk_writel(val, fd->reg); | ||
30 | } | ||
31 | |||
16 | static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | 32 | static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, |
17 | unsigned long parent_rate) | 33 | unsigned long parent_rate) |
18 | { | 34 | { |
@@ -27,7 +43,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | |||
27 | else | 43 | else |
28 | __acquire(fd->lock); | 44 | __acquire(fd->lock); |
29 | 45 | ||
30 | val = clk_readl(fd->reg); | 46 | val = clk_fd_readl(fd); |
31 | 47 | ||
32 | if (fd->lock) | 48 | if (fd->lock) |
33 | spin_unlock_irqrestore(fd->lock, flags); | 49 | spin_unlock_irqrestore(fd->lock, flags); |
@@ -115,10 +131,10 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, | |||
115 | else | 131 | else |
116 | __acquire(fd->lock); | 132 | __acquire(fd->lock); |
117 | 133 | ||
118 | val = clk_readl(fd->reg); | 134 | val = clk_fd_readl(fd); |
119 | val &= ~(fd->mmask | fd->nmask); | 135 | val &= ~(fd->mmask | fd->nmask); |
120 | val |= (m << fd->mshift) | (n << fd->nshift); | 136 | val |= (m << fd->mshift) | (n << fd->nshift); |
121 | clk_writel(val, fd->reg); | 137 | clk_fd_writel(fd, val); |
122 | 138 | ||
123 | if (fd->lock) | 139 | if (fd->lock) |
124 | spin_unlock_irqrestore(fd->lock, flags); | 140 | spin_unlock_irqrestore(fd->lock, flags); |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index f0abdfbe3d60..7c6861995505 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -606,6 +606,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw); | |||
606 | * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED | 606 | * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED |
607 | * is set then the numerator and denominator are both the value read | 607 | * is set then the numerator and denominator are both the value read |
608 | * plus one. | 608 | * plus one. |
609 | * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are | ||
610 | * used for the divider register. Setting this flag makes the register | ||
611 | * accesses big endian. | ||
609 | */ | 612 | */ |
610 | struct clk_fractional_divider { | 613 | struct clk_fractional_divider { |
611 | struct clk_hw hw; | 614 | struct clk_hw hw; |
@@ -626,6 +629,7 @@ struct clk_fractional_divider { | |||
626 | #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) | 629 | #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) |
627 | 630 | ||
628 | #define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) | 631 | #define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) |
632 | #define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1) | ||
629 | 633 | ||
630 | extern const struct clk_ops clk_fractional_divider_ops; | 634 | extern const struct clk_ops clk_fractional_divider_ops; |
631 | struct clk *clk_register_fractional_divider(struct device *dev, | 635 | struct clk *clk_register_fractional_divider(struct device *dev, |