static int qfprom_enable_fuse_blowing()

in qfprom.c [184:244]


static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
				      struct qfprom_touched_values *old)
{
	int ret;
	int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV;

	ret = clk_prepare_enable(priv->secclk);
	if (ret) {
		dev_err(priv->dev, "Failed to enable clock\n");
		return ret;
	}

	old->clk_rate = clk_get_rate(priv->secclk);
	ret = clk_set_rate(priv->secclk, priv->soc_data->qfprom_blow_set_freq);
	if (ret) {
		dev_err(priv->dev, "Failed to set clock rate for enable\n");
		goto err_clk_prepared;
	}

	/*
	 * Hardware requires a minimum voltage for fuse blowing.
	 * This may be a shared rail so don't specify a maximum.
	 * Regulator constraints will cap to the actual maximum.
	 */
	ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
	if (ret) {
		dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV);
		goto err_clk_rate_set;
	}

	ret = regulator_enable(priv->vcc);
	if (ret) {
		dev_err(priv->dev, "Failed to enable regulator\n");
		goto err_clk_rate_set;
	}

	ret = pm_runtime_get_sync(priv->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(priv->dev);
		dev_err(priv->dev, "Failed to enable power-domain\n");
		goto err_reg_enable;
	}
	dev_pm_genpd_set_performance_state(priv->dev, INT_MAX);

	old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
	old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
	writel(priv->soc_data->qfprom_blow_timer_value,
	       priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
	writel(priv->soc_data->accel_value,
	       priv->qfpconf + QFPROM_ACCEL_OFFSET);

	return 0;

err_reg_enable:
	regulator_disable(priv->vcc);
err_clk_rate_set:
	clk_set_rate(priv->secclk, old->clk_rate);
err_clk_prepared:
	clk_disable_unprepare(priv->secclk);
	return ret;
}