summaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/smtc_ipi.h
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 17:13:56 +0100
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 17:13:56 +0100
commite758936e02700ff88a0b08b722a3847b95283ef2 (patch)
tree50c919bef1b459a778b85159d5929de95b6c4a01 /arch/mips/include/asm/smtc_ipi.h
parent239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff)
parent4480f15b3306f43bbb0310d461142b4e897ca45b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: include/asm-x86/statfs.h
Diffstat (limited to 'arch/mips/include/asm/smtc_ipi.h')
-rw-r--r--arch/mips/include/asm/smtc_ipi.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/arch/mips/include/asm/smtc_ipi.h b/arch/mips/include/asm/smtc_ipi.h
new file mode 100644
index 00000000000..8ce51757434
--- /dev/null
+++ b/arch/mips/include/asm/smtc_ipi.h
@@ -0,0 +1,128 @@
+/*
+ * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
+ */
+#ifndef __ASM_SMTC_IPI_H
+#define __ASM_SMTC_IPI_H
+
+#include <linux/spinlock.h>
+
+//#define SMTC_IPI_DEBUG
+
+#ifdef SMTC_IPI_DEBUG
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#endif /* SMTC_IPI_DEBUG */
+
+/*
+ * An IPI "message"
+ */
+
+struct smtc_ipi {
+ struct smtc_ipi *flink;
+ int type;
+ void *arg;
+ int dest;
+#ifdef SMTC_IPI_DEBUG
+ int sender;
+ long stamp;
+#endif /* SMTC_IPI_DEBUG */
+};
+
+/*
+ * Defined IPI Types
+ */
+
+#define LINUX_SMP_IPI 1
+#define SMTC_CLOCK_TICK 2
+#define IRQ_AFFINITY_IPI 3
+
+/*
+ * A queue of IPI messages
+ */
+
+struct smtc_ipi_q {
+ struct smtc_ipi *head;
+ spinlock_t lock;
+ struct smtc_ipi *tail;
+ int depth;
+};
+
+static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+ if (q->head == NULL)
+ q->head = q->tail = p;
+ else
+ q->tail->flink = p;
+ p->flink = NULL;
+ q->tail = p;
+ q->depth++;
+#ifdef SMTC_IPI_DEBUG
+ p->sender = read_c0_tcbind();
+ p->stamp = read_c0_count();
+#endif /* SMTC_IPI_DEBUG */
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+
+static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
+{
+ struct smtc_ipi *p;
+
+ if (q->head == NULL)
+ p = NULL;
+ else {
+ p = q->head;
+ q->head = q->head->flink;
+ q->depth--;
+ /* Arguably unnecessary, but leaves queue cleaner */
+ if (q->head == NULL)
+ q->tail = NULL;
+ }
+
+ return p;
+}
+
+static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
+{
+ unsigned long flags;
+ struct smtc_ipi *p;
+
+ spin_lock_irqsave(&q->lock, flags);
+ p = __smtc_ipi_dq(q);
+ spin_unlock_irqrestore(&q->lock, flags);
+
+ return p;
+}
+
+static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+ if (q->head == NULL) {
+ q->head = q->tail = p;
+ p->flink = NULL;
+ } else {
+ p->flink = q->head;
+ q->head = p;
+ }
+ q->depth++;
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+
+static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
+{
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&q->lock, flags);
+ retval = q->depth;
+ spin_unlock_irqrestore(&q->lock, flags);
+ return retval;
+}
+
+extern void smtc_send_ipi(int cpu, int type, unsigned int action);
+
+#endif /* __ASM_SMTC_IPI_H */