|
@@ -67,8 +67,12 @@ static void clk_gate2_disable(struct clk_hw *hw)
|
|
|
|
|
|
spin_lock_irqsave(gate->lock, flags);
|
|
|
|
|
|
- if (gate->share_count && --(*gate->share_count) > 0)
|
|
|
- goto out;
|
|
|
+ if (gate->share_count) {
|
|
|
+ if (WARN_ON(*gate->share_count == 0))
|
|
|
+ goto out;
|
|
|
+ else if (--(*gate->share_count) > 0)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
reg = readl(gate->reg);
|
|
|
reg &= ~(3 << gate->bit_idx);
|
|
@@ -78,19 +82,26 @@ out:
|
|
|
spin_unlock_irqrestore(gate->lock, flags);
|
|
|
}
|
|
|
|
|
|
-static int clk_gate2_is_enabled(struct clk_hw *hw)
|
|
|
+static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
|
|
|
{
|
|
|
- u32 reg;
|
|
|
- struct clk_gate2 *gate = to_clk_gate2(hw);
|
|
|
+ u32 val = readl(reg);
|
|
|
|
|
|
- reg = readl(gate->reg);
|
|
|
-
|
|
|
- if (((reg >> gate->bit_idx) & 1) == 1)
|
|
|
+ if (((val >> bit_idx) & 1) == 1)
|
|
|
return 1;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int clk_gate2_is_enabled(struct clk_hw *hw)
|
|
|
+{
|
|
|
+ struct clk_gate2 *gate = to_clk_gate2(hw);
|
|
|
+
|
|
|
+ if (gate->share_count)
|
|
|
+ return !!(*gate->share_count);
|
|
|
+ else
|
|
|
+ return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
|
|
|
+}
|
|
|
+
|
|
|
static struct clk_ops clk_gate2_ops = {
|
|
|
.enable = clk_gate2_enable,
|
|
|
.disable = clk_gate2_disable,
|
|
@@ -116,6 +127,10 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
|
|
|
gate->bit_idx = bit_idx;
|
|
|
gate->flags = clk_gate2_flags;
|
|
|
gate->lock = lock;
|
|
|
+
|
|
|
+ /* Initialize share_count per hardware state */
|
|
|
+ if (share_count)
|
|
|
+ *share_count = clk_gate2_reg_is_enabled(reg, bit_idx) ? 1 : 0;
|
|
|
gate->share_count = share_count;
|
|
|
|
|
|
init.name = name;
|