diff options
Diffstat (limited to 'arch/powerpc/include/asm')
-rw-r--r-- | arch/powerpc/include/asm/irq.h | 6 | ||||
-rw-r--r-- | arch/powerpc/include/asm/xics.h | 139 |
2 files changed, 145 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index 67ab5fb7d153..47b7905a6369 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
@@ -142,6 +142,12 @@ extern struct irq_map_entry irq_map[NR_IRQS]; | |||
142 | 142 | ||
143 | extern irq_hw_number_t virq_to_hw(unsigned int virq); | 143 | extern irq_hw_number_t virq_to_hw(unsigned int virq); |
144 | 144 | ||
145 | /* This will eventually -replace- virq_to_hw if/when we stash the | ||
146 | * HW number in the irq_data itself. We use a macro so we can inline | ||
147 | * it as irq_data isn't defined yet | ||
148 | */ | ||
149 | #define irq_data_to_hw(d) (irq_map[(d)->irq].hwirq) | ||
150 | |||
145 | /** | 151 | /** |
146 | * irq_alloc_host - Allocate a new irq_host data structure | 152 | * irq_alloc_host - Allocate a new irq_host data structure |
147 | * @of_node: optional device-tree node of the interrupt controller | 153 | * @of_node: optional device-tree node of the interrupt controller |
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h new file mode 100644 index 000000000000..146aad8534de --- /dev/null +++ b/arch/powerpc/include/asm/xics.h | |||
@@ -0,0 +1,139 @@ | |||
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 */ | ||
28 | extern int icp_native_init(void); | ||
29 | |||
30 | /* PAPR ICP */ | ||
31 | extern int icp_hv_init(void); | ||
32 | |||
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 | ||
44 | }; | ||
45 | |||
46 | extern const struct icp_ops *icp_ops; | ||
47 | |||
48 | /* Native ICS */ | ||
49 | extern int ics_native_init(void); | ||
50 | |||
51 | /* RTAS ICS */ | ||
52 | extern int ics_rtas_init(void); | ||
53 | |||
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[]; | ||
61 | }; | ||
62 | |||
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; | ||
68 | |||
69 | struct xics_cppr { | ||
70 | unsigned char stack[MAX_NUM_PRIORITIES]; | ||
71 | int index; | ||
72 | }; | ||
73 | |||
74 | DECLARE_PER_CPU(struct xics_cppr, xics_cppr); | ||
75 | |||
76 | static 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 | |||
89 | static 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 | |||
99 | static 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 | |||
111 | static 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 | |||
118 | DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message); | ||
119 | |||
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 | ||
137 | |||
138 | |||
139 | #endif /* _XICS_H */ | ||