fix(xilinx): handle CRC failure in IPI callback

Currently, if CRC validation fails during IPI communication,
pm_ipi_buff_read_callb() logs error message but don't return
error code to upper layers.

Added CRC failure specific error code which will be returned by
pm_ipi_buff_read_callb() if CRC validation fails.

Signed-off-by: Naman Trivedi Manojbhai <naman.trivedimanojbhai@amd.com>
Change-Id: I2eaca073e2bf325a8c86b1820bdd7cca487b783e
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index db9fae4..cc99f11 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -196,19 +196,23 @@
  *        1 - Ack IPI after reading payload
  *
  * Read value from ipi buffer response buffer.
+ * @return	Returns status, either success or error
  */
-void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
+enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
 {
+	enum pm_ret_status ret = PM_RET_SUCCESS;
 	/* Return if interrupt is not from PMU */
 	if (pm_ipi_irq_status(primary_proc) == 0) {
-		return;
+		return ret;
 	}
 
-	pm_ipi_buff_read_callb(data, count);
+	ret = pm_ipi_buff_read_callb(data, count);
 
 	if (ack != 0U) {
 		pm_ipi_irq_clear(primary_proc);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index c539aa7..8625e95 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -38,7 +38,7 @@
 				 uintptr_t address, uint8_t ack, uint32_t flag);
 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
 					uint8_t enable, uint32_t flag);
-void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag,
+enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag,
 			 uint32_t ack);
 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
 				    uint32_t value, uint32_t flag);
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index c90f9e1..185bfdb 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -48,12 +48,17 @@
 				void *cookie)
 {
 	uint32_t payload[4] = {0};
+	enum pm_ret_status ret;
 
 	VERBOSE("Received IPI FIQ from firmware\n");
 
 	(void)plat_ic_acknowledge_interrupt();
 
+	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
+	if (ret != PM_RET_SUCCESS) {
+		payload[0] = ret;
+	}
+
-	pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
 	switch (payload[0]) {
 	case PM_INIT_SUSPEND_CB:
 	case PM_NOTIFY_CB:
@@ -61,6 +66,11 @@
 			notify_os();
 		}
 		break;
+	case PM_RET_ERROR_INVALID_CRC:
+		pm_ipi_irq_clear(primary_proc);
+		WARN("Invalid CRC in the payload\n");
+		break;
+
 	default:
 		pm_ipi_irq_clear(primary_proc);
 		WARN("Invalid IPI payload\n");
@@ -274,8 +284,13 @@
 	case PM_GET_CALLBACK_DATA:
 	{
 		uint32_t result[4] = {0};
+		enum pm_ret_status ret;
+
+		ret = pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
+		if (ret != 0) {
+			result[0] = ret;
+		}
 
-		pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
 		SMC_RET2(handle,
 			(uint64_t)result[0] | ((uint64_t)result[1] << 32U),
 			(uint64_t)result[2] | ((uint64_t)result[3] << 32U));