Commit 58a2b4c9 authored by Jonas Gorski's avatar Jonas Gorski Committed by Stephen Boyd
Browse files

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: default avatarJonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 434d69fa
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -13,6 +13,22 @@
#include <linux/slab.h>
#include <linux/rational.h>

static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
{
	if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
		return ioread32be(fd->reg);

	return clk_readl(fd->reg);
}

static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val)
{
	if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
		iowrite32be(val, fd->reg);
	else
		clk_writel(val, fd->reg);
}

static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
@@ -27,7 +43,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
	else
		__acquire(fd->lock);

	val = clk_readl(fd->reg);
	val = clk_fd_readl(fd);

	if (fd->lock)
		spin_unlock_irqrestore(fd->lock, flags);
@@ -115,10 +131,10 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
	else
		__acquire(fd->lock);

	val = clk_readl(fd->reg);
	val = clk_fd_readl(fd);
	val &= ~(fd->mmask | fd->nmask);
	val |= (m << fd->mshift) | (n << fd->nshift);
	clk_writel(val, fd->reg);
	clk_fd_writel(fd, val);

	if (fd->lock)
		spin_unlock_irqrestore(fd->lock, flags);
+4 −0
Original line number Diff line number Diff line
@@ -606,6 +606,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
 *	is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
 *	is set then the numerator and denominator are both the value read
 *	plus one.
 * CLK_FRAC_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_fractional_divider {
	struct clk_hw	hw;
@@ -626,6 +629,7 @@ struct clk_fractional_divider {
#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)

#define CLK_FRAC_DIVIDER_ZERO_BASED		BIT(0)
#define CLK_FRAC_DIVIDER_BIG_ENDIAN		BIT(1)

extern const struct clk_ops clk_fractional_divider_ops;
struct clk *clk_register_fractional_divider(struct device *dev,