Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: gate: add CLK_GATE_HIWORD_MASK

In Rockchip Cortex-A9 based chips, they don't use paradigm of
reading-changing-writing the register contents. Instead they
use a hiword mask to indicate the changed bits.

When b1 should be set as gate, it also needs to indicate the change
by setting hiword mask (b1 << 16).

The patch adds gate flag for this usage.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

authored by

Haojian Zhuang and committed by
Mike Turquette
04577994 d57dfe75

+23 -5
+18 -5
drivers/clk/clk-gate.c
··· 53 53 if (gate->lock) 54 54 spin_lock_irqsave(gate->lock, flags); 55 55 56 - reg = readl(gate->reg); 56 + if (gate->flags & CLK_GATE_HIWORD_MASK) { 57 + reg = BIT(gate->bit_idx + 16); 58 + if (set) 59 + reg |= BIT(gate->bit_idx); 60 + } else { 61 + reg = readl(gate->reg); 57 62 58 - if (set) 59 - reg |= BIT(gate->bit_idx); 60 - else 61 - reg &= ~BIT(gate->bit_idx); 63 + if (set) 64 + reg |= BIT(gate->bit_idx); 65 + else 66 + reg &= ~BIT(gate->bit_idx); 67 + } 62 68 63 69 writel(reg, gate->reg); 64 70 ··· 126 120 struct clk_gate *gate; 127 121 struct clk *clk; 128 122 struct clk_init_data init; 123 + 124 + if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { 125 + if (bit_idx > 16) { 126 + pr_err("gate bit exceeds LOWORD field\n"); 127 + return ERR_PTR(-EINVAL); 128 + } 129 + } 129 130 130 131 /* allocate the gate */ 131 132 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+5
include/linux/clk-provider.h
··· 210 210 * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to 211 211 * enable the clock. Setting this flag does the opposite: setting the bit 212 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 218 struct clk_gate { 215 219 struct clk_hw hw; ··· 224 220 }; 225 221 226 222 #define CLK_GATE_SET_TO_DISABLE BIT(0) 223 + #define CLK_GATE_HIWORD_MASK BIT(1) 227 224 228 225 extern const struct clk_ops clk_gate_ops; 229 226 struct clk *clk_register_gate(struct device *dev, const char *name,