linux-omap-pm 2.6.29: update to latest git HEAD, sync patches and defconfig with...
[openembedded.git] / recipes / linux / linux-omap-pm-2.6.29 / vfp / 04-vfp-threads.patch
1 From: Imre Deak <imre.deak@nokia.com>
2 Date: Wed, 1 Jul 2009 21:20:59 +0000 (+0300)
3 Subject: So far vfp_sync_state worked only for threads other than the current one. This worked... 
4 X-Git-Url: http://siarhei.siamashka.name/gitweb/?p=linux-omap-2.6.git;a=commitdiff_plain;h=23671113997664ae55c8132fc4a56e676d5b46c7
5
6 So far vfp_sync_state worked only for threads other than the current one. This worked for tracing other threads, but not for PTRACE_TRACEME. Syncing for the current thread will also be needed by an upcoming patch adding support for VFP context save / restore around signal handlers.
7
8 For SMP we need get_cpu now, since we have to protect the FPEXC
9 register, other than this things remained the same for threads other
10 than the current.
11
12 Signed-off-by: Imre Deak <imre.deak@nokia.com>
13 ---
14
15 diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
16 index 01599c4..969b77a 100644
17 --- a/arch/arm/vfp/vfpmodule.c
18 +++ b/arch/arm/vfp/vfpmodule.c
19 @@ -380,12 +380,19 @@ static inline void vfp_pm_init(void) { }
20  #endif /* CONFIG_PM */
21  
22  /*
23 - * Synchronise the hardware VFP state of a thread other than current with the
24 - * saved one. This function is used by the ptrace mechanism.
25 + * Synchronise the hardware VFP state of a thread with the saved one.
26 + * This function is used by the ptrace mechanism and the signal handler path.
27   */
28 -#ifdef CONFIG_SMP
29  void vfp_sync_state(struct thread_info *thread)
30  {
31 +       unsigned int cpu = get_cpu();
32 +       u32 fpexc = fmrx(FPEXC);
33 +       int vfp_enabled;
34 +       int self;
35 +
36 +       vfp_enabled = fpexc & FPEXC_EN;
37 +       self = thread == current_thread_info();
38 +#ifdef CONFIG_SMP
39         /*
40          * On SMP systems, the VFP state is automatically saved at every
41          * context switch. We mark the thread VFP state as belonging to a
42 @@ -393,18 +400,22 @@ void vfp_sync_state(struct thread_info *thread)
43          * needed.
44          */
45         thread->vfpstate.hard.cpu = NR_CPUS;
46 -}
47 -#else
48 -void vfp_sync_state(struct thread_info *thread)
49 -{
50 -       unsigned int cpu = get_cpu();
51 -       u32 fpexc = fmrx(FPEXC);
52 -
53         /*
54 -        * If VFP is enabled, the previous state was already saved and
55 -        * last_VFP_context updated.
56 +        * Only the current thread's saved VFP context can be out-of-date.
57 +        * For others there is nothing else to do, since we already ensured
58 +        * force loading above.
59          */
60 -       if (fpexc & FPEXC_EN)
61 +       if (!self)
62 +               goto out;
63 +#endif
64 +       /*
65 +        * If the VFP is enabled only the current thread's saved VFP
66 +        * context can get out-of-date. For other threads the context
67 +        * was updated when the current thread started to use the VFP.
68 +        * This also means that the context will be reloaded next time
69 +        * the thread uses the VFP, so no need to enforce it.
70 +        */
71 +       if (vfp_enabled && !self)
72                 goto out;
73  
74         if (!last_VFP_context[cpu])
75 @@ -413,8 +424,14 @@ void vfp_sync_state(struct thread_info *thread)
76         /*
77          * Save the last VFP state on this CPU.
78          */
79 -       fmxr(FPEXC, fpexc | FPEXC_EN);
80 +       if (!vfp_enabled)
81 +               fmxr(FPEXC, fpexc | FPEXC_EN);
82         vfp_save_state(last_VFP_context[cpu], fpexc);
83 +       /*
84 +        * Disable VFP in case it was enabled so that the force reload
85 +        * can happen.
86 +        */
87 +       fpexc &= ~FPEXC_EN;
88         fmxr(FPEXC, fpexc);
89  
90         /*
91 @@ -426,7 +443,6 @@ void vfp_sync_state(struct thread_info *thread)
92  out:
93         put_cpu();
94  }
95 -#endif
96  
97  #include <linux/smp.h>
98