diff options
Diffstat (limited to 'include/asm-powerpc/irq.h')
| -rw-r--r-- | include/asm-powerpc/irq.h | 358 |
1 files changed, 308 insertions, 50 deletions
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index eb5f33e1977a..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. | ||
| 48 | */ | 70 | */ |
| 49 | extern unsigned int virt_irq_to_real_map[NR_IRQS]; | 71 | struct irq_host; |
| 72 | struct radix_tree_root; | ||
| 50 | 73 | ||
| 51 | /* The maximum virtual IRQ number that we support. This | 74 | /* Functions below are provided by the host and called whenever a new mapping |
| 52 | * can be set by the platform and will be reduced by the | 75 | * is created or an old mapping is disposed. The host can then proceed to |
| 53 | * value of __irq_offset_value. It defaults to and is | 76 | * whatever internal data structures management is required. It also needs |
| 54 | * capped by (NR_IRQS - 1). | 77 | * to setup the irq_desc when returning from map(). |
| 55 | */ | 78 | */ |
| 56 | extern unsigned int virt_irq_max; | 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 | |||
| 57 | 140 | ||
| 58 | /* Create a mapping for a real_irq if it doesn't already exist. | 141 | /*** |
| 59 | * Return the virtual irq as a convenience. | 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 | ||
| 220 | */ | ||
| 221 | extern void irq_dispose_mapping(unsigned int virq); | ||
| 222 | |||
| 223 | /*** | ||
| 224 | * irq_find_mapping - Find a linux virq from an hw irq number. | ||
| 225 | * @host: host owning this hardware interrupt | ||
| 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. | ||
| 60 | */ | 231 | */ |
| 61 | int virt_irq_create_mapping(unsigned int real_irq); | 232 | extern unsigned int irq_find_mapping(struct irq_host *host, |
| 62 | void virt_irq_init(void); | 233 | irq_hw_number_t hwirq); |
| 63 | 234 | ||
| 64 | static inline unsigned int virt_irq_to_real(unsigned int virt_irq) | 235 | |
| 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. | ||
| 271 | */ | ||
| 272 | extern unsigned int irq_alloc_virt(struct irq_host *host, | ||
| 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 -- */ | ||
| 314 | |||
| 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,16 +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 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 780 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) |
| 518 | /* 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 */ |
| 519 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | 782 | extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; |
| 520 | extern atomic_t ppc_n_lost_interrupts; | ||
| 521 | |||
| 522 | #define virt_irq_create_mapping(x) (x) | ||
| 523 | |||
| 524 | #endif | ||
| 525 | 783 | ||
| 526 | /* | 784 | /* |
| 527 | * Because many systems have two overlapping names spaces for | 785 | * Because many systems have two overlapping names spaces for |
| @@ -560,6 +818,7 @@ static __inline__ int irq_canonicalize(int irq) | |||
| 560 | irq = 9; | 818 | irq = 9; |
| 561 | return irq; | 819 | return irq; |
| 562 | } | 820 | } |
| 821 | #endif /* CONFIG_PPC_MERGE */ | ||
| 563 | 822 | ||
| 564 | extern int distribute_irqs; | 823 | extern int distribute_irqs; |
| 565 | 824 | ||
| @@ -579,9 +838,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS]; | |||
| 579 | 838 | ||
| 580 | extern void irq_ctx_init(void); | 839 | extern void irq_ctx_init(void); |
| 581 | extern void call_do_softirq(struct thread_info *tp); | 840 | extern void call_do_softirq(struct thread_info *tp); |
| 582 | extern int call___do_IRQ(int irq, struct pt_regs *regs, | 841 | extern int call_handle_irq(int irq, void *p1, void *p2, |
| 583 | struct thread_info *tp); | 842 | struct thread_info *tp, void *func); |
| 584 | |||
| 585 | #else | 843 | #else |
| 586 | #define irq_ctx_init() | 844 | #define irq_ctx_init() |
| 587 | 845 | ||
