int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel) { uint32_t timeout_us; if (!dev) return -EINVAL; if (msm_spm_debug_mask & MSM_SPM_DEBUG_VCTL) pr_info("%s: requesting vlevel 0x%x\n", __func__, vlevel); msm_spm_drv_set_vctl(dev, vlevel); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_VCTL); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_0); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_1); mb(); /* Wait for PMIC state to return to idle or until timeout */ timeout_us = dev->vctl_timeout_us; msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS0); while (msm_spm_drv_get_sts_pmic_state(dev) != MSM_SPM_PMIC_STATE_IDLE) { if (!timeout_us) goto set_vdd_bail; if (timeout_us > 10) { udelay(10); timeout_us -= 10; } else { udelay(timeout_us); timeout_us = 0; } msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS0); } msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS1); if (msm_spm_drv_get_sts_curr_pmic_data(dev) != vlevel) goto set_vdd_bail; if (msm_spm_debug_mask & MSM_SPM_DEBUG_VCTL) pr_info("%s: done, remaining timeout %uus\n", __func__, timeout_us); return 0; set_vdd_bail: pr_err("%s: failed, remaining timeout %uus, vlevel 0x%x\n", __func__, timeout_us, msm_spm_drv_get_sts_curr_pmic_data(dev)); return -EIO; }
unsigned int msm_spm_get_vdd(unsigned int cpu) { struct msm_spm_device *dev; dev = &per_cpu(msm_cpu_spm_device, cpu); return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data); }