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)14 extern __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)52 extern __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