xref: /OK3568_Linux_fs/kernel/Documentation/core-api/irq/irq-domain.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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