static int div_set_rate(struct clk *c, unsigned long rate)
{
	struct div_clk *d = to_div_clk(c);
	int safe_div, div, rc = 0;
	long rrate, old_prate, new_prate;
	struct div_data *data = &d->data;

	rrate = __div_round_rate(data, rate, c->parent, &div, &new_prate);
	if (rrate != rate)
		return -EINVAL;


	safe_div = _find_safe_div(c, rate);
	if (d->safe_freq && safe_div < 0) {
		pr_err("No safe div on %s for transitioning from %lu to %lu\n",
			c->dbg_name, c->rate, rate);
		return -EINVAL;
	}

	safe_div = max(safe_div, div);

	if (safe_div > data->div) {
		rc = d->ops->set_div(d, safe_div);
		if (rc) {
			pr_err("Failed to set div %d on %s\n", safe_div,
				c->dbg_name);
			return rc;
		}
	}

	old_prate = clk_get_rate(c->parent);
	rc = clk_set_rate(c->parent, new_prate);
	if (rc)
		goto set_rate_fail;

	if (div < data->div)
		rc = d->ops->set_div(d, div);
	else if (div < safe_div)
		rc = d->ops->set_div(d, div);
	if (rc)
		goto div_dec_fail;

	data->div = div;

	return 0;

div_dec_fail:
	WARN(clk_set_rate(c->parent, old_prate),
		"Set rate failed for %s. Also in bad state!\n", c->dbg_name);
set_rate_fail:
	if (safe_div > data->div)
		WARN(d->ops->set_div(d, data->div),
			"Set rate failed for %s. Also in bad state!\n",
			c->dbg_name);
	return rc;
}
static int div_set_rate(struct clk *c, unsigned long rate)
{
	struct div_clk *d = to_div_clk(c);
	int safe_div, div, rc = 0;
	long rrate, old_prate, new_prate;
	struct div_data *data = &d->data;

	rrate = __div_round_rate(data, rate, c->parent, &div, &new_prate);
	if (rrate != rate)
		return -EINVAL;

	/*
	 * For fixed divider clock we don't want to return an error if the
	 * requested rate matches the achievable rate. So, don't check for
	 * !d->ops and return an error. __div_round_rate() ensures div ==
	 * d->div if !d->ops.
	 */

	safe_div = _find_safe_div(c, rate);
	if (d->safe_freq && safe_div < 0) {
		pr_err("No safe div on %s for transitioning from %lu to %lu\n",
			c->dbg_name, c->rate, rate);
		return -EINVAL;
	}

	safe_div = max(safe_div, div);

	if (safe_div > data->div) {
		rc = d->ops->set_div(d, safe_div);
		if (rc) {
			pr_err("Failed to set div %d on %s\n", safe_div,
				c->dbg_name);
			return rc;
		}
	}

	old_prate = clk_get_rate(c->parent);
	rc = clk_set_rate(c->parent, new_prate);
	if (rc)
		goto set_rate_fail;

	if (div < data->div)
		rc = d->ops->set_div(d, div);
	else if (div < safe_div)
		rc = d->ops->set_div(d, div);
	if (rc)
		goto div_dec_fail;

	data->div = div;

	return 0;

div_dec_fail:
	WARN(clk_set_rate(c->parent, old_prate),
		"Set rate failed for %s. Also in bad state!\n", c->dbg_name);
set_rate_fail:
	if (safe_div > data->div)
		WARN(d->ops->set_div(d, data->div),
			"Set rate failed for %s. Also in bad state!\n",
			c->dbg_name);
	return rc;
}