diff options
author | Mikael Starvik <mikael.starvik@axis.com> | 2005-07-27 11:44:42 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-27 16:26:01 -0700 |
commit | 8d20a541b089ecb67a88a673548161b686ed7b85 (patch) | |
tree | 53bac804d538068c80684becb76cd76937956502 /include/asm-cris | |
parent | 21783c9746619a782c21be606f6498bbd4d4615e (diff) | |
download | linux-8d20a541b089ecb67a88a673548161b686ed7b85.tar.gz linux-8d20a541b089ecb67a88a673548161b686ed7b85.tar.bz2 linux-8d20a541b089ecb67a88a673548161b686ed7b85.zip |
[PATCH] CRIS update: SMP
Patches to support SMP.
* Each CPU has its own current_pgd.
* flush_tlb_range is implemented as flush_tlb_mm.
* Atomic operations implemented with spinlocks.
* Semaphores implemented with spinlocks.
Signed-off-by: Mikael Starvik <starvik@axis.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-cris')
-rw-r--r-- | include/asm-cris/arch-v10/atomic.h | 7 | ||||
-rw-r--r-- | include/asm-cris/atomic.h | 66 | ||||
-rw-r--r-- | include/asm-cris/mmu_context.h | 2 | ||||
-rw-r--r-- | include/asm-cris/semaphore.h | 21 | ||||
-rw-r--r-- | include/asm-cris/smp.h | 7 | ||||
-rw-r--r-- | include/asm-cris/spinlock.h | 1 | ||||
-rw-r--r-- | include/asm-cris/tlbflush.h | 19 |
7 files changed, 65 insertions, 58 deletions
diff --git a/include/asm-cris/arch-v10/atomic.h b/include/asm-cris/arch-v10/atomic.h new file mode 100644 index 000000000000..6ef5e7d09024 --- /dev/null +++ b/include/asm-cris/arch-v10/atomic.h @@ -0,0 +1,7 @@ +#ifndef __ASM_CRIS_ARCH_ATOMIC__ +#define __ASM_CRIS_ARCH_ATOMIC__ + +#define cris_atomic_save(addr, flags) local_irq_save(flags); +#define cris_atomic_restore(addr, flags) local_irq_restore(flags); + +#endif diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h index b3dfea5a71e4..70605b09e8b7 100644 --- a/include/asm-cris/atomic.h +++ b/include/asm-cris/atomic.h @@ -4,21 +4,14 @@ #define __ASM_CRIS_ATOMIC__ #include <asm/system.h> +#include <asm/arch/atomic.h> /* * Atomic operations that C can't guarantee us. Useful for * resource counting etc.. */ -/* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ - -#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) - -typedef struct { int counter; } atomic_t; +typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } @@ -30,29 +23,26 @@ typedef struct { int counter; } atomic_t; extern __inline__ void atomic_add(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); v->counter += i; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ void atomic_sub(int i, volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); v->counter -= i; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ int atomic_add_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter += i); - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -62,10 +52,9 @@ extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter -= i); - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -73,39 +62,35 @@ extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter -= i) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } extern __inline__ void atomic_inc(volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); (v->counter)++; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ void atomic_dec(volatile atomic_t *v) { unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); (v->counter)--; - local_irq_restore(flags); + cris_atomic_restore(v, flags); } extern __inline__ int atomic_inc_return(volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter)++; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -113,20 +98,18 @@ extern __inline__ int atomic_dec_return(volatile atomic_t *v) { unsigned long flags; int retval; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = (v->counter)--; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } extern __inline__ int atomic_dec_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = --(v->counter) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } @@ -134,10 +117,9 @@ extern __inline__ int atomic_inc_and_test(volatile atomic_t *v) { int retval; unsigned long flags; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(v, flags); retval = ++(v->counter) == 0; - local_irq_restore(flags); + cris_atomic_restore(v, flags); return retval; } diff --git a/include/asm-cris/mmu_context.h b/include/asm-cris/mmu_context.h index f9308c5bbd99..e6e659dc757b 100644 --- a/include/asm-cris/mmu_context.h +++ b/include/asm-cris/mmu_context.h @@ -15,7 +15,7 @@ extern void switch_mm(struct mm_struct *prev, struct mm_struct *next, * registers like cr3 on the i386 */ -extern volatile pgd_t *current_pgd; /* defined in arch/cris/mm/fault.c */ +extern volatile DEFINE_PER_CPU(pgd_t *,current_pgd); /* defined in arch/cris/mm/fault.c */ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index 605aa7eaaaf8..8ed7636ab311 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h @@ -72,10 +72,9 @@ extern inline void down(struct semaphore * sem) might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) { __down(sem); } @@ -95,10 +94,9 @@ extern inline int down_interruptible(struct semaphore * sem) might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) failed = __down_interruptible(sem); return(failed); @@ -109,13 +107,13 @@ extern inline int down_trylock(struct semaphore * sem) unsigned long flags; int failed; - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); failed = --(sem->count.counter) < 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(failed) failed = __down_trylock(sem); return(failed); + } /* @@ -130,10 +128,9 @@ extern inline void up(struct semaphore * sem) int wakeup; /* atomically increment the semaphores count, and if it was negative, we wake people */ - local_save_flags(flags); - local_irq_disable(); + cris_atomic_save(sem, flags); wakeup = ++(sem->count.counter) <= 0; - local_irq_restore(flags); + cris_atomic_restore(sem, flags); if(wakeup) { __up(sem); } diff --git a/include/asm-cris/smp.h b/include/asm-cris/smp.h index c2f4feaa041d..dca5ef1d8c97 100644 --- a/include/asm-cris/smp.h +++ b/include/asm-cris/smp.h @@ -1,4 +1,11 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H +#include <linux/cpumask.h> + +extern cpumask_t phys_cpu_present_map; +#define cpu_possible_map phys_cpu_present_map + +#define __smp_processor_id() (current_thread_info()->cpu) + #endif diff --git a/include/asm-cris/spinlock.h b/include/asm-cris/spinlock.h new file mode 100644 index 000000000000..2e8ba8afc7af --- /dev/null +++ b/include/asm-cris/spinlock.h @@ -0,0 +1 @@ +#include <asm/arch/spinlock.h> diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h index 1781fe1a32f6..6ed7d9ae90db 100644 --- a/include/asm-cris/tlbflush.h +++ b/include/asm-cris/tlbflush.h @@ -18,13 +18,26 @@ * */ +extern void __flush_tlb_all(void); +extern void __flush_tlb_mm(struct mm_struct *mm); +extern void __flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr); + +#ifdef CONFIG_SMP extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); -extern void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end); +#else +#define flush_tlb_all __flush_tlb_all +#define flush_tlb_mm __flush_tlb_mm +#define flush_tlb_page __flush_tlb_page +#endif + +static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) +{ + flush_tlb_mm(vma->vm_mm); +} extern inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) |