smtc_ipi.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. extern struct smtc_ipi_q IPIQ[NR_CPUS];
  39. extern struct smtc_ipi_q freeIPIq;
  40. static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
  41. {
  42. 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. long flags;
  61. spin_lock_irqsave(&q->lock, flags);
  62. if (q->head == NULL)
  63. p = NULL;
  64. else {
  65. p = q->head;
  66. q->head = q->head->flink;
  67. q->depth--;
  68. /* Arguably unnecessary, but leaves queue cleaner */
  69. if (q->head == NULL)
  70. q->tail = NULL;
  71. }
  72. spin_unlock_irqrestore(&q->lock, flags);
  73. return p;
  74. }
  75. static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
  76. {
  77. long flags;
  78. spin_lock_irqsave(&q->lock, flags);
  79. if (q->head == NULL) {
  80. q->head = q->tail = p;
  81. p->flink = NULL;
  82. } else {
  83. p->flink = q->head;
  84. q->head = p;
  85. }
  86. q->depth++;
  87. spin_unlock_irqrestore(&q->lock, flags);
  88. }
  89. static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
  90. {
  91. long flags;
  92. int retval;
  93. spin_lock_irqsave(&q->lock, flags);
  94. retval = q->depth;
  95. spin_unlock_irqrestore(&q->lock, flags);
  96. return retval;
  97. }
  98. extern void smtc_send_ipi(int cpu, int type, unsigned int action);
  99. #endif /* __ASM_SMTC_IPI_H */