xics.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Common definitions accross 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. /* ICP ops */
  36. struct icp_ops {
  37. unsigned int (*get_irq)(void);
  38. void (*eoi)(struct irq_data *d);
  39. void (*set_priority)(unsigned char prio);
  40. void (*teardown_cpu)(void);
  41. void (*flush_ipi)(void);
  42. #ifdef CONFIG_SMP
  43. void (*cause_ipi)(int cpu, unsigned long data);
  44. irq_handler_t ipi_action;
  45. #endif
  46. };
  47. extern const struct icp_ops *icp_ops;
  48. /* Native ICS */
  49. extern int ics_native_init(void);
  50. /* RTAS ICS */
  51. #ifdef CONFIG_PPC_ICS_RTAS
  52. extern int ics_rtas_init(void);
  53. #else
  54. static inline int ics_rtas_init(void) { return -ENODEV; }
  55. #endif
  56. /* HAL ICS */
  57. #ifdef CONFIG_PPC_POWERNV
  58. extern int ics_opal_init(void);
  59. #else
  60. static inline int ics_opal_init(void) { return -ENODEV; }
  61. #endif
  62. /* ICS instance, hooked up to chip_data of an irq */
  63. struct ics {
  64. struct list_head link;
  65. int (*map)(struct ics *ics, unsigned int virq);
  66. void (*mask_unknown)(struct ics *ics, unsigned long vec);
  67. long (*get_server)(struct ics *ics, unsigned long vec);
  68. int (*host_match)(struct ics *ics, struct device_node *node);
  69. char data[];
  70. };
  71. /* Commons */
  72. extern unsigned int xics_default_server;
  73. extern unsigned int xics_default_distrib_server;
  74. extern unsigned int xics_interrupt_server_size;
  75. extern struct irq_domain *xics_host;
  76. struct xics_cppr {
  77. unsigned char stack[MAX_NUM_PRIORITIES];
  78. int index;
  79. };
  80. DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
  81. static inline void xics_push_cppr(unsigned int vec)
  82. {
  83. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  84. if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
  85. return;
  86. if (vec == XICS_IPI)
  87. os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
  88. else
  89. os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
  90. }
  91. static inline unsigned char xics_pop_cppr(void)
  92. {
  93. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  94. if (WARN_ON(os_cppr->index < 1))
  95. return LOWEST_PRIORITY;
  96. return os_cppr->stack[--os_cppr->index];
  97. }
  98. static inline void xics_set_base_cppr(unsigned char cppr)
  99. {
  100. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  101. /* we only really want to set the priority when there's
  102. * just one cppr value on the stack
  103. */
  104. WARN_ON(os_cppr->index != 0);
  105. os_cppr->stack[0] = cppr;
  106. }
  107. static inline unsigned char xics_cppr_top(void)
  108. {
  109. struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
  110. return os_cppr->stack[os_cppr->index];
  111. }
  112. DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
  113. extern void xics_init(void);
  114. extern void xics_setup_cpu(void);
  115. extern void xics_update_irq_servers(void);
  116. extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
  117. extern void xics_mask_unknown_vec(unsigned int vec);
  118. extern irqreturn_t xics_ipi_dispatch(int cpu);
  119. extern void xics_smp_probe(void);
  120. extern void xics_register_ics(struct ics *ics);
  121. extern void xics_teardown_cpu(void);
  122. extern void xics_kexec_teardown_cpu(int secondary);
  123. extern void xics_migrate_irqs_away(void);
  124. extern void icp_native_eoi(struct irq_data *d);
  125. #ifdef CONFIG_SMP
  126. extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
  127. unsigned int strict_check);
  128. #else
  129. #define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
  130. #endif
  131. #endif /* _XICS_H */