: : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
 }
 
+static inline void _ppc_msgclr(u32 msg)
+{
+       __asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGCLR(%1), PPC_MSGCLRP(%1), %0)
+                               : : "i" (CPU_FTR_HVMODE), "r" (msg));
+}
+
+static inline void ppc_msgclr(enum ppc_dbell type)
+{
+       u32 msg = PPC_DBELL_TYPE(type);
+
+       _ppc_msgclr(msg);
+}
+
 #else /* CONFIG_PPC_BOOK3S */
 
 #define PPC_DBELL_MSGTYPE              PPC_DBELL
 
 #define PPC_INST_MSGCLR                        0x7c0001dc
 #define PPC_INST_MSGSYNC               0x7c0006ec
 #define PPC_INST_MSGSNDP               0x7c00011c
+#define PPC_INST_MSGCLRP               0x7c00015c
 #define PPC_INST_MTTMR                 0x7c0003dc
 #define PPC_INST_NOP                   0x60000000
 #define PPC_INST_PASTE                 0x7c20070d
                                        ___PPC_RB(b))
 #define PPC_MSGSNDP(b)         stringify_in_c(.long PPC_INST_MSGSNDP | \
                                        ___PPC_RB(b))
+#define PPC_MSGCLRP(b)         stringify_in_c(.long PPC_INST_MSGCLRP | \
+                                       ___PPC_RB(b))
 #define PPC_POPCNTB(a, s)      stringify_in_c(.long PPC_INST_POPCNTB | \
                                        __PPC_RA(a) | __PPC_RS(s))
 #define PPC_POPCNTD(a, s)      stringify_in_c(.long PPC_INST_POPCNTD | \
 
 #endif
 
        DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
+       DEFINE(PPC_DBELL_MSGTYPE, PPC_DBELL_MSGTYPE);
 
 #ifdef CONFIG_PPC_8xx
        DEFINE(VIRT_IMMR_BASE, (u64)__fix_to_virt(FIX_IMMR_BASE));
 
        bl      kernel_bad_stack
        b       1b
 
+/*
+ * When doorbell is triggered from system reset wakeup, the message is
+ * not cleared, so it would fire again when EE is enabled.
+ *
+ * When coming from local_irq_enable, there may be the same problem if
+ * we were hard disabled.
+ *
+ * Execute msgclr to clear pending exceptions before handling it.
+ */
+h_doorbell_common_msgclr:
+       LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36))
+       PPC_MSGCLR(3)
+       b       h_doorbell_common
+
+doorbell_super_common_msgclr:
+       LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36))
+       PPC_MSGCLRP(3)
+       b       doorbell_super_common
+
 /*
  * Called from arch_local_irq_enable when an interrupt needs
  * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
        beq     hardware_interrupt_common
 BEGIN_FTR_SECTION
        cmpwi   r3,0xe80
-       beq     h_doorbell_common
+       beq     h_doorbell_common_msgclr
        cmpwi   r3,0xea0
        beq     h_virt_irq_common
        cmpwi   r3,0xe60
        beq     hmi_exception_common
 FTR_SECTION_ELSE
        cmpwi   r3,0xa00
-       beq     doorbell_super_common
+       beq     doorbell_super_common_msgclr
 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
        blr