bsr     $1, do_switch_stack
        mov     $sp, $17
        mov     $5, $18
-       mov     $19, $9         /* save old syscall number */
-       mov     $20, $10        /* save old a3 */
-       and     $5, _TIF_SIGPENDING, $2
-       cmovne  $2, 0, $9       /* we don't want double syscall restarts */
-       jsr     $26, do_notify_resume
-       mov     $9, $19
-       mov     $10, $20
+       jsr     $26, do_work_pending
        bsr     $1, undo_switch_stack
-       br      ret_to_user
+       br      restore_all
 .end work_pending
 
 /*
 
 }
 
 void
-do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
-                unsigned long thread_info_flags,
+do_work_pending(struct pt_regs *regs, struct switch_stack *sw,
+                unsigned long thread_flags,
                 unsigned long r0, unsigned long r19)
 {
-       if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(regs, sw, r0, r19);
-
-       if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-               clear_thread_flag(TIF_NOTIFY_RESUME);
-               tracehook_notify_resume(regs);
-       }
+       do {
+               if (thread_flags & _TIF_NEED_RESCHED) {
+                       schedule();
+               } else {
+                       local_irq_enable();
+                       if (thread_flags & _TIF_SIGPENDING) {
+                               do_signal(regs, sw, r0, r19);
+                               r0 = 0;
+                       } else {
+                               clear_thread_flag(TIF_NOTIFY_RESUME);
+                               tracehook_notify_resume(regs);
+                       }
+               }
+               local_irq_disable();
+               thread_flags = current_thread_info()->flags;
+       } while (thread_flags & _TIF_WORK_MASK);
 }