{
        struct arm_smccc_res res;
        int count_in_sec;
+       unsigned long a0, a1, a2;
 
        cb_data->kaddr1 = NULL;
        cb_data->kaddr2 = NULL;
 
        pr_debug("%s: polling config status\n", __func__);
 
+       a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
+       a1 = (unsigned long)p_data->paddr;
+       a2 = (unsigned long)p_data->size;
+
+       if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
+               a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+
        count_in_sec = FPGA_CONFIG_STATUS_TIMEOUT_SEC;
        while (count_in_sec) {
-               ctrl->invoke_fn(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE,
-                               0, 0, 0, 0, 0, 0, 0, &res);
+               ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
                if ((res.a0 == INTEL_SIP_SMC_STATUS_OK) ||
-                   (res.a0 == INTEL_SIP_SMC_STATUS_ERROR))
+                   (res.a0 == INTEL_SIP_SMC_STATUS_ERROR) ||
+                   (res.a0 == INTEL_SIP_SMC_STATUS_REJECTED))
                        break;
 
                /*
-                * configuration is still in progress, wait one second then
+                * request is still in progress, wait one second then
                 * poll again
                 */
                msleep(1000);
                count_in_sec--;
        }
 
-       if (res.a0 == INTEL_SIP_SMC_STATUS_OK && count_in_sec)
+       if (!count_in_sec) {
+               pr_err("%s: poll status timeout\n", __func__);
+               cb_data->status = BIT(SVC_STATUS_BUSY);
+       } else if (res.a0 == INTEL_SIP_SMC_STATUS_OK) {
                cb_data->status = BIT(SVC_STATUS_COMPLETED);
+               cb_data->kaddr2 = (res.a2) ?
+                                 svc_pa_to_va(res.a2) : NULL;
+               cb_data->kaddr3 = (res.a3) ? &res.a3 : NULL;
+       } else {
+               pr_err("%s: poll status error\n", __func__);
+               cb_data->kaddr1 = &res.a1;
+               cb_data->kaddr2 = (res.a2) ?
+                                 svc_pa_to_va(res.a2) : NULL;
+               cb_data->kaddr3 = (res.a3) ? &res.a3 : NULL;
+               cb_data->status = BIT(SVC_STATUS_ERROR);
+       }
 
        p_data->chan->scl->receive_cb(p_data->chan->scl, cb_data);
 }
        case COMMAND_RECONFIG:
        case COMMAND_RSU_UPDATE:
        case COMMAND_RSU_NOTIFY:
+       case COMMAND_POLL_SERVICE_STATUS:
                cb_data->status = BIT(SVC_STATUS_OK);
                break;
        case COMMAND_RECONFIG_DATA_SUBMIT:
                        a1 = 0;
                        a2 = 0;
                        break;
+               /* for polling */
+               case COMMAND_POLL_SERVICE_STATUS:
+                       a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+                       a1 = (unsigned long)pdata->paddr;
+                       a2 = (unsigned long)pdata->size;
+
+                       break;
+
                default:
                        pr_warn("it shouldn't happen\n");
                        break;
                                                          pdata, cbdata);
                                break;
                        case COMMAND_RECONFIG_STATUS:
+                       case COMMAND_POLL_SERVICE_STATUS:
                                svc_thread_cmd_config_status(ctrl,
                                                             pdata, cbdata);
                                break;
 
 #define INTEL_SIP_SMC_RSU_MAX_RETRY \
        INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY)
 
+/**
+ * Request INTEL_SIP_SMC_SERVICE_COMPLETED
+ * Sync call to check if the secure world have completed service request
+ * or not.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_SERVICE_COMPLETED
+ * a1: this register is optional. If used, it is the physical address for
+ *     secure firmware to put output data
+ * a2: this register is optional. If used, it is the size of output data
+ * a3-a7: not used
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_ERROR,
+ *     INTEL_SIP_SMC_REJECTED or INTEL_SIP_SMC_STATUS_BUSY
+ * a1: mailbox error if a0 is INTEL_SIP_SMC_STATUS_ERROR
+ * a2: physical address containing the process info
+ *     for FCS certificate -- the data contains the certificate status
+ *     for FCS cryption -- the data contains the actual data size FW processes
+ * a3: output data size
+ */
+#define INTEL_SIP_SMC_FUNCID_SERVICE_COMPLETED 30
+#define INTEL_SIP_SMC_SERVICE_COMPLETED \
+       INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_SERVICE_COMPLETED)
+
 /**
  * Request INTEL_SIP_SMC_FIRMWARE_VERSION
  *
 
  * @COMMAND_RSU_DCMF_VERSION: query firmware for the DCMF version, return status
  * is SVC_STATUS_OK or SVC_STATUS_ERROR
  *
+ * @COMMAND_POLL_SERVICE_STATUS: poll if the service request is complete,
+ * return statis is SVC_STATUS_OK, SVC_STATUS_ERROR or SVC_STATUS_BUSY
+ *
  * @COMMAND_FIRMWARE_VERSION: query running firmware version, return status
  * is SVC_STATUS_OK or SVC_STATUS_ERROR
  */
        COMMAND_RSU_MAX_RETRY,
        COMMAND_RSU_DCMF_VERSION,
        COMMAND_FIRMWARE_VERSION,
+       /* for general status poll */
+       COMMAND_POLL_SERVICE_STATUS = 40,
 };
 
 /**