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 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 49static 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 72 if (q->head == NULL) 73 p = NULL; 74 else { 75 p = q->head; 76 q->head = q->head->flink; 77 q->depth--; 78 /* Arguably unnecessary, but leaves queue cleaner */ 79 if (q->head == NULL) 80 q->tail = NULL; 81 } 82 83 return p; 84} 85 86static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) 87{ 88 unsigned long flags; 89 struct smtc_ipi *p; 90 91 spin_lock_irqsave(&q->lock, flags); 92 p = __smtc_ipi_dq(q); 93 spin_unlock_irqrestore(&q->lock, flags); 94 95 return p; 96} 97 98static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) 99{ 100 long flags; 101 102 spin_lock_irqsave(&q->lock, flags); 103 if (q->head == NULL) { 104 q->head = q->tail = p; 105 p->flink = NULL; 106 } else { 107 p->flink = q->head; 108 q->head = p; 109 } 110 q->depth++; 111 spin_unlock_irqrestore(&q->lock, flags); 112} 113 114static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q) 115{ 116 long flags; 117 int retval; 118 119 spin_lock_irqsave(&q->lock, flags); 120 retval = q->depth; 121 spin_unlock_irqrestore(&q->lock, flags); 122 return retval; 123} 124 125extern void smtc_send_ipi(int cpu, int type, unsigned int action); 126 127#endif /* __ASM_SMTC_IPI_H */ 128