Unify interrupt return paths from TSP into the TSPD

The TSP is expected to pass control back to EL3 if it gets preempted due to
an interrupt while handling a Standard SMC in the following scenarios:

1. An FIQ preempts Standard SMC execution and that FIQ is not a TSP Secure
   timer interrupt or is preempted by a higher priority interrupt by the time
   the TSP acknowledges it. In this case, the TSP issues an SMC with the ID
   as `TSP_EL3_FIQ`. Currently this case is never expected to happen as only
   the TSP Secure Timer is expected to generate FIQ.

2. An IRQ preempts Standard SMC execution and in this case the TSP issues
   an SMC with the ID as `TSP_PREEMPTED`.

In both the cases, the TSPD hands control back to the normal world and returns
returns an error code to the normal world to indicate that the standard SMC it
had issued has been preempted but not completed.

This patch unifies the handling of these two cases in the TSPD and ensures that
the TSP only uses TSP_PREEMPTED instead of separate SMC IDs. Also instead of 2
separate error codes, SMC_PREEMPTED and TSP_EL3_FIQ, only SMC_PREEMPTED is
returned as error code back to the normal world.

Background information: On a GICv3 system, when the secure world has affinity
routing enabled, in 2. an FIQ will preempt TSP execution instead of an IRQ. The
FIQ could be a result of a Group 0 or a Group 1 NS interrupt. In both case, the
TSPD passes control back to the normal world upon receipt of the TSP_PREEMPTED
SMC. A Group 0 interrupt will immediately preempt execution to EL3 where it
will be handled. This allows for unified interrupt handling in TSP for both
GICv3 and GICv2 systems.

Change-Id: I9895344db74b188021e3f6a694701ad272fb40d4
diff --git a/bl32/tsp/tsp_interrupt.c b/bl32/tsp/tsp_interrupt.c
index 139642d..d5379cd 100644
--- a/bl32/tsp/tsp_interrupt.c
+++ b/bl32/tsp/tsp_interrupt.c
@@ -67,6 +67,25 @@
 #endif
 }
 
+/******************************************************************************
+ * This function is invoked when a non S-EL1 interrupt is received and causes
+ * the preemption of TSP. This function returns TSP_PREEMPTED and results
+ * in the control being handed over to EL3 for handling the interrupt.
+ *****************************************************************************/
+int32_t tsp_handle_preemption(void)
+{
+	uint32_t linear_id = plat_my_core_pos();
+
+	tsp_stats[linear_id].preempt_intr_count++;
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	spin_lock(&console_lock);
+	VERBOSE("TSP: cpu 0x%lx: %d preempt interrupt requests\n",
+		read_mpidr(), tsp_stats[linear_id].preempt_intr_count);
+	spin_unlock(&console_lock);
+#endif
+	return TSP_PREEMPTED;
+}
+
 /*******************************************************************************
  * TSP FIQ handler called as a part of both synchronous and asynchronous
  * handling of FIQ interrupts. It returns 0 upon successfully handling a S-EL1
@@ -82,16 +101,21 @@
 	 * Get the highest priority pending interrupt id and see if it is the
 	 * secure physical generic timer interrupt in which case, handle it.
 	 * Otherwise throw this interrupt at the EL3 firmware.
+	 *
+	 * There is a small time window between reading the highest priority
+	 * pending interrupt and acknowledging it during which another
+	 * interrupt of higher priority could become the highest pending
+	 * interrupt. This is not expected to happen currently for TSP.
 	 */
 	id = plat_ic_get_pending_interrupt_id();
 
 	/* TSP can only handle the secure physical timer interrupt */
 	if (id != TSP_IRQ_SEC_PHY_TIMER)
-		return TSP_EL3_FIQ;
+		return tsp_handle_preemption();
 
 	/*
-	 * Handle the interrupt. Also sanity check if it has been preempted by
-	 * another secure interrupt through an assertion.
+	 * Acknowledge and handle the secure timer interrupt. Also sanity check
+	 * if it has been preempted by another interrupt through an assertion.
 	 */
 	id = plat_ic_acknowledge_interrupt();
 	assert(id == TSP_IRQ_SEC_PHY_TIMER);
@@ -110,18 +134,3 @@
 #endif
 	return 0;
 }
-
-int32_t tsp_irq_received(void)
-{
-	uint32_t linear_id = plat_my_core_pos();
-
-	tsp_stats[linear_id].irq_count++;
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
-	spin_lock(&console_lock);
-	VERBOSE("TSP: cpu 0x%lx received irq\n", read_mpidr());
-	VERBOSE("TSP: cpu 0x%lx: %d irq requests\n",
-		read_mpidr(), tsp_stats[linear_id].irq_count);
-	spin_unlock(&console_lock);
-#endif
-	return TSP_PREEMPTED;
-}