Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
smtc_ipi.h
Go to the documentation of this file.
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;
46  struct smtc_ipi *tail;
47  int depth;
48  int resched_flag; /* reschedule already queued */
49 };
50 
51 static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
52 {
53  unsigned long flags;
54 
55  spin_lock_irqsave(&q->lock, flags);
56  if (q->head == NULL)
57  q->head = q->tail = p;
58  else
59  q->tail->flink = p;
60  p->flink = NULL;
61  q->tail = p;
62  q->depth++;
63 #ifdef SMTC_IPI_DEBUG
64  p->sender = read_c0_tcbind();
65  p->stamp = read_c0_count();
66 #endif /* SMTC_IPI_DEBUG */
67  spin_unlock_irqrestore(&q->lock, flags);
68 }
69 
70 static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
71 {
72  struct smtc_ipi *p;
73 
74  if (q->head == NULL)
75  p = NULL;
76  else {
77  p = q->head;
78  q->head = q->head->flink;
79  q->depth--;
80  /* Arguably unnecessary, but leaves queue cleaner */
81  if (q->head == NULL)
82  q->tail = NULL;
83  }
84 
85  return p;
86 }
87 
88 static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
89 {
90  unsigned long flags;
91  struct smtc_ipi *p;
92 
93  spin_lock_irqsave(&q->lock, flags);
94  p = __smtc_ipi_dq(q);
95  spin_unlock_irqrestore(&q->lock, flags);
96 
97  return p;
98 }
99 
100 static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
101 {
102  unsigned long flags;
103 
104  spin_lock_irqsave(&q->lock, flags);
105  if (q->head == NULL) {
106  q->head = q->tail = p;
107  p->flink = NULL;
108  } else {
109  p->flink = q->head;
110  q->head = p;
111  }
112  q->depth++;
113  spin_unlock_irqrestore(&q->lock, flags);
114 }
115 
116 static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
117 {
118  unsigned long flags;
119  int retval;
120 
121  spin_lock_irqsave(&q->lock, flags);
122  retval = q->depth;
123  spin_unlock_irqrestore(&q->lock, flags);
124  return retval;
125 }
126 
127 extern void smtc_send_ipi(int cpu, int type, unsigned int action);
128 
129 #endif /* __ASM_SMTC_IPI_H */