diff options
Diffstat (limited to 'include/asm-powerpc/irq.h')
-rw-r--r-- | include/asm-powerpc/irq.h | 356 |
1 files changed, 306 insertions, 50 deletions
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 13fa2ef38dc7..e05754752028 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h | |||
@@ -9,26 +9,14 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | ||
12 | #include <linux/threads.h> | 13 | #include <linux/threads.h> |
14 | #include <linux/list.h> | ||
15 | #include <linux/radix-tree.h> | ||
13 | 16 | ||
14 | #include <asm/types.h> | 17 | #include <asm/types.h> |
15 | #include <asm/atomic.h> | 18 | #include <asm/atomic.h> |
16 | 19 | ||
17 | /* this number is used when no interrupt has been assigned */ | ||
18 | #define NO_IRQ (-1) | ||
19 | |||
20 | /* | ||
21 | * These constants are used for passing information about interrupt | ||
22 | * signal polarity and level/edge sensing to the low-level PIC chip | ||
23 | * drivers. | ||
24 | */ | ||
25 | #define IRQ_SENSE_MASK 0x1 | ||
26 | #define IRQ_SENSE_LEVEL 0x1 /* interrupt on active level */ | ||
27 | #define IRQ_SENSE_EDGE 0x0 /* interrupt triggered by edge */ | ||
28 | |||
29 | #define IRQ_POLARITY_MASK 0x2 | ||
30 | #define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */ | ||
31 | #define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */ | ||
32 | 20 | ||
33 | #define get_irq_desc(irq) (&irq_desc[(irq)]) | 21 | #define get_irq_desc(irq) (&irq_desc[(irq)]) |
34 | 22 | ||
@@ -36,50 +24,325 @@ | |||
36 | #define for_each_irq(i) \ | 24 | #define for_each_irq(i) \ |
37 | for ((i) = 0; (i) < NR_IRQS; ++(i)) | 25 | for ((i) = 0; (i) < NR_IRQS; ++(i)) |
38 | 26 | ||
39 | #ifdef CONFIG_PPC64 | 27 | extern atomic_t ppc_n_lost_interrupts; |
40 | 28 | ||
41 | /* | 29 | #ifdef CONFIG_PPC_MERGE |
42 | * Maximum number of interrupt sources that we can handle. | 30 | |
31 | /* This number is used when no interrupt has been assigned */ | ||
32 | #define NO_IRQ (0) | ||
33 | |||
34 | /* This is a special irq number to return from get_irq() to tell that | ||
35 | * no interrupt happened _and_ ignore it (don't count it as bad). Some | ||
36 | * platforms like iSeries rely on that. | ||
43 | */ | 37 | */ |
38 | #define NO_IRQ_IGNORE ((unsigned int)-1) | ||
39 | |||
40 | /* Total number of virq in the platform (make it a CONFIG_* option ? */ | ||
44 | #define NR_IRQS 512 | 41 | #define NR_IRQS 512 |
45 | 42 | ||
46 | /* Interrupt numbers are virtual in case they are sparsely | 43 | /* Number of irqs reserved for the legacy controller */ |
47 | * distributed by the hardware. | 44 | #define NUM_ISA_INTERRUPTS 16 |
45 | |||
46 | /* This type is the placeholder for a hardware interrupt number. It has to | ||
47 | * be big enough to enclose whatever representation is used by a given | ||
48 | * platform. | ||
49 | */ | ||
50 | typedef unsigned long irq_hw_number_t; | ||
51 | |||
52 | /* Interrupt controller "host" data structure. This could be defined as a | ||
53 | * irq domain controller. That is, it handles the mapping between hardware | ||
54 | * and virtual interrupt numbers for a given interrupt domain. The host | ||
55 | * structure is generally created by the PIC code for a given PIC instance | ||
56 | * (though a host can cover more than one PIC if they have a flat number | ||
57 | * model). It's the host callbacks that are responsible for setting the | ||
58 | * irq_chip on a given irq_desc after it's been mapped. | ||
59 | * | ||
60 | * The host code and data structures are fairly agnostic to the fact that | ||
61 | * we use an open firmware device-tree. We do have references to struct | ||
62 | * device_node in two places: in irq_find_host() to find the host matching | ||
63 | * a given interrupt controller node, and of course as an argument to its | ||
64 | * counterpart host->ops->match() callback. However, those are treated as | ||
65 | * generic pointers by the core and the fact that it's actually a device-node | ||
66 | * pointer is purely a convention between callers and implementation. This | ||
67 | * code could thus be used on other architectures by replacing those two | ||
68 | * by some sort of arch-specific void * "token" used to identify interrupt | ||
69 | * controllers. | ||
70 | */ | ||
71 | struct irq_host; | ||
72 | struct radix_tree_root; | ||
73 | |||
74 | /* Functions below are provided by the host and called whenever a new mapping | ||
75 | * is created or an old mapping is disposed. The host can then proceed to | ||
76 | * whatever internal data structures management is required. It also needs | ||
77 | * to setup the irq_desc when returning from map(). | ||
78 | */ | ||
79 | struct irq_host_ops { | ||
80 | /* Match an interrupt controller device node to a host, returns | ||
81 | * 1 on a match | ||
82 | */ | ||
83 | int (*match)(struct irq_host *h, struct device_node *node); | ||
84 | |||
85 | /* Create or update a mapping between a virtual irq number and a hw | ||
86 | * irq number. This can be called several times for the same mapping | ||
87 | * but with different flags, though unmap shall always be called | ||
88 | * before the virq->hw mapping is changed. | ||
89 | */ | ||
90 | int (*map)(struct irq_host *h, unsigned int virq, | ||
91 | irq_hw_number_t hw, unsigned int flags); | ||
92 | |||
93 | /* Dispose of such a mapping */ | ||
94 | void (*unmap)(struct irq_host *h, unsigned int virq); | ||
95 | |||
96 | /* Translate device-tree interrupt specifier from raw format coming | ||
97 | * from the firmware to a irq_hw_number_t (interrupt line number) and | ||
98 | * trigger flags that can be passed to irq_create_mapping(). | ||
99 | * If no translation is provided, raw format is assumed to be one cell | ||
100 | * for interrupt line and default sense. | ||
101 | */ | ||
102 | int (*xlate)(struct irq_host *h, struct device_node *ctrler, | ||
103 | u32 *intspec, unsigned int intsize, | ||
104 | irq_hw_number_t *out_hwirq, unsigned int *out_flags); | ||
105 | }; | ||
106 | |||
107 | struct irq_host { | ||
108 | struct list_head link; | ||
109 | |||
110 | /* type of reverse mapping technique */ | ||
111 | unsigned int revmap_type; | ||
112 | #define IRQ_HOST_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */ | ||
113 | #define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */ | ||
114 | #define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */ | ||
115 | #define IRQ_HOST_MAP_TREE 3 /* radix tree */ | ||
116 | union { | ||
117 | struct { | ||
118 | unsigned int size; | ||
119 | unsigned int *revmap; | ||
120 | } linear; | ||
121 | struct radix_tree_root tree; | ||
122 | } revmap_data; | ||
123 | struct irq_host_ops *ops; | ||
124 | void *host_data; | ||
125 | irq_hw_number_t inval_irq; | ||
126 | }; | ||
127 | |||
128 | /* The main irq map itself is an array of NR_IRQ entries containing the | ||
129 | * associate host and irq number. An entry with a host of NULL is free. | ||
130 | * An entry can be allocated if it's free, the allocator always then sets | ||
131 | * hwirq first to the host's invalid irq number and then fills ops. | ||
132 | */ | ||
133 | struct irq_map_entry { | ||
134 | irq_hw_number_t hwirq; | ||
135 | struct irq_host *host; | ||
136 | }; | ||
137 | |||
138 | extern struct irq_map_entry irq_map[NR_IRQS]; | ||
139 | |||
140 | |||
141 | /*** | ||
142 | * irq_alloc_host - Allocate a new irq_host data structure | ||
143 | * @node: device-tree node of the interrupt controller | ||
144 | * @revmap_type: type of reverse mapping to use | ||
145 | * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map | ||
146 | * @ops: map/unmap host callbacks | ||
147 | * @inval_irq: provide a hw number in that host space that is always invalid | ||
148 | * | ||
149 | * Allocates and initialize and irq_host structure. Note that in the case of | ||
150 | * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns | ||
151 | * for all legacy interrupts except 0 (which is always the invalid irq for | ||
152 | * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by | ||
153 | * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated | ||
154 | * later during boot automatically (the reverse mapping will use the slow path | ||
155 | * until that happens). | ||
156 | */ | ||
157 | extern struct irq_host *irq_alloc_host(unsigned int revmap_type, | ||
158 | unsigned int revmap_arg, | ||
159 | struct irq_host_ops *ops, | ||
160 | irq_hw_number_t inval_irq); | ||
161 | |||
162 | |||
163 | /*** | ||
164 | * irq_find_host - Locates a host for a given device node | ||
165 | * @node: device-tree node of the interrupt controller | ||
166 | */ | ||
167 | extern struct irq_host *irq_find_host(struct device_node *node); | ||
168 | |||
169 | |||
170 | /*** | ||
171 | * irq_set_default_host - Set a "default" host | ||
172 | * @host: default host pointer | ||
173 | * | ||
174 | * For convenience, it's possible to set a "default" host that will be used | ||
175 | * whenever NULL is passed to irq_create_mapping(). It makes life easier for | ||
176 | * platforms that want to manipulate a few hard coded interrupt numbers that | ||
177 | * aren't properly represented in the device-tree. | ||
178 | */ | ||
179 | extern void irq_set_default_host(struct irq_host *host); | ||
180 | |||
181 | |||
182 | /*** | ||
183 | * irq_set_virq_count - Set the maximum number of virt irqs | ||
184 | * @count: number of linux virtual irqs, capped with NR_IRQS | ||
185 | * | ||
186 | * This is mainly for use by platforms like iSeries who want to program | ||
187 | * the virtual irq number in the controller to avoid the reverse mapping | ||
188 | */ | ||
189 | extern void irq_set_virq_count(unsigned int count); | ||
190 | |||
191 | |||
192 | /*** | ||
193 | * irq_create_mapping - Map a hardware interrupt into linux virq space | ||
194 | * @host: host owning this hardware interrupt or NULL for default host | ||
195 | * @hwirq: hardware irq number in that host space | ||
196 | * @flags: flags passed to the controller. contains the trigger type among | ||
197 | * others. Use IRQ_TYPE_* defined in include/linux/irq.h | ||
198 | * | ||
199 | * Only one mapping per hardware interrupt is permitted. Returns a linux | ||
200 | * virq number. The flags can be used to provide sense information to the | ||
201 | * controller (typically extracted from the device-tree). If no information | ||
202 | * is passed, the controller defaults will apply (for example, xics can only | ||
203 | * do edge so flags are irrelevant for some pseries specific irqs). | ||
204 | * | ||
205 | * The device-tree generally contains the trigger info in an encoding that is | ||
206 | * specific to a given type of controller. In that case, you can directly use | ||
207 | * host->ops->trigger_xlate() to translate that. | ||
208 | * | ||
209 | * It is recommended that new PICs that don't have existing OF bindings chose | ||
210 | * to use a representation of triggers identical to linux. | ||
211 | */ | ||
212 | extern unsigned int irq_create_mapping(struct irq_host *host, | ||
213 | irq_hw_number_t hwirq, | ||
214 | unsigned int flags); | ||
215 | |||
216 | |||
217 | /*** | ||
218 | * irq_dispose_mapping - Unmap an interrupt | ||
219 | * @virq: linux virq number of the interrupt to unmap | ||
48 | */ | 220 | */ |
49 | extern unsigned int virt_irq_to_real_map[NR_IRQS]; | 221 | extern void irq_dispose_mapping(unsigned int virq); |
50 | 222 | ||
51 | /* The maximum virtual IRQ number that we support. This | 223 | /*** |
52 | * can be set by the platform and will be reduced by the | 224 | * irq_find_mapping - Find a linux virq from an hw irq number. |
53 | * value of __irq_offset_value. It defaults to and is | 225 | * @host: host owning this hardware interrupt |
54 | * capped by (NR_IRQS - 1). | 226 | * @hwirq: hardware irq number in that host space |
227 | * | ||
228 | * This is a slow path, for use by generic code. It's expected that an | ||
229 | * irq controller implementation directly calls the appropriate low level | ||
230 | * mapping function. | ||
55 | */ | 231 | */ |
56 | extern unsigned int virt_irq_max; | 232 | extern unsigned int irq_find_mapping(struct irq_host *host, |
233 | irq_hw_number_t hwirq); | ||
57 | 234 | ||
58 | /* Create a mapping for a real_irq if it doesn't already exist. | 235 | |
59 | * Return the virtual irq as a convenience. | 236 | /*** |
237 | * irq_radix_revmap - Find a linux virq from a hw irq number. | ||
238 | * @host: host owning this hardware interrupt | ||
239 | * @hwirq: hardware irq number in that host space | ||
240 | * | ||
241 | * This is a fast path, for use by irq controller code that uses radix tree | ||
242 | * revmaps | ||
243 | */ | ||
244 | extern unsigned int irq_radix_revmap(struct irq_host *host, | ||
245 | irq_hw_number_t hwirq); | ||
246 | |||
247 | /*** | ||
248 | * irq_linear_revmap - Find a linux virq from a hw irq number. | ||
249 | * @host: host owning this hardware interrupt | ||
250 | * @hwirq: hardware irq number in that host space | ||
251 | * | ||
252 | * This is a fast path, for use by irq controller code that uses linear | ||
253 | * revmaps. It does fallback to the slow path if the revmap doesn't exist | ||
254 | * yet and will create the revmap entry with appropriate locking | ||
255 | */ | ||
256 | |||
257 | extern unsigned int irq_linear_revmap(struct irq_host *host, | ||
258 | irq_hw_number_t hwirq); | ||
259 | |||
260 | |||
261 | |||
262 | /*** | ||
263 | * irq_alloc_virt - Allocate virtual irq numbers | ||
264 | * @host: host owning these new virtual irqs | ||
265 | * @count: number of consecutive numbers to allocate | ||
266 | * @hint: pass a hint number, the allocator will try to use a 1:1 mapping | ||
267 | * | ||
268 | * This is a low level function that is used internally by irq_create_mapping() | ||
269 | * and that can be used by some irq controllers implementations for things | ||
270 | * like allocating ranges of numbers for MSIs. The revmaps are left untouched. | ||
60 | */ | 271 | */ |
61 | int virt_irq_create_mapping(unsigned int real_irq); | 272 | extern unsigned int irq_alloc_virt(struct irq_host *host, |
62 | void virt_irq_init(void); | 273 | unsigned int count, |
274 | unsigned int hint); | ||
275 | |||
276 | /*** | ||
277 | * irq_free_virt - Free virtual irq numbers | ||
278 | * @virq: virtual irq number of the first interrupt to free | ||
279 | * @count: number of interrupts to free | ||
280 | * | ||
281 | * This function is the opposite of irq_alloc_virt. It will not clear reverse | ||
282 | * maps, this should be done previously by unmap'ing the interrupt. In fact, | ||
283 | * all interrupts covered by the range being freed should have been unmapped | ||
284 | * prior to calling this. | ||
285 | */ | ||
286 | extern void irq_free_virt(unsigned int virq, unsigned int count); | ||
287 | |||
288 | |||
289 | /* -- OF helpers -- */ | ||
290 | |||
291 | /* irq_create_of_mapping - Map a hardware interrupt into linux virq space | ||
292 | * @controller: Device node of the interrupt controller | ||
293 | * @inspec: Interrupt specifier from the device-tree | ||
294 | * @intsize: Size of the interrupt specifier from the device-tree | ||
295 | * | ||
296 | * This function is identical to irq_create_mapping except that it takes | ||
297 | * as input informations straight from the device-tree (typically the results | ||
298 | * of the of_irq_map_*() functions | ||
299 | */ | ||
300 | extern unsigned int irq_create_of_mapping(struct device_node *controller, | ||
301 | u32 *intspec, unsigned int intsize); | ||
302 | |||
303 | |||
304 | /* irq_of_parse_and_map - Parse nad Map an interrupt into linux virq space | ||
305 | * @device: Device node of the device whose interrupt is to be mapped | ||
306 | * @index: Index of the interrupt to map | ||
307 | * | ||
308 | * This function is a wrapper that chains of_irq_map_one() and | ||
309 | * irq_create_of_mapping() to make things easier to callers | ||
310 | */ | ||
311 | extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); | ||
312 | |||
313 | /* -- End OF helpers -- */ | ||
63 | 314 | ||
64 | static inline unsigned int virt_irq_to_real(unsigned int virt_irq) | 315 | /*** |
316 | * irq_early_init - Init irq remapping subsystem | ||
317 | */ | ||
318 | extern void irq_early_init(void); | ||
319 | |||
320 | static __inline__ int irq_canonicalize(int irq) | ||
65 | { | 321 | { |
66 | return virt_irq_to_real_map[virt_irq]; | 322 | return irq; |
67 | } | 323 | } |
68 | 324 | ||
69 | extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq); | 325 | |
326 | #else /* CONFIG_PPC_MERGE */ | ||
327 | |||
328 | /* This number is used when no interrupt has been assigned */ | ||
329 | #define NO_IRQ (-1) | ||
330 | #define NO_IRQ_IGNORE (-2) | ||
331 | |||
70 | 332 | ||
71 | /* | 333 | /* |
72 | * List of interrupt controllers. | 334 | * These constants are used for passing information about interrupt |
335 | * signal polarity and level/edge sensing to the low-level PIC chip | ||
336 | * drivers. | ||
73 | */ | 337 | */ |
74 | #define IC_INVALID 0 | 338 | #define IRQ_SENSE_MASK 0x1 |
75 | #define IC_OPEN_PIC 1 | 339 | #define IRQ_SENSE_LEVEL 0x1 /* interrupt on active level */ |
76 | #define IC_PPC_XIC 2 | 340 | #define IRQ_SENSE_EDGE 0x0 /* interrupt triggered by edge */ |
77 | #define IC_CELL_PIC 3 | ||
78 | #define IC_ISERIES 4 | ||
79 | 341 | ||
80 | extern u64 ppc64_interrupt_controller; | 342 | #define IRQ_POLARITY_MASK 0x2 |
343 | #define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */ | ||
344 | #define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */ | ||
81 | 345 | ||
82 | #else /* 32-bit */ | ||
83 | 346 | ||
84 | #if defined(CONFIG_40x) | 347 | #if defined(CONFIG_40x) |
85 | #include <asm/ibm4xx.h> | 348 | #include <asm/ibm4xx.h> |
@@ -512,19 +775,11 @@ extern u64 ppc64_interrupt_controller; | |||
512 | 775 | ||
513 | #endif /* CONFIG_8260 */ | 776 | #endif /* CONFIG_8260 */ |
514 | 777 | ||
515 | #endif | 778 | #endif /* Whatever way too big #ifdef */ |
516 | 779 | ||
517 | #ifndef CONFIG_PPC_MERGE | ||
518 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 780 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) |
519 | /* pedantic: these are long because they are used with set_bit --RR */ | 781 | /* pedantic: these are long because they are used with set_bit --RR */ |
520 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | 782 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; |
521 | #endif | ||
522 | |||
523 | extern atomic_t ppc_n_lost_interrupts; | ||
524 | |||
525 | #define virt_irq_create_mapping(x) (x) | ||
526 | |||
527 | #endif | ||
528 | 783 | ||
529 | /* | 784 | /* |
530 | * Because many systems have two overlapping names spaces for | 785 | * Because many systems have two overlapping names spaces for |
@@ -563,6 +818,7 @@ static __inline__ int irq_canonicalize(int irq) | |||
563 | irq = 9; | 818 | irq = 9; |
564 | return irq; | 819 | return irq; |
565 | } | 820 | } |
821 | #endif /* CONFIG_PPC_MERGE */ | ||
566 | 822 | ||
567 | extern int distribute_irqs; | 823 | extern int distribute_irqs; |
568 | 824 | ||