1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>High-level IRQ flow handlers</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Linux generic IRQ handling"><link rel="up" href="Abstraction.html" title="Chapter 4. Abstraction layers"><link rel="prev" href="Highlevel_Driver_API.html" title="High-level Driver API"><link rel="next" href="Chiplevel_hardware_encapsulation.html" title="Chip-level hardware encapsulation"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">High-level IRQ flow handlers</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="Highlevel_Driver_API.html">Prev</a> </td><th width="60%" align="center">Chapter 4. Abstraction layers</th><td width="20%" align="right"> <a accesskey="n" href="Chiplevel_hardware_encapsulation.html">Next</a></td></tr></table><hr></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="Highlevel_IRQ_flow_handlers"></a>High-level IRQ flow handlers</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="Highlevel_IRQ_flow_handlers.html#Default_flow_implementations">Default flow implementations</a></span></dt><dt><span class="sect2"><a href="Highlevel_IRQ_flow_handlers.html#Default_flow_handler_implementations">Default flow handler implementations</a></span></dt><dt><span class="sect2"><a href="Highlevel_IRQ_flow_handlers.html#Quirks_and_optimizations">Quirks and optimizations</a></span></dt><dt><span class="sect2"><a href="Highlevel_IRQ_flow_handlers.html#Delayed_interrupt_disable">Delayed interrupt disable</a></span></dt></dl></div><p> 2 The generic layer provides a set of pre-defined irq-flow methods: 3 </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>handle_level_irq</p></li><li class="listitem"><p>handle_edge_irq</p></li><li class="listitem"><p>handle_fasteoi_irq</p></li><li class="listitem"><p>handle_simple_irq</p></li><li class="listitem"><p>handle_percpu_irq</p></li><li class="listitem"><p>handle_edge_eoi_irq</p></li><li class="listitem"><p>handle_bad_irq</p></li></ul></div><p> 4 The interrupt flow handlers (either pre-defined or architecture 5 specific) are assigned to specific interrupts by the architecture 6 either during bootup or during device initialization. 7 </p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="Default_flow_implementations"></a>Default flow implementations</h3></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Helper_functions">Helper functions</a></span></dt></dl></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Helper_functions"></a>Helper functions</h4></div></div></div><p> 8 The helper functions call the chip primitives and 9 are used by the default flow implementations. 10 The following helper functions are implemented (simplified excerpt): 11 </p><pre class="programlisting"> 12default_enable(struct irq_data *data) 13{ 14 desc->irq_data.chip->irq_unmask(data); 15} 16 17default_disable(struct irq_data *data) 18{ 19 if (!delay_disable(data)) 20 desc->irq_data.chip->irq_mask(data); 21} 22 23default_ack(struct irq_data *data) 24{ 25 chip->irq_ack(data); 26} 27 28default_mask_ack(struct irq_data *data) 29{ 30 if (chip->irq_mask_ack) { 31 chip->irq_mask_ack(data); 32 } else { 33 chip->irq_mask(data); 34 chip->irq_ack(data); 35 } 36} 37 38noop(struct irq_data *data)) 39{ 40} 41 42 </pre><p> 43 </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="Default_flow_handler_implementations"></a>Default flow handler implementations</h3></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Default_Level_IRQ_flow_handler">Default Level IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Default_FASTEOI_IRQ_flow_handler">Default Fast EOI IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Default_Edge_IRQ_flow_handler">Default Edge IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Default_simple_IRQ_flow_handler">Default simple IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#Default_per_CPU_flow_handler">Default per CPU flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#EOI_Edge_IRQ_flow_handler">EOI Edge IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="Highlevel_IRQ_flow_handlers.html#BAD_IRQ_flow_handler">Bad IRQ flow handler</a></span></dt></dl></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Default_Level_IRQ_flow_handler"></a>Default Level IRQ flow handler</h4></div></div></div><p> 44 handle_level_irq provides a generic implementation 45 for level-triggered interrupts. 46 </p><p> 47 The following control flow is implemented (simplified excerpt): 48 </p><pre class="programlisting"> 49desc->irq_data.chip->irq_mask_ack(); 50handle_irq_event(desc->action); 51desc->irq_data.chip->irq_unmask(); 52 </pre><p> 53 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Default_FASTEOI_IRQ_flow_handler"></a>Default Fast EOI IRQ flow handler</h4></div></div></div><p> 54 handle_fasteoi_irq provides a generic implementation 55 for interrupts, which only need an EOI at the end of 56 the handler. 57 </p><p> 58 The following control flow is implemented (simplified excerpt): 59 </p><pre class="programlisting"> 60handle_irq_event(desc->action); 61desc->irq_data.chip->irq_eoi(); 62 </pre><p> 63 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Default_Edge_IRQ_flow_handler"></a>Default Edge IRQ flow handler</h4></div></div></div><p> 64 handle_edge_irq provides a generic implementation 65 for edge-triggered interrupts. 66 </p><p> 67 The following control flow is implemented (simplified excerpt): 68 </p><pre class="programlisting"> 69if (desc->status & running) { 70 desc->irq_data.chip->irq_mask_ack(); 71 desc->status |= pending | masked; 72 return; 73} 74desc->irq_data.chip->irq_ack(); 75desc->status |= running; 76do { 77 if (desc->status & masked) 78 desc->irq_data.chip->irq_unmask(); 79 desc->status &= ~pending; 80 handle_irq_event(desc->action); 81} while (status & pending); 82desc->status &= ~running; 83 </pre><p> 84 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Default_simple_IRQ_flow_handler"></a>Default simple IRQ flow handler</h4></div></div></div><p> 85 handle_simple_irq provides a generic implementation 86 for simple interrupts. 87 </p><p> 88 Note: The simple flow handler does not call any 89 handler/chip primitives. 90 </p><p> 91 The following control flow is implemented (simplified excerpt): 92 </p><pre class="programlisting"> 93handle_irq_event(desc->action); 94 </pre><p> 95 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="Default_per_CPU_flow_handler"></a>Default per CPU flow handler</h4></div></div></div><p> 96 handle_percpu_irq provides a generic implementation 97 for per CPU interrupts. 98 </p><p> 99 Per CPU interrupts are only available on SMP and 100 the handler provides a simplified version without 101 locking. 102 </p><p> 103 The following control flow is implemented (simplified excerpt): 104 </p><pre class="programlisting"> 105if (desc->irq_data.chip->irq_ack) 106 desc->irq_data.chip->irq_ack(); 107handle_irq_event(desc->action); 108if (desc->irq_data.chip->irq_eoi) 109 desc->irq_data.chip->irq_eoi(); 110 </pre><p> 111 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="EOI_Edge_IRQ_flow_handler"></a>EOI Edge IRQ flow handler</h4></div></div></div><p> 112 handle_edge_eoi_irq provides an abnomination of the edge 113 handler which is solely used to tame a badly wreckaged 114 irq controller on powerpc/cell. 115 </p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="BAD_IRQ_flow_handler"></a>Bad IRQ flow handler</h4></div></div></div><p> 116 handle_bad_irq is used for spurious interrupts which 117 have no real handler assigned.. 118 </p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="Quirks_and_optimizations"></a>Quirks and optimizations</h3></div></div></div><p> 119 The generic functions are intended for 'clean' architectures and chips, 120 which have no platform-specific IRQ handling quirks. If an architecture 121 needs to implement quirks on the 'flow' level then it can do so by 122 overriding the high-level irq-flow handler. 123 </p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="Delayed_interrupt_disable"></a>Delayed interrupt disable</h3></div></div></div><p> 124 This per interrupt selectable feature, which was introduced by Russell 125 King in the ARM interrupt implementation, does not mask an interrupt 126 at the hardware level when disable_irq() is called. The interrupt is 127 kept enabled and is masked in the flow handler when an interrupt event 128 happens. This prevents losing edge interrupts on hardware which does 129 not store an edge interrupt event while the interrupt is disabled at 130 the hardware level. When an interrupt arrives while the IRQ_DISABLED 131 flag is set, then the interrupt is masked at the hardware level and 132 the IRQ_PENDING bit is set. When the interrupt is re-enabled by 133 enable_irq() the pending bit is checked and if it is set, the 134 interrupt is resent either via hardware or by a software resend 135 mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when 136 you want to use the delayed interrupt disable feature and your 137 hardware is not capable of retriggering an interrupt.) 138 The delayed interrupt disable is not configurable. 139 </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="Highlevel_Driver_API.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="Abstraction.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="Chiplevel_hardware_encapsulation.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">High-level Driver API </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chip-level hardware encapsulation</td></tr></table></div></body></html> 140