Pull bugzilla-7200 into release branch
[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 //#define SMTC_IPI_DEBUG
8
9 #ifdef SMTC_IPI_DEBUG
10 #include <asm/mipsregs.h>
11 #include <asm/mipsmtregs.h>
12 #endif /* SMTC_IPI_DEBUG */
13
14 /*
15  * An IPI "message"
16  */
17
18 struct smtc_ipi {
19         struct smtc_ipi *flink;
20         int type;
21         void *arg;
22         int dest;
23 #ifdef  SMTC_IPI_DEBUG
24         int sender;
25         long stamp;
26 #endif /* SMTC_IPI_DEBUG */
27 };
28
29 /*
30  * Defined IPI Types
31  */
32
33 #define LINUX_SMP_IPI 1
34 #define SMTC_CLOCK_TICK 2
35
36 /*
37  * A queue of IPI messages
38  */
39
40 struct smtc_ipi_q {
41         struct smtc_ipi *head;
42         spinlock_t lock;
43         struct smtc_ipi *tail;
44         int depth;
45 };
46
47 static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
48 {
49         long flags;
50
51         spin_lock_irqsave(&q->lock, flags);
52         if (q->head == NULL)
53                 q->head = q->tail = p;
54         else
55                 q->tail->flink = p;
56         p->flink = NULL;
57         q->tail = p;
58         q->depth++;
59 #ifdef  SMTC_IPI_DEBUG
60         p->sender = read_c0_tcbind();
61         p->stamp = read_c0_count();
62 #endif /* SMTC_IPI_DEBUG */
63         spin_unlock_irqrestore(&q->lock, flags);
64 }
65
66 static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
67 {
68         struct smtc_ipi *p;
69         long flags;
70
71         spin_lock_irqsave(&q->lock, flags);
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         spin_unlock_irqrestore(&q->lock, flags);
83         return p;
84 }
85
86 static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
87 {
88         long flags;
89
90         spin_lock_irqsave(&q->lock, flags);
91         if (q->head == NULL) {
92                 q->head = q->tail = p;
93                 p->flink = NULL;
94         } else {
95                 p->flink = q->head;
96                 q->head = p;
97         }
98         q->depth++;
99         spin_unlock_irqrestore(&q->lock, flags);
100 }
101
102 static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
103 {
104         long flags;
105         int retval;
106
107         spin_lock_irqsave(&q->lock, flags);
108         retval = q->depth;
109         spin_unlock_irqrestore(&q->lock, flags);
110         return retval;
111 }
112
113 extern void smtc_send_ipi(int cpu, int type, unsigned int action);
114
115 #endif /* __ASM_SMTC_IPI_H */