Adrian Bunk | 88278ca | 2008-05-19 16:53:02 -0700 | [diff] [blame] | 1 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * smpprim.h: SMP locking primitives on the Sparc |
| 3 | * |
| 4 | * God knows we won't be actually using this code for some time |
| 5 | * but I thought I'd write it since I knew how. |
| 6 | * |
| 7 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) |
| 8 | */ |
| 9 | |
| 10 | #ifndef __SPARC_SMPPRIM_H |
| 11 | #define __SPARC_SMPPRIM_H |
| 12 | |
| 13 | /* Test and set the unsigned byte at ADDR to 1. Returns the previous |
| 14 | * value. On the Sparc we use the ldstub instruction since it is |
| 15 | * atomic. |
| 16 | */ |
| 17 | |
Adrian Bunk | 3115624 | 2005-10-03 17:37:02 -0700 | [diff] [blame] | 18 | static inline __volatile__ char test_and_set(void *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 19 | { |
| 20 | char state = 0; |
| 21 | |
| 22 | __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t" |
| 23 | "=r" (addr), "=r" (state) : |
| 24 | "0" (addr), "1" (state) : "memory"); |
| 25 | |
| 26 | return state; |
| 27 | } |
| 28 | |
| 29 | /* Initialize a spin-lock. */ |
Adrian Bunk | 3115624 | 2005-10-03 17:37:02 -0700 | [diff] [blame] | 30 | static inline __volatile__ smp_initlock(void *spinlock) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 31 | { |
| 32 | /* Unset the lock. */ |
| 33 | *((unsigned char *) spinlock) = 0; |
| 34 | |
| 35 | return; |
| 36 | } |
| 37 | |
| 38 | /* This routine spins until it acquires the lock at ADDR. */ |
Adrian Bunk | 3115624 | 2005-10-03 17:37:02 -0700 | [diff] [blame] | 39 | static inline __volatile__ smp_lock(void *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 | { |
| 41 | while(test_and_set(addr) == 0xff) |
| 42 | ; |
| 43 | |
| 44 | /* We now have the lock */ |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | /* This routine releases the lock at ADDR. */ |
Adrian Bunk | 3115624 | 2005-10-03 17:37:02 -0700 | [diff] [blame] | 49 | static inline __volatile__ smp_unlock(void *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | { |
| 51 | *((unsigned char *) addr) = 0; |
| 52 | } |
| 53 | |
| 54 | #endif /* !(__SPARC_SMPPRIM_H) */ |