.level 2.0
 #endif
 
+/*
+ * We need seven instructions after a TLB insert for it to take effect.
+ * The PA8800/PA8900 processors are an exception and need 12 instructions.
+ * The RFI changes both IAOQ_Back and IAOQ_Front, so it counts as one.
+ */
+#ifdef CONFIG_64BIT
+#define NUM_PIPELINE_INSNS    12
+#else
+#define NUM_PIPELINE_INSNS    7
+#endif
+
+       /* Insert num nops */
+       .macro  insert_nops num
+       .rept \num
+       nop
+       .endr
+       .endm
+
        /* Get aligned page_table_lock address for this mm from cr28/tr4 */
        .macro  get_ptl reg
        mfctl   %cr28,\reg
 3:
        .endm
 
-       /* Release page_table_lock without reloading lock address.
-          We use an ordered store to ensure all prior accesses are
-          performed prior to releasing the lock. */
-       .macro          ptl_unlock0     spc,tmp,tmp2
+       /* Release page_table_lock if for user space. We use an ordered
+          store to ensure all prior accesses are performed prior to
+          releasing the lock. Note stw may not be executed, so we
+          provide one extra nop when CONFIG_TLB_PTLOCK is defined. */
+       .macro          ptl_unlock      spc,tmp,tmp2
 #ifdef CONFIG_TLB_PTLOCK
-98:    ldi             __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
+98:    get_ptl         \tmp
+       ldi             __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
        or,COND(=)      %r0,\spc,%r0
        stw,ma          \tmp2,0(\tmp)
 99:    ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
-#endif
-       .endm
-
-       /* Release page_table_lock. */
-       .macro          ptl_unlock1     spc,tmp,tmp2
-#ifdef CONFIG_TLB_PTLOCK
-98:    get_ptl         \tmp
-       ptl_unlock0     \spc,\tmp,\tmp2
-99:    ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+       insert_nops     NUM_PIPELINE_INSNS - 4
+#else
+       insert_nops     NUM_PIPELINE_INSNS - 1
 #endif
        .endm
 
        
        idtlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        idtlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        idtlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        idtlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        mtsp            t1, %sr1        /* Restore sr1 */
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
        idtlba          pte,(va)
        idtlbp          prot,(va)
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        mtsp            t1, %sr1        /* Restore sr1 */
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
        idtlba          pte,(va)
        idtlbp          prot,(va)
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        idtlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
        
        idtlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
        
        idtlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        idtlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
        
        iitlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        iitlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        iitlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        mtsp            t1, %sr1        /* Restore sr1 */
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        mtsp            t1, %sr1        /* Restore sr1 */
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
        iitlba          pte,(%sr0, va)
        iitlbp          prot,(%sr0, va)
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
 
        iitlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        iitlbt          pte,prot
 
-       ptl_unlock1     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
 
        iitlbt          pte,prot
 
+       insert_nops     NUM_PIPELINE_INSNS - 1
        rfir
        nop
 
                
        idtlbt          pte,prot
 
-       ptl_unlock0     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 #else
 
        mtsp            t1, %sr1     /* Restore sr1 */
 
-       ptl_unlock0     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 
        
        idtlbt          pte,prot
 
-       ptl_unlock0     spc,t0,t1
+       ptl_unlock      spc,t0,t1
        rfir
        nop
 #endif