Sophie

Sophie

distrib > CentOS > 6 > i386 > by-pkgid > cf93d8a8acdcc6fe2225039da0502495 > files > 1449

kernel-doc-2.6.32-131.17.1.el6.centos.plus.noarch.rpm

<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Highlevel IRQ flow handlers</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="Linux generic IRQ handling" /><link rel="up" href="ch04.html" title="Chapter&#160;4.&#160;Abstraction layers" /><link rel="prev" href="ch04s02.html" title="Highlevel Driver API" /><link rel="next" href="ch04s04.html" title="Chiplevel hardware encapsulation" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Highlevel IRQ flow handlers</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04s02.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="ch04s04.html">Next</a></td></tr></table><hr /></div><div class="sect1" title="Highlevel IRQ flow handlers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Highlevel_IRQ_flow_handlers"></a>Highlevel IRQ flow handlers</h2></div></div></div><div class="toc"><dl><dt><span class="sect2"><a href="ch04s03.html#Default_flow_implementations">Default flow implementations</a></span></dt><dt><span class="sect2"><a href="ch04s03.html#Default_flow_handler_implementations">Default flow handler implementations</a></span></dt><dt><span class="sect2"><a href="ch04s03.html#Quirks_and_optimizations">Quirks and optimizations</a></span></dt><dt><span class="sect2"><a href="ch04s03.html#Delayed_interrupt_disable">Delayed interrupt disable</a></span></dt></dl></div><p>
	  The generic layer provides a set of pre-defined irq-flow methods:
	  </p><div class="itemizedlist"><ul class="itemizedlist" 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_simple_irq</p></li><li class="listitem"><p>handle_percpu_irq</p></li></ul></div><p>
	  The interrupt flow handlers (either predefined or architecture
	  specific) are assigned to specific interrupts by the architecture
	  either during bootup or during device initialization.
	</p><div class="sect2" title="Default flow implementations"><div class="titlepage"><div><div><h3 class="title"><a id="Default_flow_implementations"></a>Default flow implementations</h3></div></div></div><div class="toc"><dl><dt><span class="sect3"><a href="ch04s03.html#Helper_functions">Helper functions</a></span></dt></dl></div><div class="sect3" title="Helper functions"><div class="titlepage"><div><div><h4 class="title"><a id="Helper_functions"></a>Helper functions</h4></div></div></div><p>
		The helper functions call the chip primitives and
		are used by the default flow implementations.
		The following helper functions are implemented (simplified excerpt):
		</p><pre class="programlisting">
default_enable(irq)
{
	desc-&gt;chip-&gt;unmask(irq);
}

default_disable(irq)
{
	if (!delay_disable(irq))
		desc-&gt;chip-&gt;mask(irq);
}

default_ack(irq)
{
	chip-&gt;ack(irq);
}

default_mask_ack(irq)
{
	if (chip-&gt;mask_ack) {
		chip-&gt;mask_ack(irq);
	} else {
		chip-&gt;mask(irq);
		chip-&gt;ack(irq);
	}
}

noop(irq)
{
}

		</pre><p>
	        </p></div></div><div class="sect2" title="Default flow handler implementations"><div class="titlepage"><div><div><h3 class="title"><a id="Default_flow_handler_implementations"></a>Default flow handler implementations</h3></div></div></div><div class="toc"><dl><dt><span class="sect3"><a href="ch04s03.html#Default_Level_IRQ_flow_handler">Default Level IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="ch04s03.html#Default_Edge_IRQ_flow_handler">Default Edge IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="ch04s03.html#Default_simple_IRQ_flow_handler">Default simple IRQ flow handler</a></span></dt><dt><span class="sect3"><a href="ch04s03.html#Default_per_CPU_flow_handler">Default per CPU flow handler</a></span></dt></dl></div><div class="sect3" title="Default Level IRQ flow handler"><div class="titlepage"><div><div><h4 class="title"><a id="Default_Level_IRQ_flow_handler"></a>Default Level IRQ flow handler</h4></div></div></div><p>
		handle_level_irq provides a generic implementation
		for level-triggered interrupts.
		</p><p>
		The following control flow is implemented (simplified excerpt):
		</p><pre class="programlisting">
