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

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
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -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)
	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)
	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;
}

+1 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ struct clk_hw_omap {
	struct clockdomain	*clkdm;
	const struct clk_hw_omap_ops	*ops;
	u32			context;
	int			autoidle_count;
};

/*