示例#1
0
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	if (!pll_clk_is_enabled(c))
		return HANDOFF_DISABLED_CLK;

	remote_spin_lock(&pll_lock);
	pll_control->pll[PLL_BASE + pll->id].votes |= BIT(1);
	pll_control->pll[PLL_BASE + pll->id].on = 1;
	remote_spin_unlock(&pll_lock);

	return HANDOFF_ENABLED_CLK;
}
static void pll_clk_disable(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_id = pll->id;

	remote_spin_lock(&pll_lock);

	pll_control->pll[PLL_BASE + pll_id].votes &= ~BIT(1);
	if (pll_control->pll[PLL_BASE + pll_id].on
	    && !pll_control->pll[PLL_BASE + pll_id].votes) {
		__pll_clk_disable_reg(PLL_MODE_REG(pll));
		pll_control->pll[PLL_BASE + pll_id].on = 0;
	}

	remote_spin_unlock(&pll_lock);
}
static int pll_clk_enable(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_id = pll->id;

	remote_spin_lock(&pll_lock);

	pll_control->pll[PLL_BASE + pll_id].votes |= BIT(1);
	if (!pll_control->pll[PLL_BASE + pll_id].on) {
		__pll_clk_enable_reg(PLL_MODE_REG(pll));
		pll_control->pll[PLL_BASE + pll_id].on = 1;
	}

	remote_spin_unlock(&pll_lock);
	return 0;
}
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	/*
	 * Wait for the PLLs to be initialized and then read their frequency.
	 */
	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	/* Convert PLL L values to PLL Output rate */
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	if (!pll_clk_is_enabled(c))
		return HANDOFF_DISABLED_CLK;

	/*
	 * Do not call pll_clk_enable() since that function can assume
	 * the PLL is not in use when it's called.
	 */
	remote_spin_lock(&pll_lock);
	pll_control->pll[PLL_BASE + pll->id].votes |= BIT(1);
	pll_control->pll[PLL_BASE + pll->id].on = 1;
	remote_spin_unlock(&pll_lock);

	return HANDOFF_ENABLED_CLK;
}