• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define IRQ_AFFINITY_IPI 3
38 
39 /*
40  * A queue of IPI messages
41  */
42 
43 struct smtc_ipi_q {
44 	struct smtc_ipi *head;
45 	spinlock_t lock;
46 	struct smtc_ipi *tail;
47 	int depth;
48 };
49 
smtc_ipi_nq(struct smtc_ipi_q * q,struct smtc_ipi * p)50 static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
51 {
52 	unsigned long flags;
53 
54 	spin_lock_irqsave(&q->lock, flags);
55 	if (q->head == NULL)
56 		q->head = q->tail = p;
57 	else
58 		q->tail->flink = p;
59 	p->flink = NULL;
60 	q->tail = p;
61 	q->depth++;
62 #ifdef	SMTC_IPI_DEBUG
63 	p->sender = read_c0_tcbind();
64 	p->stamp = read_c0_count();
65 #endif /* SMTC_IPI_DEBUG */
66 	spin_unlock_irqrestore(&q->lock, flags);
67 }
68 
__smtc_ipi_dq(struct smtc_ipi_q * q)69 static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
70 {
71 	struct smtc_ipi *p;
72 
73 	if (q->head == NULL)
74 		p = NULL;
75 	else {
76 		p = q->head;
77 		q->head = q->head->flink;
78 		q->depth--;
79 		/* Arguably unnecessary, but leaves queue cleaner */
80 		if (q->head == NULL)
81 			q->tail = NULL;
82 	}
83 
84 	return p;
85 }
86 
smtc_ipi_dq(struct smtc_ipi_q * q)87 static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
88 {
89 	unsigned long flags;
90 	struct smtc_ipi *p;
91 
92 	spin_lock_irqsave(&q->lock, flags);
93 	p = __smtc_ipi_dq(q);
94 	spin_unlock_irqrestore(&q->lock, flags);
95 
96 	return p;
97 }
98 
smtc_ipi_req(struct smtc_ipi_q * q,struct smtc_ipi * p)99 static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
100 {
101 	unsigned long flags;
102 
103 	spin_lock_irqsave(&q->lock, flags);
104 	if (q->head == NULL) {
105 		q->head = q->tail = p;
106 		p->flink = NULL;
107 	} else {
108 		p->flink = q->head;
109 		q->head = p;
110 	}
111 	q->depth++;
112 	spin_unlock_irqrestore(&q->lock, flags);
113 }
114 
smtc_ipi_qdepth(struct smtc_ipi_q * q)115 static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
116 {
117 	unsigned long flags;
118 	int retval;
119 
120 	spin_lock_irqsave(&q->lock, flags);
121 	retval = q->depth;
122 	spin_unlock_irqrestore(&q->lock, flags);
123 	return retval;
124 }
125 
126 extern void smtc_send_ipi(int cpu, int type, unsigned int action);
127 
128 #endif /* __ASM_SMTC_IPI_H */
129