blob: 360ea6d250c7a7aab3ec8516cffb99413bfe0e66 [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
Ralf Baechle22e651c2007-03-04 18:22:56 +00007#include <linux/spinlock.h>
8
Ralf Baechle41c594a2006-04-05 09:45:45 +01009//#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
20struct 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
42struct smtc_ipi_q {
43 struct smtc_ipi *head;
44 spinlock_t lock;
45 struct smtc_ipi *tail;
46 int depth;
47};
48
Ralf Baechle41c594a2006-04-05 09:45:45 +010049static 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
68static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
69{
70 struct smtc_ipi *p;
71 long flags;
72
73 spin_lock_irqsave(&q->lock, flags);
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 spin_unlock_irqrestore(&q->lock, flags);
85 return p;
86}
87
88static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
89{
90 long flags;
91
92 spin_lock_irqsave(&q->lock, flags);
93 if (q->head == NULL) {
94 q->head = q->tail = p;
95 p->flink = NULL;
96 } else {
97 p->flink = q->head;
98 q->head = p;
99 }
100 q->depth++;
101 spin_unlock_irqrestore(&q->lock, flags);
102}
103
104static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
105{
106 long flags;
107 int retval;
108
109 spin_lock_irqsave(&q->lock, flags);
110 retval = q->depth;
111 spin_unlock_irqrestore(&q->lock, flags);
112 return retval;
113}
114
115extern void smtc_send_ipi(int cpu, int type, unsigned int action);
116
117#endif /* __ASM_SMTC_IPI_H */