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;
}