summaryrefslogtreecommitdiff
path: root/arch/sh/kernel/process_32.c
diff options
context:
space:
mode:
authorMichael Trimarchi <trimarchi@gandalf.sssup.it>2009-04-03 21:32:33 +0400
committerPaul Mundt <lethal@linux-sh.org>2009-04-04 19:48:11 +0400
commit01ab10393c510342ec4ce85df11ccfa3df06bbb2 (patch)
treeebf0493fa7b53941f830f8b300037f834eb85e59 /arch/sh/kernel/process_32.c
parenta27873cd234b4248dda342721d6262943e5fa235 (diff)
downloadlinux-01ab10393c510342ec4ce85df11ccfa3df06bbb2.tar.xz
sh: Fix up DSP context save/restore.
There were a number of issues with the DSP context save/restore code, mostly left-over relics from when it was introduced on SH3-DSP with little follow-up testing, resulting in things like task_pt_dspregs() referencing incorrect state on the stack. This follows the MIPS convention of tracking the DSP state in the thread_struct and handling the state save/restore in switch_to() and finish_arch_switch() respectively. The regset interface is also updated, which allows us to finally be rid of task_pt_dspregs() and the special cased task_pt_regs(). Signed-off-by: Michael Trimarchi <michael@evidence.eu.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/process_32.c')
-rw-r--r--arch/sh/kernel/process_32.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index ddafbbbab2ab..0747fabd73a7 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -176,14 +176,26 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
{
struct thread_info *ti = task_thread_info(p);
struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU)
+#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
struct task_struct *tsk = current;
+#endif
+#if defined(CONFIG_SH_FPU)
unlazy_fpu(tsk, regs);
p->thread.fpu = tsk->thread.fpu;
copy_to_stopped_child_used_math(p);
#endif
+#if defined(CONFIG_SH_DSP)
+ if (is_dsp_enabled(tsk)) {
+ /* We can use the __save_dsp or just copy the struct:
+ * __save_dsp(p);
+ * p->thread.dsp_status.status |= SR_DSP
+ */
+ p->thread.dsp_status = tsk->thread.dsp_status;
+ }
+#endif
+
childregs = task_pt_regs(p);
*childregs = *regs;