OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [Documentation/] [DocBook/] [genericirq.tmpl] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
2
3
        "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
4
 
5
6
 
7
  Linux generic IRQ handling
8
 
9
  
10
   
11
    Thomas
12
    Gleixner
13
    
14
     
15
      tglx@linutronix.de
16
     
17
    
18
   
19
   
20
    Ingo
21
    Molnar
22
    
23
     
24
      mingo@elte.hu
25
     
26
    
27
   
28
  
29
 
30
  
31
   2005-2006
32
   Thomas Gleixner
33
  
34
  
35
   2005-2006
36
   Ingo Molnar
37
  
38
 
39
  
40
   
41
     This documentation is free software; you can redistribute
42
     it and/or modify it under the terms of the GNU General Public
43
     License version 2 as published by the Free Software Foundation.
44
   
45
 
46
   
47
     This program is distributed in the hope that it will be
48
     useful, but WITHOUT ANY WARRANTY; without even the implied
49
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
50
     See the GNU General Public License for more details.
51
   
52
 
53
   
54
     You should have received a copy of the GNU General Public
55
     License along with this program; if not, write to the Free
56
     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
57
     MA 02111-1307 USA
58
   
59
 
60
   
61
     For more details see the file COPYING in the source
62
     distribution of Linux.
63
   
64
  
65
 
66
 
67
68
 
69
  
70
    Introduction
71
    
72
        The generic interrupt handling layer is designed to provide a
73
        complete abstraction of interrupt handling for device drivers.
74
        It is able to handle all the different types of interrupt controller
75
        hardware. Device drivers use generic API functions to request, enable,
76
        disable and free interrupts. The drivers do not have to know anything
77
        about interrupt hardware details, so they can be used on different
78
        platforms without code changes.
79
    
80
    
81
        This documentation is provided to developers who want to implement
82
        an interrupt subsystem based for their architecture, with the help
83
        of the generic IRQ handling layer.
84
    
85
  
86
 
87
  
88
    Rationale
89
        
90
        The original implementation of interrupt handling in Linux is using
91
        the __do_IRQ() super-handler, which is able to deal with every
92
        type of interrupt logic.
93
        
94
        
95
        Originally, Russell King identified different types of handlers to
96
        build a quite universal set for the ARM interrupt handler
97
        implementation in Linux 2.5/2.6. He distinguished between:
98
        
99
          Level type
100
          Edge type
101
          Simple type
102
        
103
        In the SMP world of the __do_IRQ() super-handler another type
104
        was identified:
105
        
106
          Per CPU type
107
        
108
        
109
        
110
        This split implementation of highlevel IRQ handlers allows us to
111
        optimize the flow of the interrupt handling for each specific
112
        interrupt type. This reduces complexity in that particular codepath
113
        and allows the optimized handling of a given type.
114
        
115
        
116
        The original general IRQ implementation used hw_interrupt_type
117
        structures and their ->ack(), ->end() [etc.] callbacks to
118
        differentiate the flow control in the super-handler. This leads to
119
        a mix of flow logic and lowlevel hardware logic, and it also leads
120
        to unnecessary code duplication: for example in i386, there is a
121
        ioapic_level_irq and a ioapic_edge_irq irq-type which share many
122
        of the lowlevel details but have different flow handling.
123
        
124
        
125
        A more natural abstraction is the clean separation of the
126
        'irq flow' and the 'chip details'.
127
        
128
        
129
        Analysing a couple of architecture's IRQ subsystem implementations
130
        reveals that most of them can use a generic set of 'irq flow'
131
        methods and only need to add the chip level specific code.
132
        The separation is also valuable for (sub)architectures
133
        which need specific quirks in the irq flow itself but not in the
134
        chip-details - and thus provides a more transparent IRQ subsystem
135
        design.
136
        
137
        
138
        Each interrupt descriptor is assigned its own highlevel flow
139
        handler, which is normally one of the generic
140
        implementations. (This highlevel flow handler implementation also
141
        makes it simple to provide demultiplexing handlers which can be
142
        found in embedded platforms on various architectures.)
143
        
144
        
145
        The separation makes the generic interrupt handling layer more
146
        flexible and extensible. For example, an (sub)architecture can
147
        use a generic irq-flow implementation for 'level type' interrupts
148
        and add a (sub)architecture specific 'edge type' implementation.
149
        
150
        
151
        To make the transition to the new model easier and prevent the
152
        breakage of existing implementations, the __do_IRQ() super-handler
153
        is still available. This leads to a kind of duality for the time
154
        being. Over time the new model should be used in more and more
