/** * sr_class1p5_voltdm_recal() - Helper routine to reset calibration. * @voltdm: Voltage domain to reset calibration for * @user: unused * * NOTE: Appropriate locks must be held by calling path to ensure mutual * exclusivity */ static int sr_class1p5_voltdm_recal(struct voltagedomain *voltdm, void *user) { struct omap_volt_data *vdata; /* * we need to go no further if sr is not enabled for this domain or * voltage processor is not present for this voltage domain * (example vdd_wakeup). Class 1.5 requires Voltage processor * to function. */ if (!voltdm->vp || !is_sr_enabled(voltdm)) return 0; vdata = omap_voltage_get_curr_vdata(voltdm); if (!vdata) { pr_err("%s: unable to find current voltage for vdd_%s\n", __func__, voltdm->name); return -ENXIO; } omap_sr_disable(voltdm); omap_voltage_calib_reset(voltdm); voltdm_reset(voltdm); omap_sr_enable(voltdm, vdata); pr_info("%s: %s: calibration reset\n", __func__, voltdm->name); return 0; }
/** * sr_class1p5_reset_calib() - reset all calibrated voltages * @voltdm: configure for which voltage domain * @reset: reset voltage before we recal? * @recal: should I recalibrate my current opp? * * if we call this, it means either periodic calibration trigger was * fired(either from sysfs or other mechanisms) or we have disabled class 1p5, * meaning we cant trust the calib voltages anymore, it is better to use * nominal in the system */ static void sr_class1p5_reset_calib(struct voltagedomain *voltdm, bool reset, bool recal) { struct sr_class1p5_work_data *work_data; /* I dont need to go further if sr is not present */ if (!is_sr_enabled(voltdm)) return; work_data = get_sr1p5_work(voltdm); if (work_data->work_active) sr_class1p5_disable(voltdm, work_data->vdata, 0); omap_voltage_calib_reset(voltdm); /* * I should now reset the voltages to my nominal to be safe */ if (reset) omap_voltage_reset(voltdm); /* * I should fire a recalibration for current opp if needed * Note: i have just reset my calibrated voltages, and if * i call sr_enable equivalent, I will cause a recalibration * loop, even though the function is called sr_enable.. we * are in class 1.5 ;) */ if (reset && recal) sr_class1p5_enable(voltdm, work_data->vdata); }
/** * sr_classp5_deinit() - class p5 deinitialization * @sr: SR to deinit * @class_priv_data: class private data for deinitialiation (unused) * * currently only resets the calibrated voltage forcing DVFS voltages * to be used in the system * * NOTE: Appropriate locks must be held by calling path to ensure mutual * exclusivity */ static int sr_classp5_deinit(struct omap_sr *sr, void *class_priv_data) { struct voltagedomain *voltdm = NULL; void **voltdm_cdata = NULL; struct sr_classp5_calib_data *work_data = NULL; if (IS_ERR_OR_NULL(sr) || IS_ERR_OR_NULL(sr->voltdm)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } voltdm = sr->voltdm; voltdm_cdata = &sr->voltdm_cdata; if (IS_ERR_OR_NULL(*voltdm_cdata)) { pr_err("%s: ooopps.. class not initialized for %s! bug??\n", __func__, voltdm->name); return -EINVAL; } work_data = (struct sr_classp5_calib_data *)*voltdm_cdata; /* * we dont have SR periodic calib anymore.. so reset calibs * we are already protected by appropriate locks, so no lock needed * here. */ if (work_data->work_active) sr_classp5_disable(sr, 0); /* Ensure worker canceled. */ cancel_delayed_work_sync(&work_data->work); omap_voltage_calib_reset(voltdm); voltdm_reset(voltdm); pm_qos_remove_request(&work_data->qos); kfree(work_data); *voltdm_cdata = NULL; return 0; }