& PSCI_0_2_POWER_STATE_AFFL_MASK);
}
+/**
+ * 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));
+}
+
int psci_cpu_suspend_enter(unsigned long index)
{
int ret;
if (WARN_ON_ONCE(!index))
return -EINVAL;
+ if (unlikely(index >= PSCI_UNUSED_INDEX))
+ return cpu_suspend(index, psci_suspend_customized_finisher);
+
if (!psci_power_state_loses_context(state[index - 1]))
ret = psci_ops.cpu_suspend(state[index - 1], 0);
else
#include <linux/init.h>
#include <linux/types.h>
+#define PSCI_UNUSED_INDEX 128
+#define PSCI_CLUSTER_SLEEP (PSCI_UNUSED_INDEX)
+#define PSCI_SYSTEM_IDLE (PSCI_UNUSED_INDEX + 1)
+#define PSCI_SYSTEM_IDLE_CLUSTER_SLEEP (PSCI_UNUSED_INDEX + 2)
+#define PSCI_SYSTEM_IDLE_AUDIO (PSCI_UNUSED_INDEX + 3)
+#define PSCI_CP_CALL (PSCI_UNUSED_INDEX + 4)
+#define PSCI_SYSTEM_SLEEP (PSCI_UNUSED_INDEX + 5)
+
#define PSCI_POWER_STATE_TYPE_STANDBY 0
#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1