diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 18:54:49 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 18:54:49 +0300 |
commit | d1a76187a5be4f89c6cb19d800cb5fb7aac735c5 (patch) | |
tree | 2fac3ffbfffc7560eeef8364b541d0d7a0057920 /arch/mips/include/asm/smtc_ipi.h | |
parent | c7e78cff6b7518212247fb20b1dc6411540dc9af (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) | |
download | linux-d1a76187a5be4f89c6cb19d800cb5fb7aac735c5.tar.xz |
Merge commit 'v2.6.28-rc2' into core/locking
Conflicts:
arch/um/include/asm/system.h
Diffstat (limited to 'arch/mips/include/asm/smtc_ipi.h')
-rw-r--r-- | arch/mips/include/asm/smtc_ipi.h | 128 |
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 000000000000..8ce517574340 --- /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 */ |