sub     \tmp, \tmp, #1                  @ decrement it
        str     \tmp, [\ti, #TI_PREEMPT]
        .endm
-
-       .macro  dec_preempt_count_ti, ti, tmp
-       get_thread_info \ti
-       dec_preempt_count \ti, \tmp
-       .endm
 #else
        .macro  inc_preempt_count, ti, tmp
        .endm
 
        .macro  dec_preempt_count, ti, tmp
        .endm
+#endif
+
+       .macro  local_bh_disable, ti, tmp
+       ldr     \tmp, [\ti, #TI_PREEMPT]
+       add     \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
+       str     \tmp, [\ti, #TI_PREEMPT]
+       .endm
 
-       .macro  dec_preempt_count_ti, ti, tmp
+       .macro  local_bh_enable_ti, ti, tmp
+       get_thread_info \ti
+       ldr     \tmp, [\ti, #TI_PREEMPT]
+       sub     \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
+       str     \tmp, [\ti, #TI_PREEMPT]
        .endm
-#endif
 
 #define USERL(l, x...)                         \
 9999:  x;                                      \
 
   DEFINE(VFP_CPU,              offsetof(union vfp_state, hard.cpu));
 #endif
 #endif
+  DEFINE(SOFTIRQ_DISABLE_OFFSET,SOFTIRQ_DISABLE_OFFSET);
 #ifdef CONFIG_ARM_THUMBEE
   DEFINE(TI_THUMBEE_STATE,     offsetof(struct thread_info, thumbee_state));
 #endif
 
 @  IRQs enabled.
 @
 ENTRY(do_vfp)
-       inc_preempt_count r10, r4
+       local_bh_disable r10, r4
        ldr     r4, .LCvfp
        ldr     r11, [r10, #TI_CPU]     @ CPU number
        add     r10, r10, #TI_VFPSTATE  @ r10 = workspace
 ENDPROC(do_vfp)
 
 ENTRY(vfp_null_entry)
-       dec_preempt_count_ti r10, r4
+       local_bh_enable_ti r10, r4
        ret     lr
 ENDPROC(vfp_null_entry)
 
 
                                        @ else it's one 32-bit instruction, so
                                        @ always subtract 4 from the following
                                        @ instruction address.
-       dec_preempt_count_ti r10, r4
+       local_bh_enable_ti r10, r4
        ret     r9                      @ we think we have handled things
 
 
        @ not recognised by VFP
 
        DBGSTR  "not VFP"
-       dec_preempt_count_ti r10, r4
+       local_bh_enable_ti r10, r4
        ret     lr
 
 process_exception:
 
        if (exceptions)
                vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
  exit:
-       preempt_enable();
+       local_bh_enable();
 }
 
 static void vfp_enable(void *unused)
 {
        unsigned int cpu = get_cpu();
 
+       local_bh_disable();
+
        if (vfp_state_in_hw(cpu, thread)) {
                u32 fpexc = fmrx(FPEXC);
 
                fmxr(FPEXC, fpexc);
        }
 
+       local_bh_enable();
        put_cpu();
 }
 
        unsigned int cpu;
        u32 fpexc;
 
+       local_bh_disable();
+
        /*
         * Kernel mode NEON is only allowed outside of interrupt context
         * with preemption disabled. This will make sure that the kernel
                vfp_save_state(vfp_current_hw_state[cpu], fpexc);
 #endif
        vfp_current_hw_state[cpu] = NULL;
+       local_bh_enable();
 }
 EXPORT_SYMBOL(kernel_neon_begin);