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, |
