aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorKyle McMartin <kyle@parisc-linux.org>2006-03-24 23:24:21 -0500
committerKyle McMartin <kyle@hera.kernel.org>2006-03-30 12:48:54 -0500
commit50a34dbd612925f2ec55b1781632835ef36b97d5 (patch)
tree1624f33bdbdd367efb8fadebe80da7db275ea1e6 /arch/parisc/kernel
parentbc8846c522264d2522b0082321ec8c2051a4536f (diff)
[PARISC] Add PREEMPT support
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/entry.S39
1 files changed, 36 insertions, 3 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 6d17c0a3431b..7c95d7663c29 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1014,14 +1014,21 @@ intr_restore:
1014 nop 1014 nop
1015 nop 1015 nop
1016 1016
1017#ifndef CONFIG_PREEMPT
1018# define intr_do_preempt intr_restore
1019#endif /* !CONFIG_PREEMPT */
1020
1017 .import schedule,code 1021 .import schedule,code
1018intr_do_resched: 1022intr_do_resched:
1019 /* Only do reschedule if we are returning to user space */ 1023 /* Only call schedule on return to userspace. If we're returning
1024 * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
1025 * we jump back to intr_restore.
1026 */
1020 LDREG PT_IASQ0(%r16), %r20 1027 LDREG PT_IASQ0(%r16), %r20
1021 CMPIB= 0,%r20,intr_restore /* backward */ 1028 CMPIB= 0, %r20, intr_do_preempt
1022 nop 1029 nop
1023 LDREG PT_IASQ1(%r16), %r20 1030 LDREG PT_IASQ1(%r16), %r20
1024 CMPIB= 0,%r20,intr_restore /* backward */ 1031 CMPIB= 0, %r20, intr_do_preempt
1025 nop 1032 nop
1026 1033
1027#ifdef CONFIG_64BIT 1034#ifdef CONFIG_64BIT
@@ -1037,6 +1044,32 @@ intr_do_resched:
1037#endif 1044#endif
1038 ldo R%intr_check_sig(%r2), %r2 1045 ldo R%intr_check_sig(%r2), %r2
1039 1046
1047 /* preempt the current task on returning to kernel
1048 * mode from an interrupt, iff need_resched is set,
1049 * and preempt_count is 0. otherwise, we continue on
1050 * our merry way back to the current running task.
1051 */
1052#ifdef CONFIG_PREEMPT
1053 .import preempt_schedule_irq,code
1054intr_do_preempt:
1055 rsm PSW_SM_I, %r0 /* disable interrupts */
1056
1057 /* current_thread_info()->preempt_count */
1058 mfctl %cr30, %r1
1059 LDREG TI_PRE_COUNT(%r1), %r19
1060 CMPIB<> 0, %r19, intr_restore /* if preempt_count > 0 */
1061 nop /* prev insn branched backwards */
1062
1063 /* check if we interrupted a critical path */
1064 LDREG PT_PSW(%r16), %r20
1065 bb,<,n %r20, 31 - PSW_SM_I, intr_restore
1066 nop
1067
1068 BL preempt_schedule_irq, %r2
1069 nop
1070
1071 b intr_restore /* ssm PSW_SM_I done by intr_restore */
1072#endif /* CONFIG_PREEMPT */
1040 1073
1041 .import do_signal,code 1074 .import do_signal,code
1042intr_do_signal: 1075intr_do_signal: