Skip to content

Commit

Permalink
clk: qcom: Use regmap_update_bits() to update the clock flags
Browse files Browse the repository at this point in the history
Currently clk_cbcr_set_flags() reads the CBCR register content,
modifies the flags and writes back the updated value into it.
Sometimes clk_set_flags() gets invoked for the same clock
while clk_enable() is in progress causing the CLK_ENABLE bit
getting updated outside of clk_enable() path. Therefore, use
regmap_update_bits() to update the flags in CBCR register.
Also add a barrier in clock enable/disable path to make
sure that register write goes through.

Change-Id: I8018f8033d05273320fd92cc7d21fcdce0885dfc
Signed-off-by: Odelu Kukatla <[email protected]>
  • Loading branch information
Odelu Kukatla authored and Gerrit - the friendly Code Review server committed Jul 24, 2019
1 parent 58bd5c1 commit af58450
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions drivers/clk/qcom/clk-branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ static int clk_branch_toggle(struct clk_hw *hw, bool en,
clk_disable_regmap(hw);
}

/*
* Make sure enable/disable request goes through before waiting
* for CLK_OFF status to get updated.
*/
mb();

return clk_branch_wait(br, en, check_halt);
}

Expand All @@ -136,34 +142,36 @@ static int clk_branch_enable(struct clk_hw *hw)
static int clk_cbcr_set_flags(struct regmap *regmap, unsigned int reg,
unsigned long flags)
{
u32 cbcr_val;

regmap_read(regmap, reg, &cbcr_val);
u32 cbcr_val = 0;
u32 cbcr_mask;
int ret;

switch (flags) {
case CLKFLAG_PERIPH_OFF_SET:
cbcr_val |= BIT(12);
cbcr_val = cbcr_mask = BIT(12);
break;
case CLKFLAG_PERIPH_OFF_CLEAR:
cbcr_val &= ~BIT(12);
cbcr_mask = BIT(12);
break;
case CLKFLAG_RETAIN_PERIPH:
cbcr_val |= BIT(13);
cbcr_val = cbcr_mask = BIT(13);
break;
case CLKFLAG_NORETAIN_PERIPH:
cbcr_val &= ~BIT(13);
cbcr_mask = BIT(13);
break;
case CLKFLAG_RETAIN_MEM:
cbcr_val |= BIT(14);
cbcr_val = cbcr_mask = BIT(14);
break;
case CLKFLAG_NORETAIN_MEM:
cbcr_val &= ~BIT(14);
cbcr_mask = BIT(14);
break;
default:
return -EINVAL;
}

regmap_write(regmap, reg, cbcr_val);
ret = regmap_update_bits(regmap, reg, cbcr_mask, cbcr_val);
if (ret)
return ret;

/* Make sure power is enabled/disabled before returning. */
mb();
Expand Down

0 comments on commit af58450

Please sign in to comment.