aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/nwfpe/fpmodule.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-06-21 08:31:52 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-22 05:24:18 -0400
commitd6551e884cf66de072b81f8b6d23259462c40baf (patch)
treefd8af193bd045e4b16ce911d392d7ffd109d7284 /arch/arm/nwfpe/fpmodule.c
parent52ab3f3dc711eeccbfbcc5d4f5c5d9b9ff59650f (diff)
[ARM] Add thread_notify infrastructure
Some machine classes need to allow VFP support to be built into the kernel, but still allow the kernel to run even though VFP isn't present. Unfortunately, the kernel hard-codes VFP instructions into the thread switch, which prevents this being run-time selectable. Solve this by introducing a notifier which things such as VFP can hook into to be informed of events which affect the VFP subsystem (eg, creation and destruction of threads, switches between threads.) Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/nwfpe/fpmodule.c')
-rw-r--r--arch/arm/nwfpe/fpmodule.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
index 2dfe1ac42ee8..7d977d23f026 100644
--- a/arch/arm/nwfpe/fpmodule.c
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -33,7 +33,8 @@
33#include <linux/signal.h> 33#include <linux/signal.h>
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/init.h> 35#include <linux/init.h>
36/* XXX */ 36
37#include <asm/thread_notify.h>
37 38
38#include "softfloat.h" 39#include "softfloat.h"
39#include "fpopcode.h" 40#include "fpopcode.h"
@@ -56,16 +57,28 @@ void fp_send_sig(unsigned long sig, struct task_struct *p, int priv);
56extern char fpe_type[]; 57extern char fpe_type[];
57#endif 58#endif
58 59
60static int nwfpe_notify(struct notifier_block *self, unsigned long cmd, void *v)
61{
62 struct thread_info *thread = v;
63
64 if (cmd == THREAD_NOTIFY_FLUSH)
65 nwfpe_init_fpa(&thread->fpstate);
66
67 return NOTIFY_DONE;
68}
69
70static struct notifier_block nwfpe_notifier_block = {
71 .notifier_call = nwfpe_notify,
72};
73
59/* kernel function prototypes required */ 74/* kernel function prototypes required */
60void fp_setup(void); 75void fp_setup(void);
61 76
62/* external declarations for saved kernel symbols */ 77/* external declarations for saved kernel symbols */
63extern void (*kern_fp_enter)(void); 78extern void (*kern_fp_enter)(void);
64extern void (*fp_init)(union fp_state *);
65 79
66/* Original value of fp_enter from kernel before patched by fpe_init. */ 80/* Original value of fp_enter from kernel before patched by fpe_init. */
67static void (*orig_fp_enter)(void); 81static void (*orig_fp_enter)(void);
68static void (*orig_fp_init)(union fp_state *);
69 82
70/* forward declarations */ 83/* forward declarations */
71extern void nwfpe_enter(void); 84extern void nwfpe_enter(void);
@@ -88,20 +101,20 @@ static int __init fpe_init(void)
88 printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" 101 printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 ("
89 NWFPE_BITS " precision)\n"); 102 NWFPE_BITS " precision)\n");
90 103
104 thread_register_notifier(&nwfpe_notifier_block);
105
91 /* Save pointer to the old FP handler and then patch ourselves in */ 106 /* Save pointer to the old FP handler and then patch ourselves in */
92 orig_fp_enter = kern_fp_enter; 107 orig_fp_enter = kern_fp_enter;
93 orig_fp_init = fp_init;
94 kern_fp_enter = nwfpe_enter; 108 kern_fp_enter = nwfpe_enter;
95 fp_init = nwfpe_init_fpa;
96 109
97 return 0; 110 return 0;
98} 111}
99 112
100static void __exit fpe_exit(void) 113static void __exit fpe_exit(void)
101{ 114{
115 thread_unregister_notifier(&nwfpe_notifier_block);
102 /* Restore the values we saved earlier. */ 116 /* Restore the values we saved earlier. */
103 kern_fp_enter = orig_fp_enter; 117 kern_fp_enter = orig_fp_enter;
104 fp_init = orig_fp_init;
105} 118}
106 119
107/* 120/*