1 #ifndef __CRIS_SMPLOCK_H 2 #define __CRIS_SMPLOCK_H 3 4 #include <linux/config.h> 5 6 #ifdef CONFIG_SMP 7 8 #error "SMP is not supported for CRIS" 9 10 /* 11 * Locking the kernel 12 */ 13 lock_kernel(void)14extern __inline void lock_kernel(void) 15 { 16 unsigned long flags; 17 int proc = smp_processor_id(); 18 19 save_flags(flags); 20 cli(); 21 /* set_bit works atomic in SMP machines */ 22 while(set_bit(0, (void *)&kernel_flag)) 23 { 24 /* 25 * We just start another level if we have the lock 26 */ 27 if (proc == active_kernel_processor) 28 break; 29 do 30 { 31 #ifdef __SMP_PROF__ 32 smp_spins[smp_processor_id()]++; 33 #endif 34 /* 35 * Doing test_bit here doesn't lock the bus 36 */ 37 if (test_bit(proc, (void *)&smp_invalidate_needed)) 38 if (clear_bit(proc, (void *)&smp_invalidate_needed)) 39 local_flush_tlb(); 40 } 41 while(test_bit(0, (void *)&kernel_flag)); 42 } 43 /* 44 * We got the lock, so tell the world we are here and increment 45 * the level counter 46 */ 47 active_kernel_processor = proc; 48 kernel_counter++; 49 restore_flags(flags); 50 } 51 unlock_kernel(void)52extern __inline void unlock_kernel(void) 53 { 54 unsigned long flags; 55 save_flags(flags); 56 cli(); 57 /* 58 * If it's the last level we have in the kernel, then 59 * free the lock 60 */ 61 if (kernel_counter == 0) 62 panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */ 63 64 if(! --kernel_counter) 65 { 66 active_kernel_processor = NO_PROC_ID; 67 clear_bit(0, (void *)&kernel_flag); 68 } 69 restore_flags(flags); 70 } 71 72 #endif 73 #endif 74