diff options
Diffstat (limited to 'arch/arm/nwfpe/fpmodule.c')
-rw-r--r-- | arch/arm/nwfpe/fpmodule.c | 25 |
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); | |||
56 | extern char fpe_type[]; | 57 | extern char fpe_type[]; |
57 | #endif | 58 | #endif |
58 | 59 | ||
60 | static 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 | |||
70 | static struct notifier_block nwfpe_notifier_block = { | ||
71 | .notifier_call = nwfpe_notify, | ||
72 | }; | ||
73 | |||
59 | /* kernel function prototypes required */ | 74 | /* kernel function prototypes required */ |
60 | void fp_setup(void); | 75 | void fp_setup(void); |
61 | 76 | ||
62 | /* external declarations for saved kernel symbols */ | 77 | /* external declarations for saved kernel symbols */ |
63 | extern void (*kern_fp_enter)(void); | 78 | extern void (*kern_fp_enter)(void); |
64 | extern 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. */ |
67 | static void (*orig_fp_enter)(void); | 81 | static void (*orig_fp_enter)(void); |
68 | static void (*orig_fp_init)(union fp_state *); | ||
69 | 82 | ||
70 | /* forward declarations */ | 83 | /* forward declarations */ |
71 | extern void nwfpe_enter(void); | 84 | extern 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 | ||
100 | static void __exit fpe_exit(void) | 113 | static 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 | /* |