smtc_ipi.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. long flags;
  60. spin_lock_irqsave(&q->lock, flags);
  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. spin_unlock_irqrestore(&q->lock, flags);
  72. return p;
  73. }
  74. static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
  75. {
  76. long flags;
  77. spin_lock_irqsave(&q->lock, flags);
  78. if (q->head == NULL) {
  79. q->head = q->tail = p;
  80. p->flink = NULL;
  81. } else {
  82. p->flink = q->head;
  83. q->head = p;
  84. }
  85. q->depth++;
  86. spin_unlock_irqrestore(&q->lock, flags);
  87. }
  88. static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
  89. {
  90. long flags;
  91. int retval;
  92. spin_lock_irqsave(&q->lock, flags);
  93. retval = q->depth;
  94. spin_unlock_irqrestore(&q->lock, flags);
  95. return retval;
  96. }
  97. extern void smtc_send_ipi(int cpu, int type, unsigned int action);
  98. #endif /* __ASM_SMTC_IPI_H */