desc-&gt;chip-&gt;start();
handle_IRQ_event(desc-&gt;action);
desc-&gt;chip-&gt;end();
		</pre><p>
		</p></div><div class="sect3" title="Default Edge IRQ flow handler"><div class="titlepage"><div><div><h4 class="title"><a id="Default_Edge_IRQ_flow_handler"></a>Default Edge IRQ flow handler</h4></div></div></div><p>
		handle_edge_irq provides a generic implementation
		for edge-triggered interrupts.
		</p><p>
		The following control flow is implemented (simplified excerpt):
		</p><pre class="programlisting">
if (desc-&gt;status &amp; running) {
	desc-&gt;chip-&gt;hold();
	desc-&gt;status |= pending | masked;
	return;
}
desc-&gt;chip-&gt;start();
desc-&gt;status |= running;
do {
	if (desc-&gt;status &amp; masked)
		desc-&gt;chip-&gt;enable();
	desc-&gt;status &amp;= ~pending;
	handle_IRQ_event(desc-&gt;action);
} while (status &amp; pending);
desc-&gt;status &amp;= ~running;
desc-&gt;chip-&gt;end();
		</pre><p>
		</p></div><div class="sect3" title="Default simple IRQ flow handler"><div class="titlepage"><div><div><h4 class="title"><a id="Default_simple_IRQ_flow_handler"></a>Default simple IRQ flow handler</h4></div></div></div><p>
		handle_simple_irq provides a generic implementation
		for simple interrupts.
		</p><p>
		Note: The simple flow handler does not call any
		handler/chip primitives.
		</p><p>
		The following control flow is implemented (simplified excerpt):
		</p><pre class="programlisting">
handle_IRQ_event(desc-&gt;action);
		</pre><p>
		</p></div><div class="sect3" title="Default per CPU flow handler"><div class="titlepage"><div><div><h4 class="title"><a id="Default_per_CPU_flow_handler"></a>Default per CPU flow handler</h4></div></div></div><p>
		handle_percpu_irq provides a generic implementation
		for per CPU interrupts.
		</p><p>
		Per CPU interrupts are only available on SMP and
		the handler provides a simplified version without
		locking.
		</p><p>
		The following control flow is implemented (simplified excerpt):
		</p><pre class="programlisting">
desc-&gt;chip-&gt;start();
handle_IRQ_event(desc-&gt;action);
desc-&gt;chip-&gt;end();
		</pre><p>
		</p></div></div><div class="sect2" title="Quirks and optimizations"><div class="titlepage"><div><div><h3 class="title"><a id="Quirks_and_optimizations"></a>Quirks and optimizations</h3></div></div></div><p>
	The generic functions are intended for 'clean' architectures and chips,
	which have no platform-specific IRQ handling quirks. If an architecture
	needs to implement quirks on the 'flow' level then it can do so by
	overriding the highlevel irq-flow handler.
	</p></div><div class="sect2" title="Delayed interrupt disable"><div class="titlepage"><div><div><h3 class="title"><a id="Delayed_interrupt_disable"></a>Delayed interrupt disable</h3></div></div></div><p>
	This per interrupt selectable feature, which was introduced by Russell
	King in the ARM interrupt implementation, does not mask an interrupt
	at the hardware level when disable_irq() is called. The interrupt is
	kept enabled and is masked in the flow handler when an interrupt event
	happens. This prevents losing edge interrupts on hardware which does
	not store an edge interrupt event while the interrupt is disabled at
	the hardware level. When an interrupt arrives while the IRQ_DISABLED
	flag is set, then the interrupt is masked at the hardware level and
	the IRQ_PENDING bit is set. When the interrupt is re-enabled by
	enable_irq() the pending bit is checked and if it is set, the
	interrupt is resent either via hardware or by a software resend
	mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
	you want to use the delayed interrupt disable feature and your
	hardware is not capable of retriggering	an interrupt.)
	The delayed interrupt disable can be runtime enabled, per interrupt,
	by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
	</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch04s02.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="ch04.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="ch04s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Highlevel 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;Chiplevel hardware encapsulation</td></tr></table></div></body></html>