/*
 * For optimization reasons, assumes no downstream clocks are actively using
 * it.
 */
static int variable_rate_pll_set_rate(struct clk *c, unsigned long rate)
{
	struct pll_clk *pll = to_pll_clk(c);
	unsigned long flags;
	u32 l_val;

	if (rate != variable_rate_pll_round_rate(c, rate))
		return -EINVAL;

	l_val = rate / pll->src_rate;

	spin_lock_irqsave(&c->lock, flags);

	if (c->count)
		c->ops->disable(c);

	writel_relaxed(l_val, PLL_L_REG(pll));

	if (c->count)
		c->ops->enable(c);

	spin_unlock_irqrestore(&c->lock, flags);

	return 0;
}
/*
 * For optimization reasons, assumes no downstream clocks are actively using
 * it.
 */
static int variable_rate_pll_set_rate(struct clk *c, unsigned long rate)
{
	struct pll_clk *pll = to_pll_clk(c);
	unsigned long flags;
	u32 l_val, regval;

	if (rate != variable_rate_pll_round_rate(c, rate))
		return -EINVAL;

	l_val = rate / pll->src_rate;

	spin_lock_irqsave(&c->lock, flags);

	if (c->count)
		c->ops->disable(c);

	/* Set any vco data if present */
	if (pll->data.vco_val) {
		regval = readl_relaxed(PLL_CONFIG_REG(pll));
		if ((rate >= pll->data.min_freq) &&
				(rate <= pll->data.max_freq)) {
			regval |= pll->data.vco_val;
			writel_relaxed(pll->data.config_ctl_val,
					PLL_CFG_CTL_REG(pll));
		} else {
			regval &= ~pll->data.vco_val;
			writel_relaxed(pll->vals.config_ctl_val,
					PLL_CFG_CTL_REG(pll));
		}

		writel_relaxed(regval, PLL_CONFIG_REG(pll));
	}

	writel_relaxed(l_val, PLL_L_REG(pll));

	if (c->count)
		c->ops->enable(c);

	spin_unlock_irqrestore(&c->lock, flags);

	return 0;
}