Commit d277ce2d authored by Andreas Kemnade's avatar Andreas Kemnade Committed by Tero Kristo

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: default avatarAndreas Kemnade <andreas@kemnade.info>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
Tested-by: default avatarKeerthy <j-keerthy@ti.com>
Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
parent ead47825
...@@ -36,17 +36,41 @@ struct clk_ti_autoidle { ...@@ -36,17 +36,41 @@ struct clk_ti_autoidle {
static LIST_HEAD(autoidle_clks); 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) static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
{ {
if (clk->ops && clk->ops->deny_idle) if (clk->ops && clk->ops->deny_idle) {
clk->ops->deny_idle(clk); 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; return 0;
} }
static int _omap2_clk_allow_idle(struct clk_hw_omap *clk) static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
{ {
if (clk->ops && clk->ops->allow_idle) if (clk->ops && clk->ops->allow_idle) {
clk->ops->allow_idle(clk); 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; return 0;
} }
......
...@@ -160,6 +160,7 @@ struct clk_hw_omap { ...@@ -160,6 +160,7 @@ struct clk_hw_omap {
struct clockdomain *clkdm; struct clockdomain *clkdm;
const struct clk_hw_omap_ops *ops; const struct clk_hw_omap_ops *ops;
u32 context; u32 context;
int autoidle_count;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment