118 lines
		
	
	
	
		
			2.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			2.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
 | |
|  */
 | |
| #ifndef __ASM_SMTC_IPI_H
 | |
| #define __ASM_SMTC_IPI_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
 | |
| 
 | |
| /*
 | |
|  * A queue of IPI messages
 | |
|  */
 | |
| 
 | |
| struct smtc_ipi_q {
 | |
| 	struct smtc_ipi *head;
 | |
| 	spinlock_t lock;
 | |
| 	struct smtc_ipi *tail;
 | |
| 	int depth;
 | |
| };
 | |
| 
 | |
| extern struct smtc_ipi_q IPIQ[NR_CPUS];
 | |
| extern struct smtc_ipi_q freeIPIq;
 | |
| 
 | |
| static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
 | |
| {
 | |
| 	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;
 | |
| 	long flags;
 | |
| 
 | |
| 	spin_lock_irqsave(&q->lock, flags);
 | |
| 	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;
 | |
| 	}
 | |
| 	spin_unlock_irqrestore(&q->lock, flags);
 | |
| 	return p;
 | |
| }
 | |
| 
 | |
| static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
 | |
| {
 | |
| 	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)
 | |
| {
 | |
| 	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 */
 | 
