diff options
-rw-r--r-- | drivers/clk/clk-gate.c | 25 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 5 |
2 files changed, 24 insertions, 6 deletions
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 15114febfd92..790306e921c8 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c | |||
@@ -53,12 +53,18 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) | |||
53 | if (gate->lock) | 53 | if (gate->lock) |
54 | spin_lock_irqsave(gate->lock, flags); | 54 | spin_lock_irqsave(gate->lock, flags); |
55 | 55 | ||
56 | reg = readl(gate->reg); | 56 | if (gate->flags & CLK_GATE_HIWORD_MASK) { |
57 | 57 | reg = BIT(gate->bit_idx + 16); | |
58 | if (set) | 58 | if (set) |
59 | reg |= BIT(gate->bit_idx); | 59 | reg |= BIT(gate->bit_idx); |
60 | else | 60 | } else { |
61 | reg &= ~BIT(gate->bit_idx); | 61 | reg = readl(gate->reg); |
62 | |||
63 | if (set) | ||
64 | reg |= BIT(gate->bit_idx); | ||
65 | else | ||
66 | reg &= ~BIT(gate->bit_idx); | ||
67 | } | ||
62 | 68 | ||
63 | writel(reg, gate->reg); | 69 | writel(reg, gate->reg); |
64 | 70 | ||
@@ -121,6 +127,13 @@ struct clk *clk_register_gate(struct device *dev, const char *name, | |||
121 | struct clk *clk; | 127 | struct clk *clk; |
122 | struct clk_init_data init; | 128 | struct clk_init_data init; |
123 | 129 | ||
130 | if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { | ||
131 | if (bit_idx > 16) { | ||
132 | pr_err("gate bit exceeds LOWORD field\n"); | ||
133 | return ERR_PTR(-EINVAL); | ||
134 | } | ||
135 | } | ||
136 | |||
124 | /* allocate the gate */ | 137 | /* allocate the gate */ |
125 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | 138 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); |
126 | if (!gate) { | 139 | if (!gate) { |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index d77f1267f419..1ec14a732176 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -210,6 +210,10 @@ void of_fixed_clk_setup(struct device_node *np); | |||
210 | * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to | 210 | * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to |
211 | * enable the clock. Setting this flag does the opposite: setting the bit | 211 | * enable the clock. Setting this flag does the opposite: setting the bit |
212 | * disable the clock and clearing it enables the clock | 212 | * disable the clock and clearing it enables the clock |
213 | * CLK_GATE_HIWORD_MASK - The gate settings are only in lower 16-bit | ||
214 | * of this register, and mask of gate bits are in higher 16-bit of this | ||
215 | * register. While setting the gate bits, higher 16-bit should also be | ||
216 | * updated to indicate changing gate bits. | ||
213 | */ | 217 | */ |
214 | struct clk_gate { | 218 | struct clk_gate { |
215 | struct clk_hw hw; | 219 | struct clk_hw hw; |
@@ -220,6 +224,7 @@ struct clk_gate { | |||
220 | }; | 224 | }; |
221 | 225 | ||
222 | #define CLK_GATE_SET_TO_DISABLE BIT(0) | 226 | #define CLK_GATE_SET_TO_DISABLE BIT(0) |
227 | #define CLK_GATE_HIWORD_MASK BIT(1) | ||
223 | 228 | ||
224 | extern const struct clk_ops clk_gate_ops; | 229 | extern const struct clk_ops clk_gate_ops; |
225 | struct clk *clk_register_gate(struct device *dev, const char *name, | 230 | struct clk *clk_register_gate(struct device *dev, const char *name, |