1*4882a593Smuzhiyun=============================================== 2*4882a593SmuzhiyunThe irq_domain interrupt number mapping library 3*4882a593Smuzhiyun=============================================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThe current design of the Linux kernel uses a single large number 6*4882a593Smuzhiyunspace where each separate IRQ source is assigned a different number. 7*4882a593SmuzhiyunThis is simple when there is only one interrupt controller, but in 8*4882a593Smuzhiyunsystems with multiple interrupt controllers the kernel must ensure 9*4882a593Smuzhiyunthat each one gets assigned non-overlapping allocations of Linux 10*4882a593SmuzhiyunIRQ numbers. 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunThe number of interrupt controllers registered as unique irqchips 13*4882a593Smuzhiyunshow a rising tendency: for example subdrivers of different kinds 14*4882a593Smuzhiyunsuch as GPIO controllers avoid reimplementing identical callback 15*4882a593Smuzhiyunmechanisms as the IRQ core system by modelling their interrupt 16*4882a593Smuzhiyunhandlers as irqchips, i.e. in effect cascading interrupt controllers. 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunHere the interrupt number loose all kind of correspondence to 19*4882a593Smuzhiyunhardware interrupt numbers: whereas in the past, IRQ numbers could 20*4882a593Smuzhiyunbe chosen so they matched the hardware IRQ line into the root 21*4882a593Smuzhiyuninterrupt controller (i.e. the component actually fireing the 22*4882a593Smuzhiyuninterrupt line to the CPU) nowadays this number is just a number. 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunFor this reason we need a mechanism to separate controller-local 25*4882a593Smuzhiyuninterrupt numbers, called hardware irq's, from Linux IRQ numbers. 26*4882a593Smuzhiyun 27*4882a593SmuzhiyunThe irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of 28*4882a593Smuzhiyunirq numbers, but they don't provide any support for reverse mapping of 29*4882a593Smuzhiyunthe controller-local IRQ (hwirq) number into the Linux IRQ number 30*4882a593Smuzhiyunspace. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunThe irq_domain library adds mapping between hwirq and IRQ numbers on 33*4882a593Smuzhiyuntop of the irq_alloc_desc*() API. An irq_domain to manage mapping is 34*4882a593Smuzhiyunpreferred over interrupt controller drivers open coding their own 35*4882a593Smuzhiyunreverse mapping scheme. 36*4882a593Smuzhiyun 37*4882a593Smuzhiyunirq_domain also implements translation from an abstract irq_fwspec 38*4882a593Smuzhiyunstructure to hwirq numbers (Device Tree and ACPI GSI so far), and can 39*4882a593Smuzhiyunbe easily extended to support other IRQ topology data sources. 40*4882a593Smuzhiyun 41*4882a593Smuzhiyunirq_domain usage 42*4882a593Smuzhiyun================ 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunAn interrupt controller driver creates and registers an irq_domain by 45*4882a593Smuzhiyuncalling one of the irq_domain_add_*() functions (each mapping method 46*4882a593Smuzhiyunhas a different allocator function, more on that later). The function 47*4882a593Smuzhiyunwill return a pointer to the irq_domain on success. The caller must 48*4882a593Smuzhiyunprovide the allocator function with an irq_domain_ops structure. 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunIn most cases, the irq_domain will begin empty without any mappings 51*4882a593Smuzhiyunbetween hwirq and IRQ numbers. Mappings are added to the irq_domain 52*4882a593Smuzhiyunby calling irq_create_mapping() which accepts the irq_domain and a 53*4882a593Smuzhiyunhwirq number as arguments. If a mapping for the hwirq doesn't already 54*4882a593Smuzhiyunexist then it will allocate a new Linux irq_desc, associate it with 55*4882a593Smuzhiyunthe hwirq, and call the .map() callback so the driver can perform any 56*4882a593Smuzhiyunrequired hardware setup. 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunWhen an interrupt is received, irq_find_mapping() function should 59*4882a593Smuzhiyunbe used to find the Linux IRQ number from the hwirq number. 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunThe irq_create_mapping() function must be called *atleast once* 62*4882a593Smuzhiyunbefore any call to irq_find_mapping(), lest the descriptor will not 63*4882a593Smuzhiyunbe allocated. 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunIf the driver has the Linux IRQ number or the irq_data pointer, and 66*4882a593Smuzhiyunneeds to know the associated hwirq number (such as in the irq_chip 67*4882a593Smuzhiyuncallbacks) then it can be directly obtained from irq_data->hwirq. 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunTypes of irq_domain mappings 70*4882a593Smuzhiyun============================ 71*4882a593Smuzhiyun 72*4882a593SmuzhiyunThere are several mechanisms available for reverse mapping from hwirq 73*4882a593Smuzhiyunto Linux irq, and each mechanism uses a different allocation function. 74*4882a593SmuzhiyunWhich reverse map type should be used depends on the use case. Each 75*4882a593Smuzhiyunof the reverse map types are described below: 76*4882a593Smuzhiyun 77*4882a593SmuzhiyunLinear 78*4882a593Smuzhiyun------ 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun:: 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun irq_domain_add_linear() 83*4882a593Smuzhiyun irq_domain_create_linear() 84*4882a593Smuzhiyun 85*4882a593SmuzhiyunThe linear reverse map maintains a fixed size table indexed by the 86*4882a593Smuzhiyunhwirq number. When a hwirq is mapped, an irq_desc is allocated for 87*4882a593Smuzhiyunthe hwirq, and the IRQ number is stored in the table. 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunThe Linear map is a good choice when the maximum number of hwirqs is 90*4882a593Smuzhiyunfixed and a relatively small number (~ < 256). The advantages of this 91*4882a593Smuzhiyunmap are fixed time lookup for IRQ numbers, and irq_descs are only 92*4882a593Smuzhiyunallocated for in-use IRQs. The disadvantage is that the table must be 93*4882a593Smuzhiyunas large as the largest possible hwirq number. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyunirq_domain_add_linear() and irq_domain_create_linear() are functionally 96*4882a593Smuzhiyunequivalent, except for the first argument is different - the former 97*4882a593Smuzhiyunaccepts an Open Firmware specific 'struct device_node', while the latter 98*4882a593Smuzhiyunaccepts a more general abstraction 'struct fwnode_handle'. 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunThe majority of drivers should use the linear map. 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunTree 103*4882a593Smuzhiyun---- 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun:: 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun irq_domain_add_tree() 108*4882a593Smuzhiyun irq_domain_create_tree() 109*4882a593Smuzhiyun 110*4882a593SmuzhiyunThe irq_domain maintains a radix tree map from hwirq numbers to Linux 111*4882a593SmuzhiyunIRQs. When an hwirq is mapped, an irq_desc is allocated and the 112*4882a593Smuzhiyunhwirq is used as the lookup key for the radix tree. 113*4882a593Smuzhiyun 114*4882a593SmuzhiyunThe tree map is a good choice if the hwirq number can be very large 115*4882a593Smuzhiyunsince it doesn't need to allocate a table as large as the largest 116*4882a593Smuzhiyunhwirq number. The disadvantage is that hwirq to IRQ number lookup is 117*4882a593Smuzhiyundependent on how many entries are in the table. 118*4882a593Smuzhiyun 119*4882a593Smuzhiyunirq_domain_add_tree() and irq_domain_create_tree() are functionally 120*4882a593Smuzhiyunequivalent, except for the first argument is different - the former 121*4882a593Smuzhiyunaccepts an Open Firmware specific 'struct device_node', while the latter 122*4882a593Smuzhiyunaccepts a more general abstraction 'struct fwnode_handle'. 123*4882a593Smuzhiyun 124*4882a593SmuzhiyunVery few drivers should need this mapping. 125*4882a593Smuzhiyun 126*4882a593SmuzhiyunNo Map 127*4882a593Smuzhiyun------ 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun:: 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun irq_domain_add_nomap() 132*4882a593Smuzhiyun 133*4882a593SmuzhiyunThe No Map mapping is to be used when the hwirq number is 134*4882a593Smuzhiyunprogrammable in the hardware. In this case it is best to program the 135*4882a593SmuzhiyunLinux IRQ number into the hardware itself so that no mapping is 136*4882a593Smuzhiyunrequired. Calling irq_create_direct_mapping() will allocate a Linux 137*4882a593SmuzhiyunIRQ number and call the .map() callback so that driver can program the 138*4882a593SmuzhiyunLinux IRQ number into the hardware. 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunMost drivers cannot use this mapping. 141*4882a593Smuzhiyun 142*4882a593SmuzhiyunLegacy 143*4882a593Smuzhiyun------ 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun:: 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun irq_domain_add_simple() 148*4882a593Smuzhiyun irq_domain_add_legacy() 149*4882a593Smuzhiyun irq_domain_add_legacy_isa() 150*4882a593Smuzhiyun 151*4882a593SmuzhiyunThe Legacy mapping is a special case for drivers that already have a 152*4882a593Smuzhiyunrange of irq_descs allocated for the hwirqs. It is used when the 153*4882a593Smuzhiyundriver cannot be immediately converted to use the linear mapping. For 154*4882a593Smuzhiyunexample, many embedded system board support files use a set of #defines 155*4882a593Smuzhiyunfor IRQ numbers that are passed to struct device registrations. In that 156*4882a593Smuzhiyuncase the Linux IRQ numbers cannot be dynamically assigned and the legacy 157*4882a593Smuzhiyunmapping should be used. 158*4882a593Smuzhiyun 159*4882a593SmuzhiyunThe legacy map assumes a contiguous range of IRQ numbers has already 160*4882a593Smuzhiyunbeen allocated for the controller and that the IRQ number can be 161*4882a593Smuzhiyuncalculated by adding a fixed offset to the hwirq number, and 162*4882a593Smuzhiyunvisa-versa. The disadvantage is that it requires the interrupt 163*4882a593Smuzhiyuncontroller to manage IRQ allocations and it requires an irq_desc to be 164*4882a593Smuzhiyunallocated for every hwirq, even if it is unused. 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunThe legacy map should only be used if fixed IRQ mappings must be 167*4882a593Smuzhiyunsupported. For example, ISA controllers would use the legacy map for 168*4882a593Smuzhiyunmapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ 169*4882a593Smuzhiyunnumbers. 170*4882a593Smuzhiyun 171*4882a593SmuzhiyunMost users of legacy mappings should use irq_domain_add_simple() which 172*4882a593Smuzhiyunwill use a legacy domain only if an IRQ range is supplied by the 173*4882a593Smuzhiyunsystem and will otherwise use a linear domain mapping. The semantics 174*4882a593Smuzhiyunof this call are such that if an IRQ range is specified then 175*4882a593Smuzhiyundescriptors will be allocated on-the-fly for it, and if no range is 176*4882a593Smuzhiyunspecified it will fall through to irq_domain_add_linear() which means 177*4882a593Smuzhiyun*no* irq descriptors will be allocated. 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunA typical use case for simple domains is where an irqchip provider 180*4882a593Smuzhiyunis supporting both dynamic and static IRQ assignments. 181*4882a593Smuzhiyun 182*4882a593SmuzhiyunIn order to avoid ending up in a situation where a linear domain is 183*4882a593Smuzhiyunused and no descriptor gets allocated it is very important to make sure 184*4882a593Smuzhiyunthat the driver using the simple domain call irq_create_mapping() 185*4882a593Smuzhiyunbefore any irq_find_mapping() since the latter will actually work 186*4882a593Smuzhiyunfor the static IRQ assignment case. 187*4882a593Smuzhiyun 188*4882a593SmuzhiyunHierarchy IRQ domain 189*4882a593Smuzhiyun-------------------- 190*4882a593Smuzhiyun 191*4882a593SmuzhiyunOn some architectures, there may be multiple interrupt controllers 192*4882a593Smuzhiyuninvolved in delivering an interrupt from the device to the target CPU. 193*4882a593SmuzhiyunLet's look at a typical interrupt delivering path on x86 platforms:: 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU 196*4882a593Smuzhiyun 197*4882a593SmuzhiyunThere are three interrupt controllers involved: 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun1) IOAPIC controller 200*4882a593Smuzhiyun2) Interrupt remapping controller 201*4882a593Smuzhiyun3) Local APIC controller 202*4882a593Smuzhiyun 203*4882a593SmuzhiyunTo support such a hardware topology and make software architecture match 204*4882a593Smuzhiyunhardware architecture, an irq_domain data structure is built for each 205*4882a593Smuzhiyuninterrupt controller and those irq_domains are organized into hierarchy. 206*4882a593SmuzhiyunWhen building irq_domain hierarchy, the irq_domain near to the device is 207*4882a593Smuzhiyunchild and the irq_domain near to CPU is parent. So a hierarchy structure 208*4882a593Smuzhiyunas below will be built for the example above:: 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun CPU Vector irq_domain (root irq_domain to manage CPU vectors) 211*4882a593Smuzhiyun ^ 212*4882a593Smuzhiyun | 213*4882a593Smuzhiyun Interrupt Remapping irq_domain (manage irq_remapping entries) 214*4882a593Smuzhiyun ^ 215*4882a593Smuzhiyun | 216*4882a593Smuzhiyun IOAPIC irq_domain (manage IOAPIC delivery entries/pins) 217*4882a593Smuzhiyun 218*4882a593SmuzhiyunThere are four major interfaces to use hierarchy irq_domain: 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun1) irq_domain_alloc_irqs(): allocate IRQ descriptors and interrupt 221*4882a593Smuzhiyun controller related resources to deliver these interrupts. 222*4882a593Smuzhiyun2) irq_domain_free_irqs(): free IRQ descriptors and interrupt controller 223*4882a593Smuzhiyun related resources associated with these interrupts. 224*4882a593Smuzhiyun3) irq_domain_activate_irq(): activate interrupt controller hardware to 225*4882a593Smuzhiyun deliver the interrupt. 226*4882a593Smuzhiyun4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware 227*4882a593Smuzhiyun to stop delivering the interrupt. 228*4882a593Smuzhiyun 229*4882a593SmuzhiyunFollowing changes are needed to support hierarchy irq_domain: 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun1) a new field 'parent' is added to struct irq_domain; it's used to 232*4882a593Smuzhiyun maintain irq_domain hierarchy information. 233*4882a593Smuzhiyun2) a new field 'parent_data' is added to struct irq_data; it's used to 234*4882a593Smuzhiyun build hierarchy irq_data to match hierarchy irq_domains. The irq_data 235*4882a593Smuzhiyun is used to store irq_domain pointer and hardware irq number. 236*4882a593Smuzhiyun3) new callbacks are added to struct irq_domain_ops to support hierarchy 237*4882a593Smuzhiyun irq_domain operations. 238*4882a593Smuzhiyun 239*4882a593SmuzhiyunWith support of hierarchy irq_domain and hierarchy irq_data ready, an 240*4882a593Smuzhiyunirq_domain structure is built for each interrupt controller, and an 241*4882a593Smuzhiyunirq_data structure is allocated for each irq_domain associated with an 242*4882a593SmuzhiyunIRQ. Now we could go one step further to support stacked(hierarchy) 243*4882a593Smuzhiyunirq_chip. That is, an irq_chip is associated with each irq_data along 244*4882a593Smuzhiyunthe hierarchy. A child irq_chip may implement a required action by 245*4882a593Smuzhiyunitself or by cooperating with its parent irq_chip. 246*4882a593Smuzhiyun 247*4882a593SmuzhiyunWith stacked irq_chip, interrupt controller driver only needs to deal 248*4882a593Smuzhiyunwith the hardware managed by itself and may ask for services from its 249*4882a593Smuzhiyunparent irq_chip when needed. So we could achieve a much cleaner 250*4882a593Smuzhiyunsoftware architecture. 251*4882a593Smuzhiyun 252*4882a593SmuzhiyunFor an interrupt controller driver to support hierarchy irq_domain, it 253*4882a593Smuzhiyunneeds to: 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun1) Implement irq_domain_ops.alloc and irq_domain_ops.free 256*4882a593Smuzhiyun2) Optionally implement irq_domain_ops.activate and 257*4882a593Smuzhiyun irq_domain_ops.deactivate. 258*4882a593Smuzhiyun3) Optionally implement an irq_chip to manage the interrupt controller 259*4882a593Smuzhiyun hardware. 260*4882a593Smuzhiyun4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap, 261*4882a593Smuzhiyun they are unused with hierarchy irq_domain. 262*4882a593Smuzhiyun 263*4882a593SmuzhiyunHierarchy irq_domain is in no way x86 specific, and is heavily used to 264*4882a593Smuzhiyunsupport other architectures, such as ARM, ARM64 etc. 265*4882a593Smuzhiyun 266*4882a593SmuzhiyunDebugging 267*4882a593Smuzhiyun========= 268*4882a593Smuzhiyun 269*4882a593SmuzhiyunMost of the internals of the IRQ subsystem are exposed in debugfs by 270*4882a593Smuzhiyunturning CONFIG_GENERIC_IRQ_DEBUGFS on. 271