clk: ti: add a usecount for autoidle

Multiple users might deny autoidle on a clock. So we should have some
counting here, also according to the comment in  _setup_iclk_autoidle().
Also setting autoidle regs is not atomic, so there is another reason
for locking.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Acked-by: Tony Lindgren <tony@atomide.com>
Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
This commit is contained in:
Andreas Kemnade 2019-01-16 23:04:27 +01:00 committed by Tero Kristo
parent ead478250b
commit d277ce2d3a
2 changed files with 29 additions and 4 deletions

View File

@ -36,17 +36,41 @@ struct clk_ti_autoidle {
static LIST_HEAD(autoidle_clks);
/*
* we have some non-atomic read/write
* operations behind it, so lets
* take one lock for handling autoidle
* of all clocks
*/
static DEFINE_SPINLOCK(autoidle_spinlock);
static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
{
if (clk->ops && clk->ops->deny_idle)
clk->ops->deny_idle(clk);
if (clk->ops && clk->ops->deny_idle) {
unsigned long irqflags;
spin_lock_irqsave(&autoidle_spinlock, irqflags);
clk->autoidle_count++;
if (clk->autoidle_count == 1)
clk->ops->deny_idle(clk);
spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
}
return 0;
}
static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
{
if (clk->ops && clk->ops->allow_idle)
clk->ops->allow_idle(clk);
if (clk->ops && clk->ops->allow_idle) {
unsigned long irqflags;
spin_lock_irqsave(&autoidle_spinlock, irqflags);
clk->autoidle_count--;
if (clk->autoidle_count == 0)
clk->ops->allow_idle(clk);
spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
}
return 0;
}

View File

@ -160,6 +160,7 @@ struct clk_hw_omap {
struct clockdomain *clkdm;
const struct clk_hw_omap_ops *ops;
u32 context;
int autoidle_count;
};
/*