linux/arch/mips/include/asm/smtc_ipi.h
<<
>>
Prefs
   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#define IRQ_AFFINITY_IPI 3
  38
  39/*
  40 * A queue of IPI messages
  41 */
  42
  43struct smtc_ipi_q {
  44        struct smtc_ipi *head;
  45        spinlock_t lock;
  46        struct smtc_ipi *tail;
  47        int depth;
  48        int resched_flag;       /* reschedule already queued */
  49};
  50
  51static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
  52{
  53        unsigned long flags;
  54
  55        spin_lock_irqsave(&q->lock, flags);
  56        if (q->head == NULL)
  57                q->head = q->tail = p;
  58        else
  59                q->tail->flink = p;
  60        p->flink = NULL;
  61        q->tail = p;
  62        q->depth++;
  63#ifdef  SMTC_IPI_DEBUG
  64        p->sender = read_c0_tcbind();
  65        p->stamp = read_c0_count();
  66#endif /* SMTC_IPI_DEBUG */
  67        spin_unlock_irqrestore(&q->lock, flags);
  68}
  69
  70static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
  71{
  72        struct smtc_ipi *p;
  73
  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
  85        return p;
  86}
  87
  88static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
  89{
  90        unsigned long flags;
  91        struct smtc_ipi *p;
  92
  93        spin_lock_irqsave(&q->lock, flags);
  94        p = __smtc_ipi_dq(q);
  95        spin_unlock_irqrestore(&q->lock, flags);
  96
  97        return p;
  98}
  99
 100static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
 101{
 102        unsigned long flags;
 103
 104        spin_lock_irqsave(&q->lock, flags);
 105        if (q->head == NULL) {
 106                q->head = q->tail = p;
 107                p->flink = NULL;
 108        } else {
 109                p->flink = q->head;
 110                q->head = p;
 111        }
 112        q->depth++;
 113        spin_unlock_irqrestore(&q->lock, flags);
 114}
 115
 116static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
 117{
 118        unsigned long flags;
 119        int retval;
 120
 121        spin_lock_irqsave(&q->lock, flags);
 122        retval = q->depth;
 123        spin_unlock_irqrestore(&q->lock, flags);
 124        return retval;
 125}
 126
 127extern void smtc_send_ipi(int cpu, int type, unsigned int action);
 128
 129#endif /* __ASM_SMTC_IPI_H */
 130