int psci_cpu_suspend(unsigned int power_state, unsigned long entrypoint, unsigned long context_id) { int rc; unsigned long mpidr; unsigned int target_afflvl, pstate_type; /* TODO: Standby states are not supported at the moment */ pstate_type = psci_get_pstate_type(power_state); if (pstate_type == 0) { rc = PSCI_E_INVALID_PARAMS; goto exit; } /* Sanity check the requested state */ target_afflvl = psci_get_pstate_afflvl(power_state); if (target_afflvl > MPIDR_MAX_AFFLVL) { rc = PSCI_E_INVALID_PARAMS; goto exit; } mpidr = read_mpidr(); rc = psci_afflvl_suspend(mpidr, entrypoint, context_id, power_state, MPIDR_AFFLVL0, target_afflvl); exit: if (rc != PSCI_E_SUCCESS) assert(rc == PSCI_E_INVALID_PARAMS); return rc; }
int psci_cpu_suspend(unsigned int power_state, unsigned long entrypoint, unsigned long context_id) { int rc; unsigned long mpidr; unsigned int target_afflvl, pstate_type; /* Sanity check the requested state */ target_afflvl = psci_get_pstate_afflvl(power_state); if (target_afflvl > MPIDR_MAX_AFFLVL) return PSCI_E_INVALID_PARAMS; pstate_type = psci_get_pstate_type(power_state); if (pstate_type == PSTATE_TYPE_STANDBY) { if (psci_plat_pm_ops->affinst_standby) rc = psci_plat_pm_ops->affinst_standby(power_state); else return PSCI_E_INVALID_PARAMS; } else { mpidr = read_mpidr(); rc = psci_afflvl_suspend(mpidr, entrypoint, context_id, power_state, MPIDR_AFFLVL0, target_afflvl); } assert(rc == PSCI_E_INVALID_PARAMS || rc == PSCI_E_SUCCESS); return rc; }
/******************************************************************************* * This function gets the affinity level till which the current cpu could be * powered down during a cpu_suspend call. Returns PSCI_INVALID_DATA if the * power state is invalid. ******************************************************************************/ int psci_get_suspend_afflvl() { unsigned int power_state; power_state = get_cpu_data(psci_svc_cpu_data.power_state); return ((power_state == PSCI_INVALID_DATA) ? power_state : psci_get_pstate_afflvl(power_state)); }
/******************************************************************************* * MTK_platform handler called when an affinity instance is about to enter standby. ******************************************************************************/ int mt_affinst_standby(unsigned int power_state) { unsigned int target_afflvl; /* Sanity check the requested state */ target_afflvl = psci_get_pstate_afflvl(power_state); /* * It's possible to enter standby only on affinity level 0 i.e. a cpu * on the MTK_platform. Ignore any other affinity level. */ if (target_afflvl != MPIDR_AFFLVL0) return PSCI_E_INVALID_PARAMS; /* * Enter standby state * dsb is good practice before using wfi to enter low power states */ dsb(); wfi(); return PSCI_E_SUCCESS; }