smtc_ipi.h 2.2 KB

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