Commit ae95bfbb authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by Russell King

[ARM] 3707/1: iwmmxt: use the generic thread notifier infrastructure

Patch from Lennert Buytenhek

This patch makes the iWMMXt context switch hook use the generic
thread notifier infrastructure that was recently merged in commit
d6551e88.
Signed-off-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9b841755
...@@ -25,7 +25,7 @@ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o ...@@ -25,7 +25,7 @@ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_IWMMXT) += iwmmxt.o iwmmxt-notifier.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
ifneq ($(CONFIG_ARCH_EBSA110),y) ifneq ($(CONFIG_ARCH_EBSA110),y)
......
...@@ -590,9 +590,7 @@ ENTRY(__switch_to) ...@@ -590,9 +590,7 @@ ENTRY(__switch_to)
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif #endif
#if defined(CONFIG_IWMMXT) #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
bl iwmmxt_task_switch
#elif defined(CONFIG_CPU_XSCALE)
add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra
ldmib r4, {r4, r5} ldmib r4, {r4, r5}
mar acc0, r4, r5 mar acc0, r4, r5
......
/*
* linux/arch/arm/kernel/iwmmxt-notifier.c
*
* XScale iWMMXt (Concan) context switching and handling
*
* Initial code:
* Copyright (c) 2003, Intel Corporation
*
* Full lazy switching support, optimizations and more, by Nicolas Pitre
* Copyright (c) 2003-2004, MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/thread_notify.h>
#include <asm/io.h>
static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
{
struct thread_info *thread = t;
switch (cmd) {
case THREAD_NOTIFY_FLUSH:
/*
* flush_thread() zeroes thread->fpstate, so no need
* to do anything here.
*
* FALLTHROUGH: Ensure we don't try to overwrite our newly
* initialised state information on the first fault.
*/
case THREAD_NOTIFY_RELEASE:
iwmmxt_task_release(thread);
break;
case THREAD_NOTIFY_SWITCH:
iwmmxt_task_switch(thread);
break;
}
return NOTIFY_DONE;
}
static struct notifier_block iwmmxt_notifier_block = {
.notifier_call = iwmmxt_do,
};
static int __init iwmmxt_init(void)
{
thread_register_notifier(&iwmmxt_notifier_block);
return 0;
}
late_initcall(iwmmxt_init);
...@@ -271,30 +271,27 @@ ENTRY(iwmmxt_task_restore) ...@@ -271,30 +271,27 @@ ENTRY(iwmmxt_task_restore)
/* /*
* Concan handling on task switch * Concan handling on task switch
* *
* r0 = previous task_struct pointer (must be preserved) * r0 = next thread_info pointer
* r1 = previous thread_info pointer
* r2 = next thread_info pointer (must be preserved)
* *
* Called only from __switch_to with task preemption disabled. * Called only from the iwmmxt notifier with task preemption disabled.
* No need to care about preserving r4 and above.
*/ */
ENTRY(iwmmxt_task_switch) ENTRY(iwmmxt_task_switch)
mrc p15, 0, r4, c15, c1, 0 mrc p15, 0, r1, c15, c1, 0
tst r4, #0x3 @ CP0 and CP1 accessible? tst r1, #0x3 @ CP0 and CP1 accessible?
bne 1f @ yes: block them for next task bne 1f @ yes: block them for next task
ldr r5, =concan_owner ldr r2, =concan_owner
add r6, r2, #TI_IWMMXT_STATE @ get next task Concan save area add r3, r0, #TI_IWMMXT_STATE @ get next task Concan save area
ldr r5, [r5] @ get current Concan owner ldr r2, [r2] @ get current Concan owner
teq r5, r6 @ next task owns it? teq r2, r3 @ next task owns it?
movne pc, lr @ no: leave Concan disabled movne pc, lr @ no: leave Concan disabled
1: eor r4, r4, #3 @ flip Concan access 1: eor r1, r1, #3 @ flip Concan access
mcr p15, 0, r4, c15, c1, 0 mcr p15, 0, r1, c15, c1, 0
mrc p15, 0, r4, c2, c0, 0 mrc p15, 0, r1, c2, c0, 0
sub pc, lr, r4, lsr #32 @ cpwait and return sub pc, lr, r1, lsr #32 @ cpwait and return
/* /*
* Remove Concan ownership of given task * Remove Concan ownership of given task
......
...@@ -353,9 +353,6 @@ void flush_thread(void) ...@@ -353,9 +353,6 @@ void flush_thread(void)
memset(&thread->fpstate, 0, sizeof(union fp_state)); memset(&thread->fpstate, 0, sizeof(union fp_state));
thread_notify(THREAD_NOTIFY_FLUSH, thread); thread_notify(THREAD_NOTIFY_FLUSH, thread);
#if defined(CONFIG_IWMMXT)
iwmmxt_task_release(thread);
#endif
} }
void release_thread(struct task_struct *dead_task) void release_thread(struct task_struct *dead_task)
...@@ -363,9 +360,6 @@ void release_thread(struct task_struct *dead_task) ...@@ -363,9 +360,6 @@ void release_thread(struct task_struct *dead_task)
struct thread_info *thread = task_thread_info(dead_task); struct thread_info *thread = task_thread_info(dead_task);
thread_notify(THREAD_NOTIFY_RELEASE, thread); thread_notify(THREAD_NOTIFY_RELEASE, thread);
#if defined(CONFIG_IWMMXT)
iwmmxt_task_release(thread);
#endif
} }
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
......
...@@ -111,6 +111,7 @@ extern void iwmmxt_task_disable(struct thread_info *); ...@@ -111,6 +111,7 @@ extern void iwmmxt_task_disable(struct thread_info *);
extern void iwmmxt_task_copy(struct thread_info *, void *); extern void iwmmxt_task_copy(struct thread_info *, void *);
extern void iwmmxt_task_restore(struct thread_info *, void *); extern void iwmmxt_task_restore(struct thread_info *, void *);
extern void iwmmxt_task_release(struct thread_info *); extern void iwmmxt_task_release(struct thread_info *);
extern void iwmmxt_task_switch(struct thread_info *);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment