|
@@ -925,15 +925,18 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
|
|
|
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ spin_lock_irqsave(&clkdm->lock, flags);
|
|
|
+
|
|
|
/*
|
|
|
* For arch's with no autodeps, clkcm_clk_enable
|
|
|
* should be called for every clock instance or hwmod that is
|
|
|
* enabled, so the clkdm can be force woken up.
|
|
|
*/
|
|
|
- if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps)
|
|
|
+ if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) {
|
|
|
+ spin_unlock_irqrestore(&clkdm->lock, flags);
|
|
|
return 0;
|
|
|
+ }
|
|
|
|
|
|
- spin_lock_irqsave(&clkdm->lock, flags);
|
|
|
arch_clkdm->clkdm_clk_enable(clkdm);
|
|
|
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
|
|
spin_unlock_irqrestore(&clkdm->lock, flags);
|
|
@@ -950,15 +953,19 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
|
|
|
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ spin_lock_irqsave(&clkdm->lock, flags);
|
|
|
+
|
|
|
if (atomic_read(&clkdm->usecount) == 0) {
|
|
|
+ spin_unlock_irqrestore(&clkdm->lock, flags);
|
|
|
WARN_ON(1); /* underflow */
|
|
|
return -ERANGE;
|
|
|
}
|
|
|
|
|
|
- if (atomic_dec_return(&clkdm->usecount) > 0)
|
|
|
+ if (atomic_dec_return(&clkdm->usecount) > 0) {
|
|
|
+ spin_unlock_irqrestore(&clkdm->lock, flags);
|
|
|
return 0;
|
|
|
+ }
|
|
|
|
|
|
- spin_lock_irqsave(&clkdm->lock, flags);
|
|
|
arch_clkdm->clkdm_clk_disable(clkdm);
|
|
|
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
|
|
spin_unlock_irqrestore(&clkdm->lock, flags);
|