smtc_ipi.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. };
  40. static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
  41. {
  42. unsigned long flags;
  43. spin_lock_irqsave(&q->lock, flags);
  44. if (q->head == NULL)
  45. q->head = q->tail = p;
  46. else
  47. q->tail->flink = p;
  48. p->flink = NULL;
  49. q->tail = p;
  50. q->depth++;
  51. #ifdef SMTC_IPI_DEBUG
  52. p->sender = read_c0_tcbind();
  53. p->stamp = read_c0_count();
  54. #endif /* SMTC_IPI_DEBUG */
  55. spin_unlock_irqrestore(&q->lock, flags);
  56. }
  57. static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
  58. {
  59. struct smtc_ipi *p;
  60. if (q->head == NULL)
  61. p = NULL;
  62. else {
  63. p = q->head;
  64. q->head = q->head->flink;
  65. q->depth--;
  66. /* Arguably unnecessary, but leaves queue cleaner */
  67. if (q->head == NULL)
  68. q->tail = NULL;
  69. }
  70. return p;
  71. }
  72. static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
  73. {
  74. unsigned long flags;
  75. struct smtc_ipi *p;
  76. spin_lock_irqsave(&q->lock, flags);
  77. p = __smtc_ipi_dq(q);
  78. spin_unlock_irqrestore(&q->lock, flags);
  79. return p;
  80. }
  81. static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
  82. {
  83. unsigned long flags;
  84. spin_lock_irqsave(&q->lock, flags);
  85. if (q->head == NULL) {
  86. q->head = q->tail = p;
  87. p->flink = NULL;
  88. } else {
  89. p->flink = q->head;
  90. q->head = p;
  91. }
  92. q->depth++;
  93. spin_unlock_irqrestore(&q->lock, flags);
  94. }
  95. static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
  96. {
  97. unsigned long flags;
  98. int retval;
  99. spin_lock_irqsave(&q->lock, flags);
  100. retval = q->depth;
  101. spin_unlock_irqrestore(&q->lock, flags);
  102. return retval;
  103. }
  104. extern void smtc_send_ipi(int cpu, int type, unsigned int action);
  105. #endif /* __ASM_SMTC_IPI_H */