xics.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Common definitions across all variants of ICP and ICS interrupt
  3. * controllers.
  4. */
  5. #ifndef _XICS_H
  6. #define _XICS_H
  7. #include <linux/interrupt.h>
  8. #define XICS_IPI 2
  9. #define XICS_IRQ_SPURIOUS 0
  10. /* Want a priority other than 0. Various HW issues require this. */
  11. #define DEFAULT_PRIORITY 5
  12. /*
  13. * Mark IPIs as higher priority so we can take them inside interrupts
  14. * FIXME: still true now?
  15. */
  16. #define IPI_PRIORITY 4
  17. /* The least favored priority */
  18. #define LOWEST_PRIORITY 0xFF
  19. /* The number of priorities defined above */
  20. #define MAX_NUM_PRIORITIES 3
  21. /* Native ICP */
  22. #ifdef CONFIG_PPC_ICP_NATIVE
  23. extern int icp_native_init(void);
  24. extern void icp_native_flush_interrupt(void);
  25. extern void icp_native_cause_ipi_rm(int cpu);
  26. #else
  27. static inline int icp_native_init(void) { return -ENODEV; }
  28. #endif
  29. /* PAPR ICP */
  30. #ifdef CONFIG_PPC_ICP_HV
  31. extern int icp_hv_init(void);
  32. #else
  33. static inline int icp_hv_init(void) { return -ENODEV; }
  34. #endif
  35. #ifdef CONFIG_PPC_POWERNV
  36. extern int icp_opal_init(void);
  37. extern void icp_opal_flush_interrupt(void);
  38. #else
  39. static inline int icp_opal_init(void) { return -ENODEV; }
  40. #endif
  41. /* ICP ops */
  42. struct icp_ops {
  43. unsigned int (*get_irq)(void);
  44. void (*eoi)(struct irq_data *d);
  45. void (*set_priority)(unsigned char prio);
  46. void (*teardown_cpu)(void);
  47. void (*flush_ipi)(void);
  48. #ifdef CONFIG_SMP
  49. void (*cause_ipi)(int cpu, unsigned long data);
  50. irq_handler_t ipi_action;
  51. #endif
  52. };
  53. extern const struct icp_ops *icp_ops;
  54. /* Native ICS */
  55. extern int ics_native_init(void);
  56. /* RTAS ICS */
  57. #ifdef CONFIG_PPC_ICS_RTAS
  58. extern int ics_rtas_init(void);
  59. #else
  60. static inline int ics_rtas_init(void) { return -ENODEV; }
  61. #endif
  62. /* HAL ICS */
  63. #ifdef CONFIG_PPC_POWERNV
  64. extern int ics_opal_init(void);
  65. #else
  66. static inline int ics_opal_init(void) { return -ENODEV; }
  67. #endif
  68. /* ICS instance, hooked up to chip_data of an irq */
  69. struct ics {
  70. struct list_head link;
  71. int (*map)(struct ics *ics, unsigned int virq);
  72. void (*mask_unknown)(struct ics *ics, unsigned long vec);
  73. long (*get_server)(struct ics *ics, unsigned long vec);
  74. int (*host_match)(struct ics *ics, struct device_node *node);
  75. char data[];
  76. };
  77. /* Commons */
  78. extern unsigned int xics_default_server;
  79. extern unsigned int xics_default_distrib_server;
  80. extern unsigned int xics_interrupt_server_size;
  81. extern struct irq_domain *xics_host;
  82. struct xics_cppr {
  83. unsigned char stack[MAX_NUM_PRIORITIES];
  84. int index;
  85. };
  86. DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
  87. static inline void xics_push_cppr(unsigned int vec)
  88. {
  89. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  90. if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
  91. return;
  92. if (vec == XICS_IPI)
  93. os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
  94. else
  95. os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
  96. }
  97. static inline unsigned char xics_pop_cppr(void)
  98. {
  99. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  100. if (WARN_ON(os_cppr->index < 1))
  101. return LOWEST_PRIORITY;
  102. return os_cppr->stack[--os_cppr->index];
  103. }
  104. static inline void xics_set_base_cppr(unsigned char cppr)
  105. {
  106. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  107. /* we only really want to set the priority when there's
  108. * just one cppr value on the stack
  109. */
  110. WARN_ON(os_cppr->index != 0);
  111. os_cppr->stack[0] = cppr;
  112. }
  113. static inline unsigned char xics_cppr_top(void)
  114. {
  115. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  116. return os_cppr->stack[os_cppr->index];
  117. }
  118. DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
  119. extern void xics_init(void);
  120. extern void xics_setup_cpu(void);
  121. extern void xics_update_irq_servers(void);
  122. extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
  123. extern void xics_mask_unknown_vec(unsigned int vec);
  124. extern irqreturn_t xics_ipi_dispatch(int cpu);
  125. extern void xics_smp_probe(void);
  126. extern void xics_register_ics(struct ics *ics);
  127. extern void xics_teardown_cpu(void);
  128. extern void xics_kexec_teardown_cpu(int secondary);
  129. extern void xics_migrate_irqs_away(void);
  130. extern void icp_native_eoi(struct irq_data *d);
  131. extern int xics_set_irq_type(struct irq_data *d, unsigned int flow_type);
  132. extern int xics_retrigger(struct irq_data *data);
  133. #ifdef CONFIG_SMP
  134. extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
  135. unsigned int strict_check);
  136. #else
  137. #define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
  138. #endif
  139. #endif /* _XICS_H */