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&#160;4.&#160;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>&#160;</td><th width="60%" align="center">Chapter&#160;4.&#160;Abstraction layers</th><td width="20%" align="right">&#160;<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-&gt;irq_data.chip-&gt;irq_unmask(data);
15}
16
17default_disable(struct irq_data *data)
18{
19	if (!delay_disable(data))
20		desc-&gt;irq_data.chip-&gt;irq_mask(data);
21}
22
23default_ack(struct irq_data *data)
24{
25	chip-&gt;irq_ack(data);
26}
27
28default_mask_ack(struct irq_data *data)
29{
30	if (chip-&gt;irq_mask_ack) {
31		chip-&gt;irq_mask_ack(data);
32	} else {
33		chip-&gt;irq_mask(data);
34		chip-&gt;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-&gt;irq_data.chip-&gt;irq_mask_ack();
50handle_irq_event(desc-&gt;action);
51desc-&gt;irq_data.chip-&gt;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-&gt;action);
61desc-&gt;irq_data.chip-&gt;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-&gt;status &amp; running) {
70	desc-&gt;irq_data.chip-&gt;irq_mask_ack();
71	desc-&gt;status |= pending | masked;
72	return;
73}
74desc-&gt;irq_data.chip-&gt;irq_ack();
75desc-&gt;status |= running;
76do {
77	if (desc-&gt;status &amp; masked)
78		desc-&gt;irq_data.chip-&gt;irq_unmask();
79	desc-&gt;status &amp;= ~pending;
80	handle_irq_event(desc-&gt;action);
81} while (status &amp; pending);
82desc-&gt;status &amp;= ~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-&gt;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-&gt;irq_data.chip-&gt;irq_ack)
106	desc-&gt;irq_data.chip-&gt;irq_ack();
107handle_irq_event(desc-&gt;action);
108if (desc-&gt;irq_data.chip-&gt;irq_eoi)
109        desc-&gt;irq_data.chip-&gt;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>&#160;</td><td width="20%" align="center"><a accesskey="u" href="Abstraction.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="Chiplevel_hardware_encapsulation.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">High-level Driver API&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Chip-level hardware encapsulation</td></tr></table></div></body></html>
140