};
 
 #define CC_NUM_IDRS 4
+#define CC_HW_RESET_LOOP_COUNT 10
 
 /* Note: PIDR3 holds CMOD/Rev so ignored for HW identification purposes */
 static const u32 pidr_0124_offsets[CC_NUM_IDRS] = {
        return IRQ_HANDLED;
 }
 
+bool cc_wait_for_reset_completion(struct cc_drvdata *drvdata)
+{
+       unsigned int val;
+       unsigned int i;
+
+       /* 712/710/63 has no reset completion indication, always return true */
+       if (drvdata->hw_rev <= CC_HW_REV_712)
+               return true;
+
+       for (i = 0; i < CC_HW_RESET_LOOP_COUNT; i++) {
+               /* in cc7x3 NVM_IS_IDLE indicates that CC reset is
+                *  completed and device is fully functional
+                */
+               val = cc_ioread(drvdata, CC_REG(NVM_IS_IDLE));
+               if (val & CC_NVM_IS_IDLE_MASK) {
+                       /* hw indicate reset completed */
+                       return true;
+               }
+               /* allow scheduling other process on the processor */
+               schedule();
+       }
+       /* reset not completed */
+       return false;
+}
+
 int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe)
 {
        unsigned int val, cache_params;
 
        new_drvdata->sec_disabled = cc_sec_disable;
 
+       /* wait for Crytpcell reset completion */
+       if (!cc_wait_for_reset_completion(new_drvdata)) {
+               dev_err(dev, "Cryptocell reset not completed");
+       }
+
        if (hw_rev->rev <= CC_HW_REV_712) {
                /* Verify correct mapping */
                val = cc_ioread(new_drvdata, new_drvdata->sig_offset);
        if (rc) {
                dev_err(dev, "Could not register to interrupt %d\n",
                        new_drvdata->irq);
-               return rc;
+               goto post_clk_err;
        }
        dev_dbg(dev, "Registered to IRQ: %d\n", new_drvdata->irq);
 
 
 
 #define CC_SECURITY_DISABLED_MASK BIT(CC_SECURITY_DISABLED_VALUE_BIT_SHIFT)
 
+#define CC_NVM_IS_IDLE_MASK BIT(CC_NVM_IS_IDLE_VALUE_BIT_SHIFT)
+
 #define AXIM_MON_COMP_VALUE GENMASK(CC_AXIM_MON_COMP_VALUE_BIT_SIZE + \
                                    CC_AXIM_MON_COMP_VALUE_BIT_SHIFT, \
                                    CC_AXIM_MON_COMP_VALUE_BIT_SHIFT)
                __dump_byte_array(name, the_array, size);
 }
 
+bool cc_wait_for_reset_completion(struct cc_drvdata *drvdata);
 int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe);
 void fini_cc_regs(struct cc_drvdata *drvdata);
 int cc_clk_on(struct cc_drvdata *drvdata);
 
 #define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SIZE    0x1UL
 #define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SHIFT      0x17UL
 #define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SIZE       0x1UL
+#define CC_NVM_IS_IDLE_REG_OFFSET       0x0A10UL
+#define CC_NVM_IS_IDLE_VALUE_BIT_SHIFT  0x0UL
+#define CC_NVM_IS_IDLE_VALUE_BIT_SIZE   0x1UL
 #define CC_SECURITY_DISABLED_REG_OFFSET                0x0A1CUL
 #define CC_SECURITY_DISABLED_VALUE_BIT_SHIFT   0x0UL
 #define CC_SECURITY_DISABLED_VALUE_BIT_SIZE    0x1UL
 
                dev_err(dev, "failed getting clock back on. We're toast.\n");
                return rc;
        }
+       /* wait for Crytpcell reset completion */
+       if (!cc_wait_for_reset_completion(drvdata)) {
+               dev_err(dev, "Cryptocell reset not completed");
+               return -EBUSY;
+       }
 
        cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE);
        rc = init_cc_regs(drvdata, false);