Add power management support in the SPD

This patch implements a set of handlers in the SPD which are called by
the PSCI runtime service upon receiving a power management
operation. These handlers in turn pass control to the Secure Payload
image if required before returning control to PSCI. This ensures that
the Secure Payload has complete visibility of all power transitions in
the system and can prepare accordingly.

Change-Id: I2d1dba5629b7cf2d53999d39fe807dfcf3f62fe2
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index 6896379..15b3922 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -129,7 +129,10 @@
 		      CTX_GPREG_X0,
 		      (uint64_t) bl32_meminfo);
 
-	/* Arrange for an entry into the secure payload */
+	/*
+	 * Arrange for an entry into the test secure payload. We expect an array
+	 * of vectors in return
+	 */
 	rc = tspd_synchronous_sp_entry(tsp_ctx);
 	assert(rc != 0);
 	if (rc)
@@ -189,11 +192,46 @@
 		/* Should never reach here */
 		assert(0);
 
+	/*
+	 * These function IDs is used only by the SP to indicate it has
+	 * finished:
+	 * 1. turning itself on in response to an earlier psci
+	 *    cpu_on request
+	 * 2. resuming itself after an earlier psci cpu_suspend
+	 *    request.
+	 */
+	case TSP_ON_DONE:
+	case TSP_RESUME_DONE:
+
+	/*
+	 * These function IDs is used only by the SP to indicate it has
+	 * finished:
+	 * 1. suspending itself after an earlier psci cpu_suspend
+	 *    request.
+	 * 2. turning itself off in response to an earlier psci
+	 *    cpu_off request.
+	 */
+	case TSP_OFF_DONE:
+	case TSP_SUSPEND_DONE:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		/*
+		 * SP reports completion. The SPD must have initiated the
+		 * original request through a synchronous entry into the SP.
+		 * Jump back to the original C runtime context, and pass x1 as
+		 * return value to the caller
+		 */
+		tspd_synchronous_sp_exit(&tspd_sp_context[linear_id], x1);
+
+		/* Should never reach here */
+		assert(0);
+
 	default:
-		panic();
+		break;
 	}
 
-	SMC_RET1(handle, 0);
+	SMC_RET1(handle, SMC_UNK);
 }
 
 /* Define a SPD runtime service descriptor */