/** * We hope that PSCI framework cover the all platform specific power * states, unfortunately PSCI can support only state managed by cpuidle. * psci_suspend_customized_finisher supports extra power state which * cpuidle does not handle. This function is only for Exynos. */ static int psci_suspend_customized_finisher(unsigned long index) { u32 state; switch (index) { case PSCI_CLUSTER_SLEEP: state = psci_power_state_pack(0, 0, 1); break; case PSCI_SYSTEM_IDLE: case PSCI_SYSTEM_IDLE_AUDIO: state = psci_power_state_pack(1, 0, 0); break; case PSCI_SYSTEM_IDLE_CLUSTER_SLEEP: state = psci_power_state_pack(1, 0, 1); break; case PSCI_CP_CALL: state = psci_power_state_pack(0, 0, 2); break; case PSCI_SYSTEM_SLEEP: state = psci_power_state_pack(0, 0, 3); break; default: panic("Unsupported psci state, index = %ld\n", index); break; }; return psci_ops.cpu_suspend(state, virt_to_phys(cpu_resume)); }
static int psci_cpu_off(struct psci_power_state state) { int err; u32 fn, power_state; fn = psci_function_id[PSCI_FN_CPU_OFF]; power_state = psci_power_state_pack(state); err = invoke_psci_fn(fn, power_state, 0, 0); return psci_to_linux_errno(err); }
static int psci_cpu_suspend(struct psci_power_state state, unsigned long entry_point) { int err; u32 fn, power_state; fn = psci_function_id[PSCI_FN_CPU_SUSPEND]; power_state = psci_power_state_pack(state); err = invoke_psci_fn(fn, power_state, entry_point, 0); return psci_to_linux_errno(err); }
static int psci_cpu_off(struct psci_power_state state) { int err; u32 fn, power_state; fn = psci_function_id[PSCI_FN_CPU_OFF]; power_state = psci_power_state_pack(state); #ifdef CONFIG_MTK_FIQ_CACHE do { err = invoke_psci_fn(fn, power_state, 0, 0); } while (err); #else err = invoke_psci_fn(fn, power_state, 0, 0); #endif return psci_to_linux_errno(err); }