155
        architectures, as it enables smaller and cleaner IRQ subsystems.
156
        
157
  
158
  
159
    Known Bugs And Assumptions
160
    
161
        None (knock on wood).
162
    
163
  
164
 
165
  
166
    Abstraction layers
167
    
168
        There are three main levels of abstraction in the interrupt code:
169
        
170
          Highlevel driver API
171
          Highlevel IRQ flow handlers
172
          Chiplevel hardware encapsulation
173
        
174
    
175
    
176
        Interrupt control flow
177
        
178
        Each interrupt is described by an interrupt descriptor structure
179
        irq_desc. The interrupt is referenced by an 'unsigned int' numeric
180
        value which selects the corresponding interrupt decription structure
181
        in the descriptor structures array.
182
        The descriptor structure contains status information and pointers
183
        to the interrupt flow method and the interrupt chip structure
184
        which are assigned to this interrupt.
185
        
186
        
187
        Whenever an interrupt triggers, the lowlevel arch code calls into
188
        the generic interrupt code by calling desc->handle_irq().
189
        This highlevel IRQ handling function only uses desc->chip primitives
190
        referenced by the assigned chip descriptor structure.
191
        
192
    
193
    
194
        Highlevel Driver API
195
        
196
          The highlevel Driver API consists of following functions:
197
          
198
          request_irq()
199
          free_irq()
200
          disable_irq()
201
          enable_irq()
202
          disable_irq_nosync() (SMP only)
203
          synchronize_irq() (SMP only)
204
          set_irq_type()
205
          set_irq_wake()
206
          set_irq_data()
207
          set_irq_chip()
208
          set_irq_chip_data()
209
          
210
          See the autogenerated function documentation for details.
211
        
212
    
213
    
214
        Highlevel IRQ flow handlers
215
        
216
          The generic layer provides a set of pre-defined irq-flow methods:
217
          
218
          handle_level_irq
219
          handle_edge_irq
220
          handle_simple_irq
221
          handle_percpu_irq
222
          
223
          The interrupt flow handlers (either predefined or architecture
224
          specific) are assigned to specific interrupts by the architecture
225
          either during bootup or during device initialization.
226
        
227
        
228
        Default flow implementations
229
            
230
                Helper functions
231
                
232
                The helper functions call the chip primitives and
233
                are used by the default flow implementations.
234
                The following helper functions are implemented (simplified excerpt):
235
                
236
default_enable(irq)
237
{
238
        desc->chip->unmask(irq);
239
}
240
 
241
default_disable(irq)
242
{
243
        if (!delay_disable(irq))
244
                desc->chip->mask(irq);
245
}
246
 
247
default_ack(irq)
248
{
249
        chip->ack(irq);
250
}
251
 
252
default_mask_ack(irq)
253
{
254
        if (chip->mask_ack) {
255
                chip->mask_ack(irq);
256
        } else {
257
                chip->mask(irq);
258
                chip->ack(irq);
259
        }
260
}
261
 
262
noop(irq)
263
{
264
}
265
 
266
                
267
                
268
            
269
        
270
        
271
        Default flow handler implementations
272
            
273
                Default Level IRQ flow handler
274
                
275
                handle_level_irq provides a generic implementation
276
                for level-triggered interrupts.
277
                
278
                
279
                The following control flow is implemented (simplified excerpt):
280
                
281
desc->chip->start();
282
handle_IRQ_event(desc->action);
283
desc->chip->end();
284
                
285
                
286
            
287
            
288
                Default Edge IRQ flow handler
289
                
290
                handle_edge_irq provides a generic implementation
291
                for edge-triggered interrupts.
292
                
293
                
294
                The following control flow is implemented (simplified excerpt):
295
                
296
if (desc->status & running) {
297
        desc->chip->hold();
298
        desc->status |= pending | masked;
299
        return;
300
}
301
desc->chip->start();
302
desc->status |= running;
303
do {
304
        if (desc->status & masked)
305
                desc->chip->enable();
306
        desc->status &= ~pending;
307
        handle_IRQ_event(desc->action);
308
} while (status & pending);
309
desc->status &= ~running;
310
desc->chip->end();
311
                
312
                
313
            
314
            
315
                Default simple IRQ flow handler
316
                
317
                handle_simple_irq provides a generic implementation
318
                for simple interrupts.
319
                
320
                
321
                Note: The simple flow handler does not call any
322
                handler/chip primitives.
323
                
324
                
325
                The following control flow is implemented (simplified excerpt):
326
                
327
handle_IRQ_event(desc->action);
328
                
