blob: 55f3419f65465892f35630c3a32b730866ed77e1 [file] [log] [blame]
Ralf Baechle41c594a2006-04-05 09:45:45 +01001/*
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
18struct 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
40struct smtc_ipi_q {
41 struct smtc_ipi *head;
42 spinlock_t lock;
43 struct smtc_ipi *tail;
44 int depth;
45};
46
Ralf Baechle41c594a2006-04-05 09:45:45 +010047static 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
66static 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
86static 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
102static 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
113extern void smtc_send_ipi(int cpu, int type, unsigned int action);
114
115#endif /* __ASM_SMTC_IPI_H */