1*3bd3b99aSMauro Carvalho Chehab.. include:: <isonum.txt> 2*3bd3b99aSMauro Carvalho Chehab 3*3bd3b99aSMauro Carvalho Chehab========================== 4*3bd3b99aSMauro Carvalho ChehabLinux generic IRQ handling 5*3bd3b99aSMauro Carvalho Chehab========================== 6*3bd3b99aSMauro Carvalho Chehab 7*3bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2010: Thomas Gleixner 8*3bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2006: Ingo Molnar 9*3bd3b99aSMauro Carvalho Chehab 10*3bd3b99aSMauro Carvalho ChehabIntroduction 11*3bd3b99aSMauro Carvalho Chehab============ 12*3bd3b99aSMauro Carvalho Chehab 13*3bd3b99aSMauro Carvalho ChehabThe generic interrupt handling layer is designed to provide a complete 14*3bd3b99aSMauro Carvalho Chehababstraction of interrupt handling for device drivers. It is able to 15*3bd3b99aSMauro Carvalho Chehabhandle all the different types of interrupt controller hardware. Device 16*3bd3b99aSMauro Carvalho Chehabdrivers use generic API functions to request, enable, disable and free 17*3bd3b99aSMauro Carvalho Chehabinterrupts. The drivers do not have to know anything about interrupt 18*3bd3b99aSMauro Carvalho Chehabhardware details, so they can be used on different platforms without 19*3bd3b99aSMauro Carvalho Chehabcode changes. 20*3bd3b99aSMauro Carvalho Chehab 21*3bd3b99aSMauro Carvalho ChehabThis documentation is provided to developers who want to implement an 22*3bd3b99aSMauro Carvalho Chehabinterrupt subsystem based for their architecture, with the help of the 23*3bd3b99aSMauro Carvalho Chehabgeneric IRQ handling layer. 24*3bd3b99aSMauro Carvalho Chehab 25*3bd3b99aSMauro Carvalho ChehabRationale 26*3bd3b99aSMauro Carvalho Chehab========= 27*3bd3b99aSMauro Carvalho Chehab 28*3bd3b99aSMauro Carvalho ChehabThe original implementation of interrupt handling in Linux uses the 29*3bd3b99aSMauro Carvalho Chehab__do_IRQ() super-handler, which is able to deal with every type of 30*3bd3b99aSMauro Carvalho Chehabinterrupt logic. 31*3bd3b99aSMauro Carvalho Chehab 32*3bd3b99aSMauro Carvalho ChehabOriginally, Russell King identified different types of handlers to build 33*3bd3b99aSMauro Carvalho Chehaba quite universal set for the ARM interrupt handler implementation in 34*3bd3b99aSMauro Carvalho ChehabLinux 2.5/2.6. He distinguished between: 35*3bd3b99aSMauro Carvalho Chehab 36*3bd3b99aSMauro Carvalho Chehab- Level type 37*3bd3b99aSMauro Carvalho Chehab 38*3bd3b99aSMauro Carvalho Chehab- Edge type 39*3bd3b99aSMauro Carvalho Chehab 40*3bd3b99aSMauro Carvalho Chehab- Simple type 41*3bd3b99aSMauro Carvalho Chehab 42*3bd3b99aSMauro Carvalho ChehabDuring the implementation we identified another type: 43*3bd3b99aSMauro Carvalho Chehab 44*3bd3b99aSMauro Carvalho Chehab- Fast EOI type 45*3bd3b99aSMauro Carvalho Chehab 46*3bd3b99aSMauro Carvalho ChehabIn the SMP world of the __do_IRQ() super-handler another type was 47*3bd3b99aSMauro Carvalho Chehabidentified: 48*3bd3b99aSMauro Carvalho Chehab 49*3bd3b99aSMauro Carvalho Chehab- Per CPU type 50*3bd3b99aSMauro Carvalho Chehab 51*3bd3b99aSMauro Carvalho ChehabThis split implementation of high-level IRQ handlers allows us to 52*3bd3b99aSMauro Carvalho Chehaboptimize the flow of the interrupt handling for each specific interrupt 53*3bd3b99aSMauro Carvalho Chehabtype. This reduces complexity in that particular code path and allows 54*3bd3b99aSMauro Carvalho Chehabthe optimized handling of a given type. 55*3bd3b99aSMauro Carvalho Chehab 56*3bd3b99aSMauro Carvalho ChehabThe original general IRQ implementation used hw_interrupt_type 57*3bd3b99aSMauro Carvalho Chehabstructures and their ->ack(), ->end() [etc.] callbacks to differentiate 58*3bd3b99aSMauro Carvalho Chehabthe flow control in the super-handler. This leads to a mix of flow logic 59*3bd3b99aSMauro Carvalho Chehaband low-level hardware logic, and it also leads to unnecessary code 60*3bd3b99aSMauro Carvalho Chehabduplication: for example in i386, there is an ioapic_level_irq and an 61*3bd3b99aSMauro Carvalho Chehabioapic_edge_irq IRQ-type which share many of the low-level details but 62*3bd3b99aSMauro Carvalho Chehabhave different flow handling. 63*3bd3b99aSMauro Carvalho Chehab 64*3bd3b99aSMauro Carvalho ChehabA more natural abstraction is the clean separation of the 'irq flow' and 65*3bd3b99aSMauro Carvalho Chehabthe 'chip details'. 66*3bd3b99aSMauro Carvalho Chehab 67*3bd3b99aSMauro Carvalho ChehabAnalysing a couple of architecture's IRQ subsystem implementations 68*3bd3b99aSMauro Carvalho Chehabreveals that most of them can use a generic set of 'irq flow' methods 69*3bd3b99aSMauro Carvalho Chehaband only need to add the chip-level specific code. The separation is 70*3bd3b99aSMauro Carvalho Chehabalso valuable for (sub)architectures which need specific quirks in the 71*3bd3b99aSMauro Carvalho ChehabIRQ flow itself but not in the chip details - and thus provides a more 72*3bd3b99aSMauro Carvalho Chehabtransparent IRQ subsystem design. 73*3bd3b99aSMauro Carvalho Chehab 74*3bd3b99aSMauro Carvalho ChehabEach interrupt descriptor is assigned its own high-level flow handler, 75*3bd3b99aSMauro Carvalho Chehabwhich is normally one of the generic implementations. (This high-level 76*3bd3b99aSMauro Carvalho Chehabflow handler implementation also makes it simple to provide 77*3bd3b99aSMauro Carvalho Chehabdemultiplexing handlers which can be found in embedded platforms on 78*3bd3b99aSMauro Carvalho Chehabvarious architectures.) 79*3bd3b99aSMauro Carvalho Chehab 80*3bd3b99aSMauro Carvalho ChehabThe separation makes the generic interrupt handling layer more flexible 81*3bd3b99aSMauro Carvalho Chehaband extensible. For example, an (sub)architecture can use a generic 82*3bd3b99aSMauro Carvalho ChehabIRQ-flow implementation for 'level type' interrupts and add a 83*3bd3b99aSMauro Carvalho Chehab(sub)architecture specific 'edge type' implementation. 84*3bd3b99aSMauro Carvalho Chehab 85*3bd3b99aSMauro Carvalho ChehabTo make the transition to the new model easier and prevent the breakage 86*3bd3b99aSMauro Carvalho Chehabof existing implementations, the __do_IRQ() super-handler is still 87*3bd3b99aSMauro Carvalho Chehabavailable. This leads to a kind of duality for the time being. Over time 88*3bd3b99aSMauro Carvalho Chehabthe new model should be used in more and more architectures, as it 89*3bd3b99aSMauro Carvalho Chehabenables smaller and cleaner IRQ subsystems. It's deprecated for three 90*3bd3b99aSMauro Carvalho Chehabyears now and about to be removed. 91*3bd3b99aSMauro Carvalho Chehab 92*3bd3b99aSMauro Carvalho ChehabKnown Bugs And Assumptions 93*3bd3b99aSMauro Carvalho Chehab========================== 94*3bd3b99aSMauro Carvalho Chehab 95*3bd3b99aSMauro Carvalho ChehabNone (knock on wood). 96*3bd3b99aSMauro Carvalho Chehab 97*3bd3b99aSMauro Carvalho ChehabAbstraction layers 98*3bd3b99aSMauro Carvalho Chehab================== 99*3bd3b99aSMauro Carvalho Chehab 100*3bd3b99aSMauro Carvalho ChehabThere are three main levels of abstraction in the interrupt code: 101*3bd3b99aSMauro Carvalho Chehab 102*3bd3b99aSMauro Carvalho Chehab1. High-level driver API 103*3bd3b99aSMauro Carvalho Chehab 104*3bd3b99aSMauro Carvalho Chehab2. High-level IRQ flow handlers 105*3bd3b99aSMauro Carvalho Chehab 106*3bd3b99aSMauro Carvalho Chehab3. Chip-level hardware encapsulation 107*3bd3b99aSMauro Carvalho Chehab 108*3bd3b99aSMauro Carvalho ChehabInterrupt control flow 109*3bd3b99aSMauro Carvalho Chehab---------------------- 110*3bd3b99aSMauro Carvalho Chehab 111*3bd3b99aSMauro Carvalho ChehabEach interrupt is described by an interrupt descriptor structure 112*3bd3b99aSMauro Carvalho Chehabirq_desc. The interrupt is referenced by an 'unsigned int' numeric 113*3bd3b99aSMauro Carvalho Chehabvalue which selects the corresponding interrupt description structure in 114*3bd3b99aSMauro Carvalho Chehabthe descriptor structures array. The descriptor structure contains 115*3bd3b99aSMauro Carvalho Chehabstatus information and pointers to the interrupt flow method and the 116*3bd3b99aSMauro Carvalho Chehabinterrupt chip structure which are assigned to this interrupt. 117*3bd3b99aSMauro Carvalho Chehab 118*3bd3b99aSMauro Carvalho ChehabWhenever an interrupt triggers, the low-level architecture code calls 119*3bd3b99aSMauro Carvalho Chehabinto the generic interrupt code by calling desc->handle_irq(). This 120*3bd3b99aSMauro Carvalho Chehabhigh-level IRQ handling function only uses desc->irq_data.chip 121*3bd3b99aSMauro Carvalho Chehabprimitives referenced by the assigned chip descriptor structure. 122*3bd3b99aSMauro Carvalho Chehab 123*3bd3b99aSMauro Carvalho ChehabHigh-level Driver API 124*3bd3b99aSMauro Carvalho Chehab--------------------- 125*3bd3b99aSMauro Carvalho Chehab 126*3bd3b99aSMauro Carvalho ChehabThe high-level Driver API consists of following functions: 127*3bd3b99aSMauro Carvalho Chehab 128*3bd3b99aSMauro Carvalho Chehab- request_irq() 129*3bd3b99aSMauro Carvalho Chehab 130*3bd3b99aSMauro Carvalho Chehab- free_irq() 131*3bd3b99aSMauro Carvalho Chehab 132*3bd3b99aSMauro Carvalho Chehab- disable_irq() 133*3bd3b99aSMauro Carvalho Chehab 134*3bd3b99aSMauro Carvalho Chehab- enable_irq() 135*3bd3b99aSMauro Carvalho Chehab 136*3bd3b99aSMauro Carvalho Chehab- disable_irq_nosync() (SMP only) 137*3bd3b99aSMauro Carvalho Chehab 138*3bd3b99aSMauro Carvalho Chehab- synchronize_irq() (SMP only) 139*3bd3b99aSMauro Carvalho Chehab 140*3bd3b99aSMauro Carvalho Chehab- irq_set_irq_type() 141*3bd3b99aSMauro Carvalho Chehab 142*3bd3b99aSMauro Carvalho Chehab- irq_set_irq_wake() 143*3bd3b99aSMauro Carvalho Chehab 144*3bd3b99aSMauro Carvalho Chehab- irq_set_handler_data() 145*3bd3b99aSMauro Carvalho Chehab 146*3bd3b99aSMauro Carvalho Chehab- irq_set_chip() 147*3bd3b99aSMauro Carvalho Chehab 148*3bd3b99aSMauro Carvalho Chehab- irq_set_chip_data() 149*3bd3b99aSMauro Carvalho Chehab 150*3bd3b99aSMauro Carvalho ChehabSee the autogenerated function documentation for details. 151*3bd3b99aSMauro Carvalho Chehab 152*3bd3b99aSMauro Carvalho ChehabHigh-level IRQ flow handlers 153*3bd3b99aSMauro Carvalho Chehab---------------------------- 154*3bd3b99aSMauro Carvalho Chehab 155*3bd3b99aSMauro Carvalho ChehabThe generic layer provides a set of pre-defined irq-flow methods: 156*3bd3b99aSMauro Carvalho Chehab 157*3bd3b99aSMauro Carvalho Chehab- handle_level_irq 158*3bd3b99aSMauro Carvalho Chehab 159*3bd3b99aSMauro Carvalho Chehab- handle_edge_irq 160*3bd3b99aSMauro Carvalho Chehab 161*3bd3b99aSMauro Carvalho Chehab- handle_fasteoi_irq 162*3bd3b99aSMauro Carvalho Chehab 163*3bd3b99aSMauro Carvalho Chehab- handle_simple_irq 164*3bd3b99aSMauro Carvalho Chehab 165*3bd3b99aSMauro Carvalho Chehab- handle_percpu_irq 166*3bd3b99aSMauro Carvalho Chehab 167*3bd3b99aSMauro Carvalho Chehab- handle_edge_eoi_irq 168*3bd3b99aSMauro Carvalho Chehab 169*3bd3b99aSMauro Carvalho Chehab- handle_bad_irq 170*3bd3b99aSMauro Carvalho Chehab 171*3bd3b99aSMauro Carvalho ChehabThe interrupt flow handlers (either pre-defined or architecture 172*3bd3b99aSMauro Carvalho Chehabspecific) are assigned to specific interrupts by the architecture either 173*3bd3b99aSMauro Carvalho Chehabduring bootup or during device initialization. 174*3bd3b99aSMauro Carvalho Chehab 175*3bd3b99aSMauro Carvalho ChehabDefault flow implementations 176*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 177*3bd3b99aSMauro Carvalho Chehab 178*3bd3b99aSMauro Carvalho ChehabHelper functions 179*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^ 180*3bd3b99aSMauro Carvalho Chehab 181*3bd3b99aSMauro Carvalho ChehabThe helper functions call the chip primitives and are used by the 182*3bd3b99aSMauro Carvalho Chehabdefault flow implementations. The following helper functions are 183*3bd3b99aSMauro Carvalho Chehabimplemented (simplified excerpt):: 184*3bd3b99aSMauro Carvalho Chehab 185*3bd3b99aSMauro Carvalho Chehab default_enable(struct irq_data *data) 186*3bd3b99aSMauro Carvalho Chehab { 187*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_unmask(data); 188*3bd3b99aSMauro Carvalho Chehab } 189*3bd3b99aSMauro Carvalho Chehab 190*3bd3b99aSMauro Carvalho Chehab default_disable(struct irq_data *data) 191*3bd3b99aSMauro Carvalho Chehab { 192*3bd3b99aSMauro Carvalho Chehab if (!delay_disable(data)) 193*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_mask(data); 194*3bd3b99aSMauro Carvalho Chehab } 195*3bd3b99aSMauro Carvalho Chehab 196*3bd3b99aSMauro Carvalho Chehab default_ack(struct irq_data *data) 197*3bd3b99aSMauro Carvalho Chehab { 198*3bd3b99aSMauro Carvalho Chehab chip->irq_ack(data); 199*3bd3b99aSMauro Carvalho Chehab } 200*3bd3b99aSMauro Carvalho Chehab 201*3bd3b99aSMauro Carvalho Chehab default_mask_ack(struct irq_data *data) 202*3bd3b99aSMauro Carvalho Chehab { 203*3bd3b99aSMauro Carvalho Chehab if (chip->irq_mask_ack) { 204*3bd3b99aSMauro Carvalho Chehab chip->irq_mask_ack(data); 205*3bd3b99aSMauro Carvalho Chehab } else { 206*3bd3b99aSMauro Carvalho Chehab chip->irq_mask(data); 207*3bd3b99aSMauro Carvalho Chehab chip->irq_ack(data); 208*3bd3b99aSMauro Carvalho Chehab } 209*3bd3b99aSMauro Carvalho Chehab } 210*3bd3b99aSMauro Carvalho Chehab 211*3bd3b99aSMauro Carvalho Chehab noop(struct irq_data *data)) 212*3bd3b99aSMauro Carvalho Chehab { 213*3bd3b99aSMauro Carvalho Chehab } 214*3bd3b99aSMauro Carvalho Chehab 215*3bd3b99aSMauro Carvalho Chehab 216*3bd3b99aSMauro Carvalho Chehab 217*3bd3b99aSMauro Carvalho ChehabDefault flow handler implementations 218*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219*3bd3b99aSMauro Carvalho Chehab 220*3bd3b99aSMauro Carvalho ChehabDefault Level IRQ flow handler 221*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 222*3bd3b99aSMauro Carvalho Chehab 223*3bd3b99aSMauro Carvalho Chehabhandle_level_irq provides a generic implementation for level-triggered 224*3bd3b99aSMauro Carvalho Chehabinterrupts. 225*3bd3b99aSMauro Carvalho Chehab 226*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt):: 227*3bd3b99aSMauro Carvalho Chehab 228*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_mask_ack(); 229*3bd3b99aSMauro Carvalho Chehab handle_irq_event(desc->action); 230*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_unmask(); 231*3bd3b99aSMauro Carvalho Chehab 232*3bd3b99aSMauro Carvalho Chehab 233*3bd3b99aSMauro Carvalho ChehabDefault Fast EOI IRQ flow handler 234*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 235*3bd3b99aSMauro Carvalho Chehab 236*3bd3b99aSMauro Carvalho Chehabhandle_fasteoi_irq provides a generic implementation for interrupts, 237*3bd3b99aSMauro Carvalho Chehabwhich only need an EOI at the end of the handler. 238*3bd3b99aSMauro Carvalho Chehab 239*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt):: 240*3bd3b99aSMauro Carvalho Chehab 241*3bd3b99aSMauro Carvalho Chehab handle_irq_event(desc->action); 242*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_eoi(); 243*3bd3b99aSMauro Carvalho Chehab 244*3bd3b99aSMauro Carvalho Chehab 245*3bd3b99aSMauro Carvalho ChehabDefault Edge IRQ flow handler 246*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 247*3bd3b99aSMauro Carvalho Chehab 248*3bd3b99aSMauro Carvalho Chehabhandle_edge_irq provides a generic implementation for edge-triggered 249*3bd3b99aSMauro Carvalho Chehabinterrupts. 250*3bd3b99aSMauro Carvalho Chehab 251*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt):: 252*3bd3b99aSMauro Carvalho Chehab 253*3bd3b99aSMauro Carvalho Chehab if (desc->status & running) { 254*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_mask_ack(); 255*3bd3b99aSMauro Carvalho Chehab desc->status |= pending | masked; 256*3bd3b99aSMauro Carvalho Chehab return; 257*3bd3b99aSMauro Carvalho Chehab } 258*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_ack(); 259*3bd3b99aSMauro Carvalho Chehab desc->status |= running; 260*3bd3b99aSMauro Carvalho Chehab do { 261*3bd3b99aSMauro Carvalho Chehab if (desc->status & masked) 262*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_unmask(); 263*3bd3b99aSMauro Carvalho Chehab desc->status &= ~pending; 264*3bd3b99aSMauro Carvalho Chehab handle_irq_event(desc->action); 265*3bd3b99aSMauro Carvalho Chehab } while (status & pending); 266*3bd3b99aSMauro Carvalho Chehab desc->status &= ~running; 267*3bd3b99aSMauro Carvalho Chehab 268*3bd3b99aSMauro Carvalho Chehab 269*3bd3b99aSMauro Carvalho ChehabDefault simple IRQ flow handler 270*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 271*3bd3b99aSMauro Carvalho Chehab 272*3bd3b99aSMauro Carvalho Chehabhandle_simple_irq provides a generic implementation for simple 273*3bd3b99aSMauro Carvalho Chehabinterrupts. 274*3bd3b99aSMauro Carvalho Chehab 275*3bd3b99aSMauro Carvalho Chehab.. note:: 276*3bd3b99aSMauro Carvalho Chehab 277*3bd3b99aSMauro Carvalho Chehab The simple flow handler does not call any handler/chip primitives. 278*3bd3b99aSMauro Carvalho Chehab 279*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt):: 280*3bd3b99aSMauro Carvalho Chehab 281*3bd3b99aSMauro Carvalho Chehab handle_irq_event(desc->action); 282*3bd3b99aSMauro Carvalho Chehab 283*3bd3b99aSMauro Carvalho Chehab 284*3bd3b99aSMauro Carvalho ChehabDefault per CPU flow handler 285*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 286*3bd3b99aSMauro Carvalho Chehab 287*3bd3b99aSMauro Carvalho Chehabhandle_percpu_irq provides a generic implementation for per CPU 288*3bd3b99aSMauro Carvalho Chehabinterrupts. 289*3bd3b99aSMauro Carvalho Chehab 290*3bd3b99aSMauro Carvalho ChehabPer CPU interrupts are only available on SMP and the handler provides a 291*3bd3b99aSMauro Carvalho Chehabsimplified version without locking. 292*3bd3b99aSMauro Carvalho Chehab 293*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt):: 294*3bd3b99aSMauro Carvalho Chehab 295*3bd3b99aSMauro Carvalho Chehab if (desc->irq_data.chip->irq_ack) 296*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_ack(); 297*3bd3b99aSMauro Carvalho Chehab handle_irq_event(desc->action); 298*3bd3b99aSMauro Carvalho Chehab if (desc->irq_data.chip->irq_eoi) 299*3bd3b99aSMauro Carvalho Chehab desc->irq_data.chip->irq_eoi(); 300*3bd3b99aSMauro Carvalho Chehab 301*3bd3b99aSMauro Carvalho Chehab 302*3bd3b99aSMauro Carvalho ChehabEOI Edge IRQ flow handler 303*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^ 304*3bd3b99aSMauro Carvalho Chehab 305*3bd3b99aSMauro Carvalho Chehabhandle_edge_eoi_irq provides an abnomination of the edge handler 306*3bd3b99aSMauro Carvalho Chehabwhich is solely used to tame a badly wreckaged irq controller on 307*3bd3b99aSMauro Carvalho Chehabpowerpc/cell. 308*3bd3b99aSMauro Carvalho Chehab 309*3bd3b99aSMauro Carvalho ChehabBad IRQ flow handler 310*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^ 311*3bd3b99aSMauro Carvalho Chehab 312*3bd3b99aSMauro Carvalho Chehabhandle_bad_irq is used for spurious interrupts which have no real 313*3bd3b99aSMauro Carvalho Chehabhandler assigned.. 314*3bd3b99aSMauro Carvalho Chehab 315*3bd3b99aSMauro Carvalho ChehabQuirks and optimizations 316*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~ 317*3bd3b99aSMauro Carvalho Chehab 318*3bd3b99aSMauro Carvalho ChehabThe generic functions are intended for 'clean' architectures and chips, 319*3bd3b99aSMauro Carvalho Chehabwhich have no platform-specific IRQ handling quirks. If an architecture 320*3bd3b99aSMauro Carvalho Chehabneeds to implement quirks on the 'flow' level then it can do so by 321*3bd3b99aSMauro Carvalho Chehaboverriding the high-level irq-flow handler. 322*3bd3b99aSMauro Carvalho Chehab 323*3bd3b99aSMauro Carvalho ChehabDelayed interrupt disable 324*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~ 325*3bd3b99aSMauro Carvalho Chehab 326*3bd3b99aSMauro Carvalho ChehabThis per interrupt selectable feature, which was introduced by Russell 327*3bd3b99aSMauro Carvalho ChehabKing in the ARM interrupt implementation, does not mask an interrupt at 328*3bd3b99aSMauro Carvalho Chehabthe hardware level when disable_irq() is called. The interrupt is kept 329*3bd3b99aSMauro Carvalho Chehabenabled and is masked in the flow handler when an interrupt event 330*3bd3b99aSMauro Carvalho Chehabhappens. This prevents losing edge interrupts on hardware which does not 331*3bd3b99aSMauro Carvalho Chehabstore an edge interrupt event while the interrupt is disabled at the 332*3bd3b99aSMauro Carvalho Chehabhardware level. When an interrupt arrives while the IRQ_DISABLED flag 333*3bd3b99aSMauro Carvalho Chehabis set, then the interrupt is masked at the hardware level and the 334*3bd3b99aSMauro Carvalho ChehabIRQ_PENDING bit is set. When the interrupt is re-enabled by 335*3bd3b99aSMauro Carvalho Chehabenable_irq() the pending bit is checked and if it is set, the interrupt 336*3bd3b99aSMauro Carvalho Chehabis resent either via hardware or by a software resend mechanism. (It's 337*3bd3b99aSMauro Carvalho Chehabnecessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use 338*3bd3b99aSMauro Carvalho Chehabthe delayed interrupt disable feature and your hardware is not capable 339*3bd3b99aSMauro Carvalho Chehabof retriggering an interrupt.) The delayed interrupt disable is not 340*3bd3b99aSMauro Carvalho Chehabconfigurable. 341*3bd3b99aSMauro Carvalho Chehab 342*3bd3b99aSMauro Carvalho ChehabChip-level hardware encapsulation 343*3bd3b99aSMauro Carvalho Chehab--------------------------------- 344*3bd3b99aSMauro Carvalho Chehab 345*3bd3b99aSMauro Carvalho ChehabThe chip-level hardware descriptor structure irq_chip contains all the 346*3bd3b99aSMauro Carvalho Chehabdirect chip relevant functions, which can be utilized by the irq flow 347*3bd3b99aSMauro Carvalho Chehabimplementations. 348*3bd3b99aSMauro Carvalho Chehab 349*3bd3b99aSMauro Carvalho Chehab- irq_ack() 350*3bd3b99aSMauro Carvalho Chehab 351*3bd3b99aSMauro Carvalho Chehab- irq_mask_ack() - Optional, recommended for performance 352*3bd3b99aSMauro Carvalho Chehab 353*3bd3b99aSMauro Carvalho Chehab- irq_mask() 354*3bd3b99aSMauro Carvalho Chehab 355*3bd3b99aSMauro Carvalho Chehab- irq_unmask() 356*3bd3b99aSMauro Carvalho Chehab 357*3bd3b99aSMauro Carvalho Chehab- irq_eoi() - Optional, required for EOI flow handlers 358*3bd3b99aSMauro Carvalho Chehab 359*3bd3b99aSMauro Carvalho Chehab- irq_retrigger() - Optional 360*3bd3b99aSMauro Carvalho Chehab 361*3bd3b99aSMauro Carvalho Chehab- irq_set_type() - Optional 362*3bd3b99aSMauro Carvalho Chehab 363*3bd3b99aSMauro Carvalho Chehab- irq_set_wake() - Optional 364*3bd3b99aSMauro Carvalho Chehab 365*3bd3b99aSMauro Carvalho ChehabThese primitives are strictly intended to mean what they say: ack means 366*3bd3b99aSMauro Carvalho ChehabACK, masking means masking of an IRQ line, etc. It is up to the flow 367*3bd3b99aSMauro Carvalho Chehabhandler(s) to use these basic units of low-level functionality. 368*3bd3b99aSMauro Carvalho Chehab 369*3bd3b99aSMauro Carvalho Chehab__do_IRQ entry point 370*3bd3b99aSMauro Carvalho Chehab==================== 371*3bd3b99aSMauro Carvalho Chehab 372*3bd3b99aSMauro Carvalho ChehabThe original implementation __do_IRQ() was an alternative entry point 373*3bd3b99aSMauro Carvalho Chehabfor all types of interrupts. It no longer exists. 374*3bd3b99aSMauro Carvalho Chehab 375*3bd3b99aSMauro Carvalho ChehabThis handler turned out to be not suitable for all interrupt hardware 376*3bd3b99aSMauro Carvalho Chehaband was therefore reimplemented with split functionality for 377*3bd3b99aSMauro Carvalho Chehabedge/level/simple/percpu interrupts. This is not only a functional 378*3bd3b99aSMauro Carvalho Chehaboptimization. It also shortens code paths for interrupts. 379*3bd3b99aSMauro Carvalho Chehab 380*3bd3b99aSMauro Carvalho ChehabLocking on SMP 381*3bd3b99aSMauro Carvalho Chehab============== 382*3bd3b99aSMauro Carvalho Chehab 383*3bd3b99aSMauro Carvalho ChehabThe locking of chip registers is up to the architecture that defines the 384*3bd3b99aSMauro Carvalho Chehabchip primitives. The per-irq structure is protected via desc->lock, by 385*3bd3b99aSMauro Carvalho Chehabthe generic layer. 386*3bd3b99aSMauro Carvalho Chehab 387*3bd3b99aSMauro Carvalho ChehabGeneric interrupt chip 388*3bd3b99aSMauro Carvalho Chehab====================== 389*3bd3b99aSMauro Carvalho Chehab 390*3bd3b99aSMauro Carvalho ChehabTo avoid copies of identical implementations of IRQ chips the core 391*3bd3b99aSMauro Carvalho Chehabprovides a configurable generic interrupt chip implementation. 392*3bd3b99aSMauro Carvalho ChehabDevelopers should check carefully whether the generic chip fits their 393*3bd3b99aSMauro Carvalho Chehabneeds before implementing the same functionality slightly differently 394*3bd3b99aSMauro Carvalho Chehabthemselves. 395*3bd3b99aSMauro Carvalho Chehab 396*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/generic-chip.c 397*3bd3b99aSMauro Carvalho Chehab :export: 398*3bd3b99aSMauro Carvalho Chehab 399*3bd3b99aSMauro Carvalho ChehabStructures 400*3bd3b99aSMauro Carvalho Chehab========== 401*3bd3b99aSMauro Carvalho Chehab 402*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the structures 403*3bd3b99aSMauro Carvalho Chehabwhich are used in the generic IRQ layer. 404*3bd3b99aSMauro Carvalho Chehab 405*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/irq.h 406*3bd3b99aSMauro Carvalho Chehab :internal: 407*3bd3b99aSMauro Carvalho Chehab 408*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/interrupt.h 409*3bd3b99aSMauro Carvalho Chehab :internal: 410*3bd3b99aSMauro Carvalho Chehab 411*3bd3b99aSMauro Carvalho ChehabPublic Functions Provided 412*3bd3b99aSMauro Carvalho Chehab========================= 413*3bd3b99aSMauro Carvalho Chehab 414*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the kernel API 415*3bd3b99aSMauro Carvalho Chehabfunctions which are exported. 416*3bd3b99aSMauro Carvalho Chehab 417*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/manage.c 418*3bd3b99aSMauro Carvalho Chehab :export: 419*3bd3b99aSMauro Carvalho Chehab 420*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c 421*3bd3b99aSMauro Carvalho Chehab :export: 422*3bd3b99aSMauro Carvalho Chehab 423*3bd3b99aSMauro Carvalho ChehabInternal Functions Provided 424*3bd3b99aSMauro Carvalho Chehab=========================== 425*3bd3b99aSMauro Carvalho Chehab 426*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the internal 427*3bd3b99aSMauro Carvalho Chehabfunctions. 428*3bd3b99aSMauro Carvalho Chehab 429*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/irqdesc.c 430*3bd3b99aSMauro Carvalho Chehab :internal: 431*3bd3b99aSMauro Carvalho Chehab 432*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/handle.c 433*3bd3b99aSMauro Carvalho Chehab :internal: 434*3bd3b99aSMauro Carvalho Chehab 435*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c 436*3bd3b99aSMauro Carvalho Chehab :internal: 437*3bd3b99aSMauro Carvalho Chehab 438*3bd3b99aSMauro Carvalho ChehabCredits 439*3bd3b99aSMauro Carvalho Chehab======= 440*3bd3b99aSMauro Carvalho Chehab 441*3bd3b99aSMauro Carvalho ChehabThe following people have contributed to this document: 442*3bd3b99aSMauro Carvalho Chehab 443*3bd3b99aSMauro Carvalho Chehab1. Thomas Gleixner tglx@linutronix.de 444*3bd3b99aSMauro Carvalho Chehab 445*3bd3b99aSMauro Carvalho Chehab2. Ingo Molnar mingo@elte.hu 446