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