Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux-2.6] / include / asm-mips / smtc_ipi.h
1 /*
2  * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
3  */
4 #ifndef __ASM_SMTC_IPI_H
5 #define __ASM_SMTC_IPI_H
6
7 #include <linux/spinlock.h>
8
9 //#define SMTC_IPI_DEBUG
10
11 #ifdef SMTC_IPI_DEBUG
12 #include <asm/mipsregs.h>
13 #include <asm/mipsmtregs.h>
14 #endif /* SMTC_IPI_DEBUG */
15
16 /*
17  * An IPI "message"
18  */
19
20 struct smtc_ipi {
21         struct smtc_ipi *flink;
22         int type;
23         void *arg;
24         int dest;
25 #ifdef  SMTC_IPI_DEBUG
26         int sender;
27         long stamp;
28 #endif /* SMTC_IPI_DEBUG */
29 };
30
31 /*
32  * Defined IPI Types
33  */
34
35 #define LINUX_SMP_IPI 1
36 #define SMTC_CLOCK_TICK 2
37
38 /*
39  * A queue of IPI messages
40  */
41
42 struct smtc_ipi_q {
43         struct smtc_ipi *head;
44         spinlock_t lock;
45         struct smtc_ipi *tail;
46         int depth;
47 };
48
49 static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
50 {
51         long flags;
52
53         spin_lock_irqsave(&q->lock, flags);
54         if (q->head == NULL)
55                 q->head = q->tail = p;
56         else
57                 q->tail->flink = p;
58         p->flink = NULL;
59         q->tail = p;
60         q->depth++;
61 #ifdef  SMTC_IPI_DEBUG
62         p->sender = read_c0_tcbind();
63         p->stamp = read_c0_count();
64 #endif /* SMTC_IPI_DEBUG */
65         spin_unlock_irqrestore(&q->lock, flags);
66 }
67
68 static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
69 {
70         struct smtc_ipi *p;
71
72         if (q->head == NULL)
73                 p = NULL;
74         else {
75                 p = q->head;
76                 q->head = q->head->flink;
77                 q->depth--;
78                 /* Arguably unnecessary, but leaves queue cleaner */
79                 if (q->head == NULL)
80                         q->tail = NULL;
81         }
82
83         return p;
84 }
85
86 static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
87 {
88         unsigned long flags;
89         struct smtc_ipi *p;
90
91         spin_lock_irqsave(&q->lock, flags);
92         p = __smtc_ipi_dq(q);
93         spin_unlock_irqrestore(&q->lock, flags);
94
95         return p;
96 }
97
98 static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
99 {
100         long flags;
101
102         spin_lock_irqsave(&q->lock, flags);
103         if (q->head == NULL) {
104                 q->head = q->tail = p;
105                 p->flink = NULL;
106         } else {
107                 p->flink = q->head;
108                 q->head = p;
109         }
110         q->depth++;
111         spin_unlock_irqrestore(&q->lock, flags);
112 }
113
114 static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
115 {
116         long flags;
117         int retval;
118
119         spin_lock_irqsave(&q->lock, flags);
120         retval = q->depth;
121         spin_unlock_irqrestore(&q->lock, flags);
122         return retval;
123 }
124
125 extern void smtc_send_ipi(int cpu, int type, unsigned int action);
126
127 #endif /* __ASM_SMTC_IPI_H */