aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S24
-rw-r--r--arch/arm/kernel/iwmmxt.S2
-rw-r--r--arch/arm/kernel/process.c24
3 files changed, 22 insertions, 28 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index ab8e600c18c8..86c92523a346 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -20,6 +20,7 @@
20#include <asm/glue.h> 20#include <asm/glue.h>
21#include <asm/vfpmacros.h> 21#include <asm/vfpmacros.h>
22#include <asm/arch/entry-macro.S> 22#include <asm/arch/entry-macro.S>
23#include <asm/thread_notify.h>
23 24
24#include "entry-header.S" 25#include "entry-header.S"
25 26
@@ -560,10 +561,8 @@ ENTRY(__switch_to)
560 add ip, r1, #TI_CPU_SAVE 561 add ip, r1, #TI_CPU_SAVE
561 ldr r3, [r2, #TI_TP_VALUE] 562 ldr r3, [r2, #TI_TP_VALUE]
562 stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack 563 stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
563#ifndef CONFIG_MMU 564#ifdef CONFIG_MMU
564 add r2, r2, #TI_CPU_DOMAIN 565 ldr r6, [r2, #TI_CPU_DOMAIN]
565#else
566 ldr r6, [r2, #TI_CPU_DOMAIN]!
567#endif 566#endif
568#if __LINUX_ARM_ARCH__ >= 6 567#if __LINUX_ARM_ARCH__ >= 6
569#ifdef CONFIG_CPU_32v6K 568#ifdef CONFIG_CPU_32v6K
@@ -585,21 +584,20 @@ ENTRY(__switch_to)
585#ifdef CONFIG_MMU 584#ifdef CONFIG_MMU
586 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 585 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
587#endif 586#endif
588#ifdef CONFIG_VFP
589 @ Always disable VFP so we can lazily save/restore the old
590 @ state. This occurs in the context of the previous thread.
591 VFPFMRX r4, FPEXC
592 bic r4, r4, #FPEXC_ENABLE
593 VFPFMXR FPEXC, r4
594#endif
595#if defined(CONFIG_IWMMXT) 587#if defined(CONFIG_IWMMXT)
596 bl iwmmxt_task_switch 588 bl iwmmxt_task_switch
597#elif defined(CONFIG_CPU_XSCALE) 589#elif defined(CONFIG_CPU_XSCALE)
598 add r4, r2, #40 @ cpu_context_save->extra 590 add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra
599 ldmib r4, {r4, r5} 591 ldmib r4, {r4, r5}
600 mar acc0, r4, r5 592 mar acc0, r4, r5
601#endif 593#endif
602 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously 594 mov r5, r0
595 add r4, r2, #TI_CPU_SAVE
596 ldr r0, =thread_notify_head
597 mov r1, #THREAD_NOTIFY_SWITCH
598 bl atomic_notifier_call_chain
599 mov r0, r5
600 ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
603 601
604 __INIT 602 __INIT
605 603
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index 24c7b0477a09..af9e0ae952d5 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -285,7 +285,7 @@ ENTRY(iwmmxt_task_switch)
285 bne 1f @ yes: block them for next task 285 bne 1f @ yes: block them for next task
286 286
287 ldr r5, =concan_owner 287 ldr r5, =concan_owner
288 add r6, r2, #(TI_IWMMXT_STATE - TI_CPU_DOMAIN) @ get next task Concan save area 288 add r6, r2, #TI_IWMMXT_STATE @ get next task Concan save area
289 ldr r5, [r5] @ get current Concan owner 289 ldr r5, [r5] @ get current Concan owner
290 teq r5, r6 @ next task owns it? 290 teq r5, r6 @ next task owns it?
291 movne pc, lr @ no: leave Concan disabled 291 movne pc, lr @ no: leave Concan disabled
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 17c38dbf2f3c..e1c77ee885a7 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -33,6 +33,7 @@
33#include <asm/leds.h> 33#include <asm/leds.h>
34#include <asm/processor.h> 34#include <asm/processor.h>
35#include <asm/system.h> 35#include <asm/system.h>
36#include <asm/thread_notify.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37#include <asm/mach/time.h> 38#include <asm/mach/time.h>
38 39
@@ -338,13 +339,9 @@ void exit_thread(void)
338{ 339{
339} 340}
340 341
341static void default_fp_init(union fp_state *fp) 342ATOMIC_NOTIFIER_HEAD(thread_notify_head);
342{
343 memset(fp, 0, sizeof(union fp_state));
344}
345 343
346void (*fp_init)(union fp_state *) = default_fp_init; 344EXPORT_SYMBOL_GPL(thread_notify_head);
347EXPORT_SYMBOL(fp_init);
348 345
349void flush_thread(void) 346void flush_thread(void)
350{ 347{
@@ -353,22 +350,21 @@ void flush_thread(void)
353 350
354 memset(thread->used_cp, 0, sizeof(thread->used_cp)); 351 memset(thread->used_cp, 0, sizeof(thread->used_cp));
355 memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); 352 memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
353 memset(&thread->fpstate, 0, sizeof(union fp_state));
354
355 thread_notify(THREAD_NOTIFY_FLUSH, thread);
356#if defined(CONFIG_IWMMXT) 356#if defined(CONFIG_IWMMXT)
357 iwmmxt_task_release(thread); 357 iwmmxt_task_release(thread);
358#endif 358#endif
359 fp_init(&thread->fpstate);
360#if defined(CONFIG_VFP)
361 vfp_flush_thread(&thread->vfpstate);
362#endif
363} 359}
364 360
365void release_thread(struct task_struct *dead_task) 361void release_thread(struct task_struct *dead_task)
366{ 362{
367#if defined(CONFIG_VFP) 363 struct thread_info *thread = task_thread_info(dead_task);
368 vfp_release_thread(&task_thread_info(dead_task)->vfpstate); 364
369#endif 365 thread_notify(THREAD_NOTIFY_RELEASE, thread);
370#if defined(CONFIG_IWMMXT) 366#if defined(CONFIG_IWMMXT)
371 iwmmxt_task_release(task_thread_info(dead_task)); 367 iwmmxt_task_release(thread);
372#endif 368#endif
373} 369}
374 370