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

clk: gate: add explicit big endian support



Add a clock specific flag to switch register accesses to big endian, to
allow runtime configuration of big endian gated clocks.

Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 58a2b4c9
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -23,6 +23,22 @@
 * parent - fixed parent.  No clk_set_parent support
 */

static inline u32 clk_gate_readl(struct clk_gate *gate)
{
	if (gate->flags & CLK_GATE_BIG_ENDIAN)
		return ioread32be(gate->reg);

	return clk_readl(gate->reg);
}

static inline void clk_gate_writel(struct clk_gate *gate, u32 val)
{
	if (gate->flags & CLK_GATE_BIG_ENDIAN)
		iowrite32be(val, gate->reg);
	else
		clk_writel(val, gate->reg);
}

/*
 * It works on following logic:
 *
@@ -55,7 +71,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
		if (set)
			reg |= BIT(gate->bit_idx);
	} else {
		reg = clk_readl(gate->reg);
		reg = clk_gate_readl(gate);

		if (set)
			reg |= BIT(gate->bit_idx);
@@ -63,7 +79,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
			reg &= ~BIT(gate->bit_idx);
	}

	clk_writel(reg, gate->reg);
	clk_gate_writel(gate, reg);

	if (gate->lock)
		spin_unlock_irqrestore(gate->lock, flags);
@@ -88,7 +104,7 @@ int clk_gate_is_enabled(struct clk_hw *hw)
	u32 reg;
	struct clk_gate *gate = to_clk_gate(hw);

	reg = clk_readl(gate->reg);
	reg = clk_gate_readl(gate);

	/* if a set bit disables this clk, flip it before masking */
	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+4 −0
Original line number Diff line number Diff line
@@ -349,6 +349,9 @@ void of_fixed_clk_setup(struct device_node *np);
 *	of this register, and mask of gate bits are in higher 16-bit of this
 *	register.  While setting the gate bits, higher 16-bit should also be
 *	updated to indicate changing gate bits.
 * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for
 *	the gate register.  Setting this flag makes the register accesses big
 *	endian.
 */
struct clk_gate {
	struct clk_hw hw;
@@ -362,6 +365,7 @@ struct clk_gate {

#define CLK_GATE_SET_TO_DISABLE		BIT(0)
#define CLK_GATE_HIWORD_MASK		BIT(1)
#define CLK_GATE_BIG_ENDIAN		BIT(2)

extern const struct clk_ops clk_gate_ops;
struct clk *clk_register_gate(struct device *dev, const char *name,