xics.h 4.4 KB

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