smtc_ipi.h 2.0 KB

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