powerpc/xics: Rewrite XICS driver
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / powerpc / include / asm / xics.h
blob146aad8534de1e3dd2e384e52a85292f79564ae2
1 /*
2 * Common definitions accross all variants of ICP and ICS interrupt
3 * controllers.
4 */
6 #ifndef _XICS_H
7 #define _XICS_H
9 #define XICS_IPI 2
10 #define XICS_IRQ_SPURIOUS 0
12 /* Want a priority other than 0. Various HW issues require this. */
13 #define DEFAULT_PRIORITY 5
16 * Mark IPIs as higher priority so we can take them inside interrupts that
17 * arent marked IRQF_DISABLED
19 #define IPI_PRIORITY 4
21 /* The least favored priority */
22 #define LOWEST_PRIORITY 0xFF
24 /* The number of priorities defined above */
25 #define MAX_NUM_PRIORITIES 3
27 /* Native ICP */
28 extern int icp_native_init(void);
30 /* PAPR ICP */
31 extern int icp_hv_init(void);
33 /* ICP ops */
34 struct 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
46 extern const struct icp_ops *icp_ops;
48 /* Native ICS */
49 extern int ics_native_init(void);
51 /* RTAS ICS */
52 extern int ics_rtas_init(void);
54 /* ICS instance, hooked up to chip_data of an irq */
55 struct 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[];
63 /* Commons */
64 extern unsigned int xics_default_server;
65 extern unsigned int xics_default_distrib_server;
66 extern unsigned int xics_interrupt_server_size;
67 extern struct irq_host *xics_host;
69 struct xics_cppr {
70 unsigned char stack[MAX_NUM_PRIORITIES];
71 int index;
74 DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
76 static inline void xics_push_cppr(unsigned int vec)
78 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
80 if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
81 return;
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;
89 static inline unsigned char xics_pop_cppr(void)
91 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
93 if (WARN_ON(os_cppr->index < 1))
94 return LOWEST_PRIORITY;
96 return os_cppr->stack[--os_cppr->index];
99 static inline void xics_set_base_cppr(unsigned char cppr)
101 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
103 /* we only really want to set the priority when there's
104 * just one cppr value on the stack
106 WARN_ON(os_cppr->index != 0);
108 os_cppr->stack[0] = cppr;
111 static inline unsigned char xics_cppr_top(void)
113 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
115 return os_cppr->stack[os_cppr->index];
118 DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
120 extern void xics_init(void);
121 extern void xics_setup_cpu(void);
122 extern void xics_update_irq_servers(void);
123 extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
124 extern void xics_mask_unknown_vec(unsigned int vec);
125 extern irqreturn_t xics_ipi_dispatch(int cpu);
126 extern int xics_smp_probe(void);
127 extern void xics_register_ics(struct ics *ics);
128 extern void xics_teardown_cpu(void);
129 extern void xics_kexec_teardown_cpu(int secondary);
130 extern void xics_migrate_irqs_away(void);
131 #ifdef CONFIG_SMP
132 extern 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
139 #endif /* _XICS_H */