329
                
330
            
331
            
332
                Default per CPU flow handler
333
                
334
                handle_percpu_irq provides a generic implementation
335
                for per CPU interrupts.
336
                
337
                
338
                Per CPU interrupts are only available on SMP and
339
                the handler provides a simplified version without
340
                locking.
341
                
342
                
343
                The following control flow is implemented (simplified excerpt):
344
                
345
desc->chip->start();
346
handle_IRQ_event(desc->action);
347
desc->chip->end();
348
                
349
                
350
            
351
        
352
        
353
        Quirks and optimizations
354
        
355
        The generic functions are intended for 'clean' architectures and chips,
356
        which have no platform-specific IRQ handling quirks. If an architecture
357
        needs to implement quirks on the 'flow' level then it can do so by
358
        overriding the highlevel irq-flow handler.
359
        
360
        
361
        
362
        Delayed interrupt disable
363
        
364
        This per interrupt selectable feature, which was introduced by Russell
365
        King in the ARM interrupt implementation, does not mask an interrupt
366
        at the hardware level when disable_irq() is called. The interrupt is
367
        kept enabled and is masked in the flow handler when an interrupt event
368
        happens. This prevents losing edge interrupts on hardware which does
369
        not store an edge interrupt event while the interrupt is disabled at
370
        the hardware level. When an interrupt arrives while the IRQ_DISABLED
371
        flag is set, then the interrupt is masked at the hardware level and
372
        the IRQ_PENDING bit is set. When the interrupt is re-enabled by
373
        enable_irq() the pending bit is checked and if it is set, the
374
        interrupt is resent either via hardware or by a software resend
375
        mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
376
        you want to use the delayed interrupt disable feature and your
377
        hardware is not capable of retriggering an interrupt.)
378
        The delayed interrupt disable can be runtime enabled, per interrupt,
379
        by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
380
        
381
        
382
    
383
    
384
        Chiplevel hardware encapsulation
385
        
386
        The chip level hardware descriptor structure irq_chip
387
        contains all the direct chip relevant functions, which
388
        can be utilized by the irq flow implementations.
389
          
390
          ack()
391
          mask_ack() - Optional, recommended for performance
392
          mask()
393
          unmask()
394
          retrigger() - Optional
395
          set_type() - Optional
396
          set_wake() - Optional
397
          
398
        These primitives are strictly intended to mean what they say: ack means
399
        ACK, masking means masking of an IRQ line, etc. It is up to the flow
400
        handler(s) to use these basic units of lowlevel functionality.
401
        
402
    
403
  
404
 
405
  
406
     __do_IRQ entry point
407
     
408
        The original implementation __do_IRQ() is an alternative entry
409
        point for all types of interrupts.
410
     
411
     
412
        This handler turned out to be not suitable for all
413
        interrupt hardware and was therefore reimplemented with split
414
        functionality for egde/level/simple/percpu interrupts. This is not
415
        only a functional optimization. It also shortens code paths for
416
        interrupts.
417
      
418
      
419
        To make use of the split implementation, replace the call to
420
        __do_IRQ by a call to desc->chip->handle_irq() and associate
421
        the appropriate handler function to desc->chip->handle_irq().
422
        In most cases the generic handler implementations should
423
        be sufficient.
424
     
425
  
426
 
427
  
428
     Locking on SMP
429
     
430
        The locking of chip registers is up to the architecture that
431
        defines the chip primitives. There is a chip->lock field that can be used
432
        for serialization, but the generic layer does not touch it. The per-irq
433
        structure is protected via desc->lock, by the generic layer.
434
     
435
  
436
  
437
     Structures
438
     
439
     This chapter contains the autogenerated documentation of the structures which are
440
     used in the generic IRQ layer.
441
     
442
!Iinclude/linux/irq.h
443
  
444
 
445
  
446
     Public Functions Provided
447
     
448
     This chapter contains the autogenerated documentation of the kernel API functions
449
      which are exported.
450
     
451
!Ekernel/irq/manage.c
452
!Ekernel/irq/chip.c
453
  
454
 
455
  
456
     Internal Functions Provided
457
     
458
     This chapter contains the autogenerated documentation of the internal functions.
459
     
460
!Ikernel/irq/handle.c
461
!Ikernel/irq/chip.c
462
  
463
 
464
  
465
     Credits
466
        
467
                The following people have contributed to this document:
468
                
469
                        Thomas Gleixnertglx@linutronix.de
470
                        Ingo Molnarmingo@elte.hu
471
                
472
        
473
  
474

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.