smtc_ipi.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. #include <linux/spinlock.h>
  7. //#define SMTC_IPI_DEBUG
  8. #ifdef SMTC_IPI_DEBUG
  9. #include <asm/mipsregs.h>
  10. #include <asm/mipsmtregs.h>
  11. #endif /* SMTC_IPI_DEBUG */
  12. /*
  13. * An IPI "message"
  14. */
  15. struct smtc_ipi {
  16. struct smtc_ipi *flink;
  17. int type;
  18. void *arg;
  19. int dest;
  20. #ifdef SMTC_IPI_DEBUG
  21. int sender;
  22. long stamp;
  23. #endif /* SMTC_IPI_DEBUG */
  24. };
  25. /*
  26. * Defined IPI Types
  27. */
  28. #define LINUX_SMP_IPI 1
  29. #define SMTC_CLOCK_TICK 2
  30. #define IRQ_AFFINITY_IPI 3
  31. /*
  32. * A queue of IPI messages
  33. */
  34. struct smtc_ipi_q {
  35. struct smtc_ipi *head;
  36. spinlock_t lock;
  37. struct smtc_ipi *tail;
  38. int depth;
  39. int resched_flag; /* reschedule already queued */
  40. };
  41. static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
  42. {
  43. unsigned long flags;
  44. spin_lock_irqsave(&q->lock, flags);
  45. if (q->head == NULL)
  46. q->head = q->tail = p;
  47. else
  48. q->tail->flink = p;
  49. p->flink = NULL;
  50. q->tail = p;
  51. q->depth++;
  52. #ifdef SMTC_IPI_DEBUG
  53. p->sender = read_c0_tcbind();
  54. p->stamp = read_c0_count();
  55. #endif /* SMTC_IPI_DEBUG */
  56. spin_unlock_irqrestore(&q->lock, flags);
  57. }
  58. static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
  59. {
  60. struct smtc_ipi *p;
  61. if (q->head == NULL)
  62. p = NULL;
  63. else {
  64. p = q->head;
  65. q->head = q->head->flink;
  66. q->depth--;
  67. /* Arguably unnecessary, but leaves queue cleaner */
  68. if (q->head == NULL)
  69. q->tail = NULL;
  70. }
  71. return p;
  72. }
  73. static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
  74. {
  75. unsigned long flags;
  76. struct smtc_ipi *p;
  77. spin_lock_irqsave(&q->lock, flags);
  78. p = __smtc_ipi_dq(q);
  79. spin_unlock_irqrestore(&q->lock, flags);
  80. return p;
  81. }
  82. static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
  83. {
  84. unsigned long flags;
  85. spin_lock_irqsave(&q->lock, flags);
  86. if (q->head == NULL) {
  87. q->head = q->tail = p;
  88. p->flink = NULL;
  89. } else {
  90. p->flink = q->head;
  91. q->head = p;
  92. }
  93. q->depth++;
  94. spin_unlock_irqrestore(&q->lock, flags);
  95. }
  96. static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
  97. {
  98. unsigned long flags;
  99. int retval;
  100. spin_lock_irqsave(&q->lock, flags);
  101. retval = q->depth;
  102. spin_unlock_irqrestore(&q->lock, flags);
  103. return retval;
  104. }
  105. extern void smtc_send_ipi(int cpu, int type, unsigned int action);
  106. #endif /* __ASM_SMTC_IPI_H */