Skip to content

Commit 8a53fc5

Browse files
Eddie Jamesbebarino
authored andcommitted
clk: aspeed: Prevent reset if clock is enabled
According to the Aspeed specification, the reset and enable sequence should be done when the clock is stopped. The specification doesn't define behavior if the reset is done while the clock is enabled. From testing on the AST2500, the LPC Controller has problems if the clock is reset while enabled. Therefore, check whether the clock is enabled or not before performing the reset and enable sequence in the Aspeed clock driver. Reported-by: Lei Yu <[email protected]> Signed-off-by: Eddie James <[email protected]> Fixes: 15ed8ce ("clk: aspeed: Register gated clocks") Reviewed-by: Joel Stanley <[email protected]> Signed-off-by: Stephen Boyd <[email protected]>
1 parent d90c76b commit 8a53fc5

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

drivers/clk/clk-aspeed.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,18 @@ static const struct aspeed_clk_soc_data ast2400_data = {
205205
.calc_pll = aspeed_ast2400_calc_pll,
206206
};
207207

208+
static int aspeed_clk_is_enabled(struct clk_hw *hw)
209+
{
210+
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
211+
u32 clk = BIT(gate->clock_idx);
212+
u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
213+
u32 reg;
214+
215+
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
216+
217+
return ((reg & clk) == enval) ? 1 : 0;
218+
}
219+
208220
static int aspeed_clk_enable(struct clk_hw *hw)
209221
{
210222
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
@@ -215,6 +227,11 @@ static int aspeed_clk_enable(struct clk_hw *hw)
215227

216228
spin_lock_irqsave(gate->lock, flags);
217229

230+
if (aspeed_clk_is_enabled(hw)) {
231+
spin_unlock_irqrestore(gate->lock, flags);
232+
return 0;
233+
}
234+
218235
if (gate->reset_idx >= 0) {
219236
/* Put IP in reset */
220237
regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);
@@ -255,18 +272,6 @@ static void aspeed_clk_disable(struct clk_hw *hw)
255272
spin_unlock_irqrestore(gate->lock, flags);
256273
}
257274

258-
static int aspeed_clk_is_enabled(struct clk_hw *hw)
259-
{
260-
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
261-
u32 clk = BIT(gate->clock_idx);
262-
u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
263-
u32 reg;
264-
265-
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
266-
267-
return ((reg & clk) == enval) ? 1 : 0;
268-
}
269-
270275
static const struct clk_ops aspeed_clk_gate_ops = {
271276
.enable = aspeed_clk_enable,
272277
.disable = aspeed_clk_disable,

0 commit comments

Comments
 (0)