aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc/irq.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-powerpc/irq.h')
-rw-r--r--include/asm-powerpc/irq.h356
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 27extern 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 */
50typedef 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 */
71struct irq_host;
72struct 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 */
79struct 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
107struct 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 */
133struct irq_map_entry {
134 irq_hw_number_t hwirq;
135 struct irq_host *host;
136};
137
138extern 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 */
157extern 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 */
167extern 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 */
179extern 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 */
189extern 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 */
212extern 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 */
49extern unsigned int virt_irq_to_real_map[NR_IRQS]; 221extern 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 */
56extern unsigned int virt_irq_max; 232extern 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 */
244extern 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
257extern 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 */
61int virt_irq_create_mapping(unsigned int real_irq); 272extern unsigned int irq_alloc_virt(struct irq_host *host,
62void 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 */
286extern 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 */
300extern 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 */
311extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
312
313/* -- End OF helpers -- */
63 314
64static inline unsigned int virt_irq_to_real(unsigned int virt_irq) 315/***
316 * irq_early_init - Init irq remapping subsystem
317 */
318extern void irq_early_init(void);
319
320static __inline__ int irq_canonicalize(int irq)
65{ 321{
66 return virt_irq_to_real_map[virt_irq]; 322 return irq;
67} 323}
68 324
69extern 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
80extern 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 */
520extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 782extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
521#endif
522
523extern 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
567extern int distribute_irqs; 823extern int distribute_irqs;
568 824