Discussion:
[PATCH 00/32] Convert ARM to generic irq subsystem
(too old to reply)
Thomas Gleixner
2006-04-07 19:45:33 UTC
Permalink
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.

Why is this patch useful ?

During a lengthy discussion on arm-linux-kernel mailing list, ARM
maintainer Russell King posted a list of requirements that any
integration of ARM into the generic interrupt layer would have to
implement:

http://marc.theaimsgroup.com/?l=linux-arm-kernel&m=110693029912801&w=2

The background of the discussion was an attempt to modify the ARM
interrupt handling code to make the adoption of Ingo's Realtime
Preemption patches for ARM possible. The proposed changes were not yet
acceptable from Russell's point of view and Ingo was also reluctant to
accept a non-generic version of his interrupt preemption work open-coded
into the ARM architecture.

To solve this problem, we analysed the ARM specific interrupt code and
extended the generic interrupt layer with the interrupt abstractions
pioneered in the ARM port - for example 'struct irq_chip' and 'struct
irq_type', per-interrupt-type entry handlers instead of the
all-inclusive __do_IRQ() superhandler, etc. Then we added a conversion
model to the generic interrupt layer, to reduce the impact of inevitable
API changes to the ARM port.

Further reasoning and lots of details of the new 'unified' IRQ code are
described in the DocBook docs of the patch along with the documentation
of the resulting API. An online version is available at:

http://www.tglx.de/projects/armirq/DocBook/index.html

A broken out patch-series is available at:

http://tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq4.patches.tar.bz2

The patch has been tested on a broad range of ARM platforms and the
featureset requested by Russell has been verified. There is no
functional change to the other architectures which use the generic
interrupt layer, but the type-dependent entry level handler seperation
also has possible benefits for those architectures.

Thomas, Ingo

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:42 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-footbridge/dc21285-timer.c | 1 +
arch/arm/mach-footbridge/isa-irq.c | 19 ++++++++++++++++---
arch/arm/mach-footbridge/isa-timer.c | 1 +
3 files changed, 18 insertions(+), 3 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-footbridge/dc21285-timer.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-footbridge/dc21285-timer.c
+++ linux-2.6.16-git/arch/arm/mach-footbridge/dc21285-timer.c
@@ -6,6 +6,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <asm/irq.h>

Index: linux-2.6.16-git/arch/arm/mach-footbridge/isa-irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-footbridge/isa-irq.c
+++ linux-2.6.16-git/arch/arm/mach-footbridge/isa-irq.c
@@ -102,6 +102,17 @@ static struct irqaction irq_cascade = {
static struct resource pic1_resource = { "pic1", 0x20, 0x3f };
static struct resource pic2_resource = { "pic2", 0xa0, 0xbf };

+static DEFINE_IRQ_CHAINED_TYPE(isa_irq_handler);
+
+static unsigned int startup_irq_disabled(unsigned int irq)
+{
+ return 0;
+}
+
+/* Interrupt type for irqs which must not be
+ * automatically enabled in reqeust_irq */
+static struct irq_type level_type_nostart;
+
void __init isa_init_irq(unsigned int host_irq)
{
unsigned int irq;
@@ -159,9 +170,11 @@ void __init isa_init_irq(unsigned int ho
* There appears to be a missing pull-up
* resistor on this line.
*/
- if (machine_is_netwinder())
- set_irq_flags(_ISA_IRQ(11), IRQF_VALID |
- IRQF_PROBE | IRQF_NOAUTOEN);
+ if (machine_is_netwinder()) {
+ level_type_nostart = default_level_type;
+ level_type_nostart.startup = startup_irq_disabled;
+ set_irq_handler(_ISA_IRQ(11), &level_type_nostart);
+ }
}
}

Index: linux-2.6.16-git/arch/arm/mach-footbridge/isa-timer.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-footbridge/isa-timer.c
+++ linux-2.6.16-git/arch/arm/mach-footbridge/isa-timer.c
@@ -6,6 +6,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <asm/io.h>
#include <asm/irq.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:50 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-lh7a40x/arch-kev7a400.c | 2 ++
arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 2 ++
arch/arm/mach-lh7a40x/irq-kev7a400.c | 2 ++
arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 1 +
arch/arm/mach-lh7a40x/time.c | 1 +
5 files changed, 8 insertions(+)

Index: linux-2.6.16-git/arch/arm/mach-lh7a40x/arch-kev7a400.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ linux-2.6.16-git/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -81,6 +81,8 @@ static void kev7a400_cpld_handler (unsig
}
}

+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
void __init lh7a40x_init_board_irq (void)
{
int irq;
Index: linux-2.6.16-git/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ linux-2.6.16-git/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <asm/hardware.h>
#include <asm/setup.h>
@@ -173,6 +174,7 @@ static void lpd7a40x_cpld_handler (unsig
desc->chip->unmask (irq); /* Level-triggered need this */
}

+static DEFINE_IRQ_CHAINED_TYPE(lpd7a40x_cpld_handler);

void __init lh7a40x_init_board_irq (void)
{
Index: linux-2.6.16-git/arch/arm/mach-lh7a40x/irq-kev7a400.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-lh7a40x/irq-kev7a400.c
+++ linux-2.6.16-git/arch/arm/mach-lh7a40x/irq-kev7a400.c
@@ -61,6 +61,8 @@ lh7a400_cpld_handler (unsigned int irq,
}
}

+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
/* IRQ initialization */

void __init
Index: linux-2.6.16-git/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ linux-2.6.16-git/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -72,6 +72,7 @@ static void lh7a40x_cpld_handler (unsign
desc->chip->unmask (irq); /* Level-triggered need this */
}

+static DEFINE_IRQ_CHAINED_TYPE(lh7a40x_cpld_handler);

/* IRQ initialization */

Index: linux-2.6.16-git/arch/arm/mach-lh7a40x/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-lh7a40x/time.c
+++ linux-2.6.16-git/arch/arm/mach-lh7a40x/time.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/time.h>

#include <asm/hardware.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:45 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-integrator/core.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-integrator/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-integrator/core.c
+++ linux-2.6.16-git/arch/arm/mach-integrator/core.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/termios.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:05 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/input/serio/sa1111ps2.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/drivers/input/serio/sa1111ps2.c
===================================================================
--- linux-2.6.16-git.orig/drivers/input/serio/sa1111ps2.c
+++ linux-2.6.16-git/drivers/input/serio/sa1111ps2.c
@@ -13,6 +13,7 @@
#include <linux/serio.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/device.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:48 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-ixp4xx/coyote-pci.c | 1 +
arch/arm/mach-ixp4xx/ixdp425-pci.c | 1 +
arch/arm/mach-ixp4xx/ixdpg425-pci.c | 2 +-
arch/arm/mach-ixp4xx/nas100d-pci.c | 1 +
arch/arm/mach-ixp4xx/nas100d-power.c | 1 +
5 files changed, 5 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/arch/arm/mach-ixp4xx/coyote-pci.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp4xx/coyote-pci.c
+++ linux-2.6.16-git/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/irq.h>

#include <asm/mach-types.h>
#include <asm/hardware.h>
Index: linux-2.6.16-git/arch/arm/mach-ixp4xx/ixdp425-pci.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ linux-2.6.16-git/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -16,6 +16,7 @@

#include <linux/kernel.h>
#include <linux/config.h>
+#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
Index: linux-2.6.16-git/arch/arm/mach-ixp4xx/ixdpg425-pci.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ linux-2.6.16-git/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -16,10 +16,10 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/irq.h>

#include <asm/mach-types.h>
#include <asm/hardware.h>
-#include <asm/irq.h>

#include <asm/mach/pci.h>

Index: linux-2.6.16-git/arch/arm/mach-ixp4xx/nas100d-pci.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp4xx/nas100d-pci.c
+++ linux-2.6.16-git/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -18,6 +18,7 @@
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/irq.h>

#include <asm/mach/pci.h>
#include <asm/mach-types.h>
Index: linux-2.6.16-git/arch/arm/mach-ixp4xx/nas100d-power.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp4xx/nas100d-power.c
+++ linux-2.6.16-git/arch/arm/mach-ixp4xx/nas100d-power.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <asm/mach-types.h>


--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:39 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/kernel/ecard.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

Index: linux-2.6.16-git/arch/arm/kernel/ecard.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/kernel/ecard.c
+++ linux-2.6.16-git/arch/arm/kernel/ecard.c
@@ -620,7 +620,7 @@ ecard_irqexp_handler(unsigned int irq, s
ecard_t *ec = slot_to_ecard(slot);

if (ec->claimed) {
- struct irqdesc *d = irqdesc + ec->irq;
+ struct irqdesc *d = irq_desc + ec->irq;
/*
* this ugly code is so that we can operate a
* prioritorising system:
@@ -1051,6 +1051,9 @@ ecard_probe(int slot, card_type_t type)
return rc;
}

+static DEFINE_IRQ_CHAINED_TYPE(ecard_irqexp_handler);
+static DEFINE_IRQ_CHAINED_TYPE(ecard_irq_handler);
+
/*
* Initialise the expansion card system.
* Locate all hardware - interrupt management and
@@ -1080,8 +1083,10 @@ static int __init ecard_init(void)

irqhw = ecard_probeirqhw();

- set_irq_chained_handler(IRQ_EXPANSIONCARD,
- irqhw ? ecard_irqexp_handler : ecard_irq_handler);
+ if (irqhw)
+ set_irq_chained_handler(IRQ_EXPANSIONCARD, ecard_irqexp_handler);
+ else
+ set_irq_chained_handler(IRQ_EXPANSIONCARD, ecard_irq_handler);

ecard_proc_init();


--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:34 UTC
Permalink
Add docbook file - includes API documentation.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

Documentation/DocBook/Makefile | 3
Documentation/DocBook/genericirq.tmpl | 560 ++++++++++++++++++++++++++++++++++
2 files changed, 562 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/Documentation/DocBook/Makefile
===================================================================
--- linux-2.6.16-git.orig/Documentation/DocBook/Makefile
+++ linux-2.6.16-git/Documentation/DocBook/Makefile
@@ -10,7 +10,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml \
kernel-api.xml journal-api.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
+ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
+ genericirq.xml

###
# The build process is as follows (targets):
Index: linux-2.6.16-git/Documentation/DocBook/genericirq.tmpl
===================================================================
--- /dev/null
+++ linux-2.6.16-git/Documentation/DocBook/genericirq.tmpl
@@ -0,0 +1,560 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="Generic-IRQ-Guide">
+ <bookinfo>
+ <title>Linux generic IRQ handling</title>
+
+ <authorgroup>
+ <author>
+ <firstname>Thomas</firstname>
+ <surname>Gleixner</surname>
+ <affiliation>
+ <address>
+ <email>***@linutronix.de</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Ingo</firstname>
+ <surname>Molnar</surname>
+ <affiliation>
+ <address>
+ <email>***@elte.hu</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2005</year>
+ <holder>Thomas Gleixner</holder>
+ </copyright>
+ <copyright>
+ <year>2005</year>
+ <holder>Ingo Molnar</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>
+ This documentation is free software; you can redistribute
+ it and/or modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+ </para>
+
+ <para>
+ This program is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ </para>
+
+ <para>
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ MA 02111-1307 USA
+ </para>
+
+ <para>
+ For more details see the file COPYING in the source
+ distribution of Linux.
+ </para>
+ </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+ <chapter id="intro">
+ <title>Introduction</title>
+ <para>
+ The generic interrupt handling layer is designed to provide a
+ complete abstraction of interrupt handling for device drivers
+ and is able to handle all different types of interrupt controller
+ hardware. Device drivers use generic API function to request, enable,
+ disable and free interrupts. The drivers do not have to know anything
+ about interrupt hardware, so they can be used on different hardware
+ platforms without code changes.
+ </para>
+ <para>
+ This documentation is provided for developers who want to implement
+ architecture interrupt support based on the Generic IRQ handling layer.
+ </para>
+ </chapter>
+
+ <chapter id="rationale">
+ <title>Rationale</title>
+ <para>
+ The original implementation of interrupt handling in Linux is using
+ the __do_IRQ() super-handler, which must be able to deal with every
+ type of interrupt logic. This is achieved by an 'interrupt type'
+ structure and runtime flags to handle special cases.
+ Furthermore the superhandler assumed a certain type of interrupt
+ handling hardware and turned out to be not capable of handling all
+ kind of interrupt controller hardware which can be found through
+ the architectures. The all in one approach also adds unnecessary
+ complexity for every user.
+ </para>
+ <para>
+ Originally, Russell King identified different types of handlers to
+ build a quite universal set for the ARM interrupt handler
+ implementation in Linux 2.5/2.6. He distiguished between:
+ <itemizedlist>
+ <listitem><para>Level type</para></listitem>
+ <listitem><para>Edge type</para></listitem>
+ <listitem><para>Simple type</para></listitem>
+ </itemizedlist>
+ In the SMP world of the __do_IRQ() super-handler another type
+ was identified:
+ <itemizedlist>
+ <listitem><para>Per CPU type</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ This split implementation of handlers allows to optimize the flow
+ of the interrupt handling for each specific interrupt type.
+ This reduces complexitiy in that particular code path and allows
+ the optimized handling of a given type.
+ </para>
+ <para>
+ The original general implementation uses interrupt_type structures
+ to differentiate the flow control in the super-handler. This
+ leads to a mix of flow logic and code related to hardware details.
+ Russell Kings ARM implementation which replaced the type by a chip
+ abstraction did the mix the other way around.
+ </para>
+ <para>
+ The natural conclusion was a clean seperation of the 'type flow'
+ and the 'chip'. Analysing a couple of architecture implementations
+ reveals that many of them can use a generic set of 'type flow'
+ implementations and only need to add the chip level specific code.
+ The seperation is also valuable for the (sub)architectures,
+ which need specific quirks in the type flow itself, because it
+ provides a more transparent design.
+ </para>
+ <para>
+ Each interrupt type implementation has assigned its own flow
+ handler, which should be normally one of the generic
+ implementations. The flow handler implementation makes it
+ simple to provide demultiplexing handlers which can be found in
+ embedded platforms on various architectures.
+ </para>
+ <para>
+ The seperation makes the generic interrupt handling more flexible
+ and extensible. An (sub)architecture can use a generic type flow
+ implementation for e.g. 'level type' interrupts and add a
+ (sub)architecture specific 'edge type' implementation.
+ </para>
+ <para>
+ To make the transition to the new model easier and prevent the
+ breakage of existing implementations the __do_IRQ() super-handler
+ is still available. This leads to a kind of duality for the time
+ being. Over time the new model should achieve a homogeneous
+ implementation scheme over all architectures with enhanced
+ maintainability and cleanliness.
+ </para>
+ </chapter>
+ <chapter id="bugs">
+ <title>Known Bugs And Assumptions</title>
+ <para>
+ None (hopefully).
+ </para>
+ </chapter>
+
+ <chapter id="Abstraction">
+ <title>Abstraction layers</title>
+ <para>
+ There are three main levels of abstraction in the interrupt code:
+ <orderedlist>
+ <listitem><para>Highlevel driver API</para></listitem>
+ <listitem><para>Abstract interrupt type</para></listitem>
+ <listitem><para>Chiplevel hardware encapsulation</para></listitem>
+ </orderedlist>
+ </para>
+ <para>
+ The seperation of interrupt type and chip level functionality
+ provides the most flexible design. This implementation can handle
+ all kinds of interrupt hardware and the necessary workarounds for
+ the interrupt types without the need of redundant implementations.
+ The seperation handles also edge and level type interrupts
+ on the same hardware chip.
+ </para>
+ <sect1>
+ <title>Interrupt control flow</title>
+ <para>
+ Each interrupt is described by an interrupt description structure
+ irq_desc. The interrupt is referenced by an 'unsigned int' numeric
+ value which selects the corresponding interrupt decription structure
+ in the description structures array.
+ The description structure contains status information and pointers
+ to the interrupt type structure and the interrupt chip structure
+ which are assigned to this interrupt.
+ </para>
+ <para>
+ Whenever an interrupt triggers, the lowlevel arch code calls into
+ the generic interrupt code by calling desc->handler->handle_irq().
+ This highlevel IRQ handling function only uses other
+ desc->handler primitives which describe the control flow operation
+ necessary for the interrupt type. These operations are calling
+ the chip primitives referenced by the assigned chip description
+ structure.
+ </para>
+ </sect1>
+ <sect1>
+ <title>Highlevel Driver API</title>
+ <para>
+ The highlevel Driver API consists of following functions:
+ <itemizedlist>
+ <listitem><para>request_irq()</para></listitem>
+ <listitem><para>free_irq()</para></listitem>
+ <listitem><para>disable_irq()</para></listitem>
+ <listitem><para>enable_irq()</para></listitem>
+ <listitem><para>disable_irq_nosync() (SMP only)</para></listitem>
+ <listitem><para>synchronize_irq() (SMP only)</para></listitem>
+ <listitem><para>set_irq_type()</para></listitem>
+ <listitem><para>set_irq_wake()</para></listitem>
+ <listitem><para>set_irq_data()</para></listitem>
+ <listitem><para>set_irq_chip()</para></listitem>
+ <listitem><para>set_irq_chip_data()</para></listitem>
+ </itemizedlist>
+ See the autogenerated function documentation for details.
+ </para>
+ </sect1>
+ <sect1>
+ <title>Abstract interrupt type</title>
+ <para>
+ The 'interrupt type' (struct irq_type) abstraction mainly consists of
+ methods which implement the 'interrupt handling flow'. The generic
+ layer provides a set of pre-defined types:
+ <itemizedlist>
+ <listitem><para>default_level_type</para></listitem>
+ <listitem><para>default_edge_type</para></listitem>
+ <listitem><para>default_simple_type</para></listitem>
+ <listitem><para>default_percpu_type</para></listitem>
+ </itemizedlist>
+ The default type implementations use the generic type handlers.
+ <itemizedlist>
+ <listitem><para>handle_level_type</para></listitem>
+ <listitem><para>handle_edge_type</para></listitem>
+ <listitem><para>handle_simple_type</para></listitem>
+ <listitem><para>handle_percpu_type</para></listitem>
+ </itemizedlist>
+ The interrupt types (either predefined or architecture specific) are
+ assigned to specific interrupts by the architecture either during
+ bootup or during device initialization.
+ </para>
+ <sect2>
+ <title>Default type implementations</title>
+ <sect3>
+ <title>Helper functions</title>
+ <para>
+ The helper functions call the chip primitives and
+ are used by the default type implementations.
+ Following helper functions are implemented (simplified excerpt):
+ <programlisting>
+default_enable(irq)
+{
+ desc->chip->unmask(irq);
+}
+
+default_disable(irq)
+{
+ desc->chip->mask(irq);
+}
+
+default_ack(irq)
+{
+ chip->ack(irq);
+}
+
+default_mask_ack(irq)
+{
+ if (chip->mask_ack) {
+ chip->mask_ack(irq);
+ } else {
+ chip->mask(irq);
+ chip->ack(irq);
+ }
+}
+
+noop(irq)
+{
+}
+
+default_set_type(irq, type)
+{
+ if (desc->chip->set_type) {
+ if (desc->chip->set_type(irq, type))
+ return NULL;
+ }
+
+ return default_handler for type;
+}
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default Level IRQ type</title>
+ <para>
+ The default Level IRQ type implements the functions
+ <simplelist type="horiz" columns="2">
+ <member>enable</member><member>default_enable</member>
+ <member>disable</member><member>default_disable</member>
+ <member>start</member><member>default_mask_ack</member>
+ <member>end</member><member>default_enable</member>
+ <member>handle_irq</member><member>handle_level_irq</member>
+ <member>set_type</member><member>default_set_type</member>
+ </simplelist>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default Edge IRQ type</title>
+ <para>
+ The default Edge IRQ type implements the functions
+ <simplelist type="horiz" columns="2">
+ <member>enable</member><member>default_enable</member>
+ <member>disable</member><member>default_disable</member>
+ <member>start</member><member>default_ack</member>
+ <member>hold</member><member>default_mask_ack</member>
+ <member>end</member><member>noop</member>
+ <member>handle_irq</member><member>handle_edge_irq</member>
+ <member>set_type</member><member>default_set_type</member>
+ </simplelist>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default simple IRQ type</title>
+ <para>
+ The default simple IRQ type implements the functions
+ <simplelist type="horiz" columns="2">
+ <member>enable</member><member>noop</member>
+ <member>disable</member><member>noop</member>
+ <member>handle_irq</member><member>handle_simple_irq</member>
+ </simplelist>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default per CPU IRQ type</title>
+ <para>
+ The default per CPU IRQ type implements the functions
+ <simplelist type="horiz" columns="2">
+ <member>enable</member><member>default_enable</member>
+ <member>disable</member><member>default_disable</member>
+ <member>start</member><member>default_ack</member>
+ <member>end</member><member>default_enable</member>
+ <member>handle_irq</member><member>handle_percpu_irq</member>
+ </simplelist>
+ </para>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Default type handler implementations</title>
+ <sect3>
+ <title>Default Level IRQ type handler</title>
+ <para>
+ handle_level_type provides a generic implementation
+ for level type interrupts.
+ </para>
+ <para>
+ Following control flow is implemented (simplified excerpt):
+ <programlisting>
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default Edge IRQ type handler</title>
+ <para>
+ handle_edge_type provides a generic implementation
+ for edge type interrupts.
+ </para>
+ <para>
+ Following control flow is implemented (simplified excerpt):
+ <programlisting>
+if (desc->status &amp; running) {
+ desc->handler->hold();
+ desc->status |= pending | masked;
+ return;
+}
+desc->handler->start();
+desc->status |= running;
+do {
+ if (desc->status &amp; masked)
+ desc->handler->enable();
+ desc-status &amp;= ~pending;
+ handle_IRQ_event(desc->action);
+} while (status &amp; pending);
+desc-status &amp;= ~running;
+desc->handler->end();
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default simple IRQ type handler</title>
+ <para>
+ handle_simple_type provides a generic implementation
+ for simple type interrupts.
+ </para>
+ <para>
+ Note: The simple type handler does not call any
+ handler/chip primitives.
+ </para>
+ <para>
+ Following control flow is implemented (simplified excerpt):
+ <programlisting>
+handle_IRQ_event(desc->action);
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Default per CPU type handler</title>
+ <para>
+ handle_percpu_type provides a generic implementation
+ for per CPU type interrupts.
+ </para>
+ <para>
+ Per CPU interrupts are only available on SMP and
+ the handler provides a simplified version without
+ locking.
+ </para>
+ <para>
+ Following control flow is implemented (simplified excerpt):
+ <programlisting>
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+ </programlisting>
+ </para>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Architecture specific type implementation</title>
+ <para>
+ If an architecture needs to implement its own type structures, then
+ the following primitives have to be implemented:
+ <itemizedlist>
+ <listitem><para>handle_irq() - The handle_irq function pointer should preferably point to
+ one of the generic type handler functions</para></listitem>
+ <listitem><para>startup() - Optional</para></listitem>
+ <listitem><para>shutdown() - Optional</para></listitem>
+ <listitem><para>enable()</para></listitem>
+ <listitem><para>disable()</para></listitem>
+ <listitem><para>start()</para></listitem>
+ <listitem><para>hold() - For edge type interupts only</para></listitem>
+ <listitem><para>end()</para></listitem>
+ <listitem><para>set_type - Optional</para></listitem>
+ <listitem><para>set_affinity - SMP only</para></listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2>
+ <title>Quirks and optimizations</title>
+ <para>
+ 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 irqtype. This is also done for compatibility reasons, as
+ most architectures use irqtypes only at the moment.
+ </para>
+ <para>
+ An architecture could implement all of its IRQ logic via pushing
+ chip handling details into the irqtype's ->start()/->end()/->hold()
+ functions. This is only recommended when the underlying primitives
+ are pure chip primitives without additional quirks. The direct pointer
+ to the chip functions reduces the indirection level by one.
+ </para>
+ </sect2>
+ </sect1>
+ <sect1>
+ <title>Chiplevel hardware encapsulation</title>
+ <para>
+ The chip level hardware description structure irq_chip
+ contains all the direct chip relevant functions, which
+ can be utilized by the irq_type implementations.
+ <itemizedlist>
+ <listitem><para>ack()</para></listitem>
+ <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
+ <listitem><para>mask()</para></listitem>
+ <listitem><para>unmask()</para></listitem>
+ <listitem><para>retrigger() - Optional</para></listitem>
+ <listitem><para>set_type() - Optional</para></listitem>
+ <listitem><para>set_wake() - Optional</para></listitem>
+ </itemizedlist>
+ These primitives are strictly intended to mean what they say: ack means
+ ACK, masking means masking of an IRQ line, etc. It is up to the flow
+ handler(s) to use these basic units of lowlevel functionality.
+ </para>
+ </sect1>
+ </chapter>
+
+ <chapter id="doirq">
+ <title>__do_IRQ entry point</title>
+ <para>
+ The original implementation __do_IRQ() is an alternative entry
+ point for all types of interrupts.
+ </para>
+ <para>
+ This handler turned out to be not suitable for all
+ interrupt hardware and was therefor reimplemented with split
+ functionality for egde/level/simple/percpu interrupts. This is not
+ only a functional optimization. It also shortenes code pathes for
+ interrupts.
+ </para>
+ <para>
+ To make use of the split implementation, replace the call to
+ __do_IRQ by a call to desc->handler->handle_irq() and associate
+ the appropriate handler function to desc->handler->handle_irq().
+ In most cases the generic type and handler implementations should
+ be sufficient.
+ </para>
+ </chapter>
+
+ <chapter id="locking">
+ <title>Locking on SMP</title>
+ <para>
+ The locking of chip registers is up to the architecture that
+ defines the chip primitives. There is a chip->lock field that can be used
+ for serialization, but the generic layer does not touch it. The per-irq
+ structure is protected via desc->lock, by the generic layer.
+ </para>
+ </chapter>
+ <chapter id="structs">
+ <title>Structures</title>
+ <para>
+ This chapter contains the autogenerated documentation of the structures which are
+ used in the generic IRQ layer.
+ </para>
+!Iinclude/linux/irq.h
+ </chapter>
+
+ <chapter id="pubfunctions">
+ <title>Public Functions Provided</title>
+ <para>
+ This chapter contains the autogenerated documentation of the kernel API functions
+ which are exported.
+ </para>
+!Ekernel/irq/manage.c
+ </chapter>
+
+ <chapter id="intfunctions">
+ <title>Internal Functions Provided</title>
+ <para>
+ This chapter contains the autogenerated documentation of the internal functions.
+ </para>
+!Ikernel/irq/handle.c
+ </chapter>
+
+ <chapter id="credits">
+ <title>Credits</title>
+ <para>
+ The following people have contributed to this document:
+ <orderedlist>
+ <listitem><para>Thomas Gleixner<email>***@linutronix.de</email></para></listitem>
+ <listitem><para>Ingo Molnar<email>***@elte.hu</email></para></listitem>
+ </orderedlist>
+ </para>
+ </chapter>
+</book>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:36 UTC
Permalink
Switch the ARM irq core handling to the generic implementation. The
ARM specific header files now contain mostly migration stubs and
helper macros. Note that each machine type must be converted after
this step seperately. This was seperated out from the patch for easier
review.

The main changes for the machine type code is the conversion of the
type handlers to a 'type flow' and 'chip' model. This affects only the
multiplex interrupt handlers. A conversion macro needs to be added to
those implementations, which defines the data structure which is
registered by the set_irq_chained_handler() macro.

Some minor fixups of include files and the conversion of data
structure access is necessary all over the place.

The mostly macro based conversion was provided to allow an easy
migration of the existing implementations.

The code compiles on all defconfigs available in arch/arm/configs
except those which were broken also before applying the conversion
patches.

The code has been boot and runtime tested on following platforms:

PXA, EP93XX, IPX2000, IPX400, IMX, CLPS711X, H720X, S3C2410, OMAP.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/Kconfig | 4
arch/arm/kernel/fiq.c | 1
arch/arm/kernel/irq.c | 972 ++-------------------------------------------
include/asm-arm/dyntick.h | 6
include/asm-arm/hw_irq.h | 9
include/asm-arm/irq.h | 26 -
include/asm-arm/mach/irq.h | 144 +-----
7 files changed, 121 insertions(+), 1041 deletions(-)

Index: linux-2.6.16-git/arch/arm/Kconfig
===================================================================
--- linux-2.6.16-git.orig/arch/arm/Kconfig
+++ linux-2.6.16-git/arch/arm/Kconfig
@@ -47,6 +47,10 @@ config MCA
<file:Documentation/mca.txt> (and especially the web page given
there) before attempting to build an MCA bus kernel.

+config GENERIC_HARDIRQS
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
Index: linux-2.6.16-git/arch/arm/kernel/fiq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/kernel/fiq.c
+++ linux-2.6.16-git/arch/arm/kernel/fiq.c
@@ -38,6 +38,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/seq_file.h>

#include <asm/cacheflush.h>
Index: linux-2.6.16-git/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/kernel/irq.c
+++ linux-2.6.16-git/arch/arm/kernel/irq.c
@@ -27,6 +27,7 @@
#include <linux/signal.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/random.h>
@@ -38,192 +39,12 @@
#include <linux/kallsyms.h>
#include <linux/proc_fs.h>

-#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/mach/irq.h>
#include <asm/mach/time.h>

-/*
- * Maximum IRQ count. Currently, this is arbitary. However, it should
- * not be set too low to prevent false triggering. Conversely, if it
- * is set too high, then you could miss a stuck IRQ.
- *
- * Maybe we ought to set a timer and re-enable the IRQ at a later time?
- */
-#define MAX_IRQ_CNT 100000
-
-static int noirqdebug;
-static volatile unsigned long irq_err_count;
-static DEFINE_SPINLOCK(irq_controller_lock);
-static LIST_HEAD(irq_pending);
-
-struct irqdesc irq_desc[NR_IRQS];
void (*init_arch_irq)(void) __initdata = NULL;

-/*
- * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
- */
-#ifndef irq_finish
-#define irq_finish(irq) do { } while (0)
-#endif
-
-/*
- * Dummy mask/unmask handler
- */
-void dummy_mask_unmask_irq(unsigned int irq)
-{
-}
-
-irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs)
-{
- return IRQ_NONE;
-}
-
-void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- irq_err_count += 1;
- printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
-}
-
-static struct irqchip bad_chip = {
- .ack = dummy_mask_unmask_irq,
- .mask = dummy_mask_unmask_irq,
- .unmask = dummy_mask_unmask_irq,
-};
-
-static struct irqdesc bad_irq_desc = {
- .chip = &bad_chip,
- .handle = do_bad_IRQ,
- .pend = LIST_HEAD_INIT(bad_irq_desc.pend),
- .disable_depth = 1,
-};
-
-#ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
-
- while (desc->running)
- barrier();
-}
-EXPORT_SYMBOL(synchronize_irq);
-
-#define smp_set_running(desc) do { desc->running = 1; } while (0)
-#define smp_clear_running(desc) do { desc->running = 0; } while (0)
-#else
-#define smp_set_running(desc) do { } while (0)
-#define smp_clear_running(desc) do { } while (0)
-#endif
-
-/**
- * disable_irq_nosync - disable an irq without waiting
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Enables and disables
- * are nested. We do this lazily.
- *
- * This function may be called from IRQ context.
- */
-void disable_irq_nosync(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->disable_depth++;
- list_del_init(&desc->pend);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_nosync);
-
-/**
- * disable_irq - disable an irq and wait for completion
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Enables and disables
- * are nested. This functions waits for any pending IRQ
- * handlers for this interrupt to complete before returning.
- * If you use this function while holding a resource the IRQ
- * handler may need you will deadlock.
- *
- * This function may be called - with care - from IRQ context.
- */
-void disable_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
-
- disable_irq_nosync(irq);
- if (desc->action)
- synchronize_irq(irq);
-}
-EXPORT_SYMBOL(disable_irq);
-
-/**
- * enable_irq - enable interrupt handling on an irq
- * @irq: Interrupt to enable
- *
- * Re-enables the processing of interrupts on this IRQ line.
- * Note that this may call the interrupt handler, so you may
- * get unexpected results if you hold IRQs disabled.
- *
- * This function may be called from IRQ context.
- */
-void enable_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (unlikely(!desc->disable_depth)) {
- printk("enable_irq(%u) unbalanced from %p\n", irq,
- __builtin_return_address(0));
- } else if (!--desc->disable_depth) {
- desc->probing = 0;
- desc->chip->unmask(irq);
-
- /*
- * If the interrupt is waiting to be processed,
- * try to re-run it. We can't directly run it
- * from here since the caller might be in an
- * interrupt-protected region.
- */
- if (desc->pending && list_empty(&desc->pend)) {
- desc->pending = 0;
- if (!desc->chip->retrigger ||
- desc->chip->retrigger(irq))
- list_add(&desc->pend, &irq_pending);
- }
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(enable_irq);
-
-/*
- * Enable wake on selected irq
- */
-void enable_irq_wake(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (desc->chip->set_wake)
- desc->chip->set_wake(irq, 1);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(enable_irq_wake);
-
-void disable_irq_wake(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (desc->chip->set_wake)
- desc->chip->set_wake(irq, 0);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_wake);
+unsigned long irq_err_count;

int show_interrupts(struct seq_file *p, void *v)
{
@@ -243,8 +64,8 @@ int show_interrupts(struct seq_file *p,
}

if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_controller_lock, flags);
- action = irq_desc[i].action;
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
if (!action)
goto unlock;

@@ -257,7 +78,7 @@ int show_interrupts(struct seq_file *p,

seq_putc(p, '\n');
unlock:
- spin_unlock_irqrestore(&irq_controller_lock, flags);
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
#ifdef CONFIG_ARCH_ACORN
show_fiq_list(p, v);
@@ -271,270 +92,16 @@ unlock:
return 0;
}

-/*
- * IRQ lock detection.
- *
- * Hopefully, this should get us out of a few locked situations.
- * However, it may take a while for this to happen, since we need
- * a large number if IRQs to appear in the same jiffie with the
- * same instruction pointer (or within 2 instructions).
- */
-static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
-{
- unsigned long instr_ptr = instruction_pointer(regs);
-
- if (desc->lck_jif == jiffies &&
- desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
- desc->lck_cnt += 1;
-
- if (desc->lck_cnt > MAX_IRQ_CNT) {
- printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
- return 1;
- }
- } else {
- desc->lck_cnt = 0;
- desc->lck_pc = instruction_pointer(regs);
- desc->lck_jif = jiffies;
- }
- return 0;
-}
-
-static void
-report_bad_irq(unsigned int irq, struct pt_regs *regs, struct irqdesc *desc, int ret)
-{
- static int count = 100;
- struct irqaction *action;
-
- if (noirqdebug)
- return;

- if (ret != IRQ_HANDLED && ret != IRQ_NONE) {
- if (!count)
- return;
- count--;
- printk("irq%u: bogus retval mask %x\n", irq, ret);
- } else {
- desc->irqs_unhandled++;
- if (desc->irqs_unhandled <= 99900)
- return;
- desc->irqs_unhandled = 0;
- printk("irq%u: nobody cared\n", irq);
- }
- show_regs(regs);
- dump_stack();
- printk(KERN_ERR "handlers:");
- action = desc->action;
- do {
- printk("\n" KERN_ERR "[<%p>]", action->handler);
- print_symbol(" (%s)", (unsigned long)action->handler);
- action = action->next;
- } while (action);
- printk("\n");
-}

-static int
-__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
-{
- unsigned int status;
- int ret, retval = 0;
-
- spin_unlock(&irq_controller_lock);
-
-#ifdef CONFIG_NO_IDLE_HZ
- if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
- write_seqlock(&xtime_lock);
- if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
- system_timer->dyn_tick->handler(irq, 0, regs);
- write_sequnlock(&xtime_lock);
- }
-#endif
-
- if (!(action->flags & SA_INTERRUPT))
- local_irq_enable();
-
- status = 0;
- do {
- ret = action->handler(irq, action->dev_id, regs);
- if (ret == IRQ_HANDLED)
- status |= action->flags;
- retval |= ret;
- action = action->next;
- } while (action);
-
- if (status & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
-
- spin_lock_irq(&irq_controller_lock);
-
- return retval;
-}
-
-/*
- * This is for software-decoded IRQs. The caller is expected to
- * handle the ack, clear, mask and unmask issues.
- */
-void
-do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- struct irqaction *action;
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- kstat_cpu(cpu).irqs[irq]++;
-
- smp_set_running(desc);
-
- action = desc->action;
- if (action) {
- int ret = __do_irq(irq, action, regs);
- if (ret != IRQ_HANDLED)
- report_bad_irq(irq, regs, desc, ret);
- }
-
- smp_clear_running(desc);
-}
-
-/*
- * Most edge-triggered IRQ implementations seem to take a broken
- * approach to this. Hence the complexity.
- */
-void
-do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- /*
- * If we're currently running this IRQ, or its disabled,
- * we shouldn't process the IRQ. Instead, turn on the
- * hardware masks.
- */
- if (unlikely(desc->running || desc->disable_depth))
- goto running;
-
- /*
- * Acknowledge and clear the IRQ, but don't mask it.
- */
- desc->chip->ack(irq);
-
- /*
- * Mark the IRQ currently in progress.
- */
- desc->running = 1;
-
- kstat_cpu(cpu).irqs[irq]++;
-
- do {
- struct irqaction *action;
-
- action = desc->action;
- if (!action)
- break;
-
- if (desc->pending && !desc->disable_depth) {
- desc->pending = 0;
- desc->chip->unmask(irq);
- }
-
- __do_irq(irq, action, regs);
- } while (desc->pending && !desc->disable_depth);
-
- desc->running = 0;
-
- /*
- * If we were disabled or freed, shut down the handler.
- */
- if (likely(desc->action && !check_irq_lock(desc, irq, regs)))
- return;
-
- running:
- /*
- * We got another IRQ while this one was masked or
- * currently running. Delay it.
- */
- desc->pending = 1;
- desc->chip->mask(irq);
- desc->chip->ack(irq);
-}
-
-/*
- * Level-based IRQ handler. Nice and simple.
- */
-void
-do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- struct irqaction *action;
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- /*
- * Acknowledge, clear _AND_ disable the interrupt.
- */
- desc->chip->ack(irq);
-
- if (likely(!desc->disable_depth)) {
- kstat_cpu(cpu).irqs[irq]++;
-
- smp_set_running(desc);
-
- /*
- * Return with this interrupt masked if no action
- */
- action = desc->action;
- if (action) {
- int ret = __do_irq(irq, desc->action, regs);
-
- if (ret != IRQ_HANDLED)
- report_bad_irq(irq, regs, desc, ret);
-
- if (likely(!desc->disable_depth &&
- !check_irq_lock(desc, irq, regs)))
- desc->chip->unmask(irq);
- }
-
- smp_clear_running(desc);
- }
-}
-
-static void do_pending_irqs(struct pt_regs *regs)
-{
- struct list_head head, *l, *n;
-
- do {
- struct irqdesc *desc;
-
- /*
- * First, take the pending interrupts off the list.
- * The act of calling the handlers may add some IRQs
- * back onto the list.
- */
- head = irq_pending;
- INIT_LIST_HEAD(&irq_pending);
- head.next->prev = &head;
- head.prev->next = &head;
-
- /*
- * Now run each entry. We must delete it from our
- * list before calling the handler.
- */
- list_for_each_safe(l, n, &head) {
- desc = list_entry(l, struct irqdesc, pend);
- list_del_init(&desc->pend);
- desc_handle_irq(desc - irq_desc, desc, regs);
- }
-
- /*
- * The list must be empty.
- */
- BUG_ON(!list_empty(&head));
- } while (!list_empty(&irq_pending));
-}
+/* Handle bad interrupts */
+static struct irq_desc bad_irq = {
+ .handler = &no_irq_type,
+ .lock = SPIN_LOCK_UNLOCKED
+};

/*
- * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+ * asm_do_IRQ handles all hardware IRQ's. Decoded IRQs should not
* come via this function. Instead, they should provide their
* own 'handler'
*/
@@ -547,98 +114,56 @@ asmlinkage void asm_do_IRQ(unsigned int
* than crashing, do something sensible.
*/
if (irq >= NR_IRQS)
- desc = &bad_irq_desc;
+ desc = &bad_irq;

irq_enter();
- spin_lock(&irq_controller_lock);
- desc_handle_irq(irq, desc, regs);
-
- /*
- * Now re-run any pending interrupts.
- */
- if (!list_empty(&irq_pending))
- do_pending_irqs(regs);

- irq_finish(irq);
+ desc_handle_irq(irq, desc, regs);

- spin_unlock(&irq_controller_lock);
irq_exit();
}

-void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained)
-{
- struct irqdesc *desc;
- unsigned long flags;
-
- if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
- return;
- }
-
- if (handle == NULL)
- handle = do_bad_IRQ;
-
- desc = irq_desc + irq;
-
- if (is_chained && desc->chip == &bad_chip)
- printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (handle == do_bad_IRQ) {
- desc->chip->mask(irq);
- desc->chip->ack(irq);
- desc->disable_depth = 1;
- }
- desc->handle = handle;
- if (handle != do_bad_IRQ && is_chained) {
- desc->valid = 0;
- desc->probe_ok = 0;
- desc->disable_depth = 0;
- desc->chip->unmask(irq);
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-
-void set_irq_chip(unsigned int irq, struct irqchip *chip)
+void __set_irq_handler(unsigned int irq, struct irq_type *type, int is_chained)
{
struct irqdesc *desc;
unsigned long flags;

if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ printk(KERN_ERR
+ "Trying to install type control for IRQ%d\n", irq);
return;
}

- if (chip == NULL)
- chip = &bad_chip;
-
desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->chip = chip;
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}

-int set_irq_type(unsigned int irq, unsigned int type)
-{
- struct irqdesc *desc;
- unsigned long flags;
- int ret = -ENXIO;
-
- if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
- return -ENODEV;
- }
-
- desc = irq_desc + irq;
- if (desc->chip->set_type) {
- spin_lock_irqsave(&irq_controller_lock, flags);
- ret = desc->chip->set_type(irq, type);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
+ /* Uninstall ? */
+ if (type == NULL || type == &no_irq_type) {
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->chip) {
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+ }
+ desc->depth = 1;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
+
+ /* Install the irq_type */
+ if (generic_set_irq_type(irq, type))
+ return;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ if (is_chained && (desc->handler == &no_irq_type || !desc->chip))
+ printk(KERN_WARNING "Trying to install "
+ "chained interrupt type for IRQ%d\n", irq);
+
+ if (type != NULL && is_chained) {
+ desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ desc->depth = 0;
+ if (desc->chip)
+ desc->chip->unmask(irq);
}
-
- return ret;
+ spin_unlock_irqrestore(&desc->lock, flags);
}
-EXPORT_SYMBOL(set_irq_type);

void set_irq_flags(unsigned int irq, unsigned int iflags)
{
@@ -651,421 +176,30 @@ void set_irq_flags(unsigned int irq, uns
}

desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->valid = (iflags & IRQF_VALID) != 0;
- desc->probe_ok = (iflags & IRQF_PROBE) != 0;
- desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-
-int setup_irq(unsigned int irq, struct irqaction *new)
-{
- int shared = 0;
- struct irqaction *old, **p;
- unsigned long flags;
- struct irqdesc *desc;
-
- /*
- * Some drivers like serial.c use request_irq() heavily,
- * so we have to be careful not to interfere with a
- * running system.
- */
- if (new->flags & SA_SAMPLE_RANDOM) {
- /*
- * This function might sleep, we want to call it first,
- * outside of the atomic block.
- * Yes, this might clear the entropy pool if the wrong
- * driver is attempted to be loaded, without actually
- * installing a new handler, but is this really a problem,
- * only the sysadmin is able to do this.
- */
- rand_initialize_irq(irq);
- }
-
- /*
- * The following block of code has to be executed atomically
- */
- desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- p = &desc->action;
- if ((old = *p) != NULL) {
- /*
- * Can't share interrupts unless both agree to and are
- * the same type.
- */
- if (!(old->flags & new->flags & SA_SHIRQ) ||
- (~old->flags & new->flags) & SA_TRIGGER_MASK) {
- spin_unlock_irqrestore(&irq_controller_lock, flags);
- return -EBUSY;
- }
-
- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
- shared = 1;
- }
-
- *p = new;
-
- if (!shared) {
- desc->probing = 0;
- desc->running = 0;
- desc->pending = 0;
- desc->disable_depth = 1;
-
- if (new->flags & SA_TRIGGER_MASK &&
- desc->chip->set_type) {
- unsigned int type = new->flags & SA_TRIGGER_MASK;
- desc->chip->set_type(irq, type);
- }
-
- if (!desc->noautoenable) {
- desc->disable_depth = 0;
- desc->chip->unmask(irq);
- }
- }
-
- spin_unlock_irqrestore(&irq_controller_lock, flags);
- return 0;
-}
-
-/**
- * request_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs
- * @irqflags: Interrupt type flags
- * @devname: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. From the point this
- * call is made your handler function may be invoked. Since
- * your handler function must clear any interrupt the board
- * raises, you must take care both to initialise your hardware
- * and to set up the interrupt handler in the right order.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
- *
- * If your interrupt is shared you must pass a non NULL dev_id
- * as this is required when freeing the interrupt.
- *
- * Flags:
- *
- * SA_SHIRQ Interrupt is shared
- *
- * SA_INTERRUPT Disable local interrupts while processing
- *
- * SA_SAMPLE_RANDOM The interrupt can be used for entropy
- *
- */
-int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irq_flags, const char * devname, void *dev_id)
-{
- unsigned long retval;
- struct irqaction *action;
-
- if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
- (irq_flags & SA_SHIRQ && !dev_id))
- return -EINVAL;
-
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
- return -ENOMEM;
-
- action->handler = handler;
- action->flags = irq_flags;
- cpus_clear(action->mask);
- action->name = devname;
- action->next = NULL;
- action->dev_id = dev_id;
-
- retval = setup_irq(irq, action);
-
- if (retval)
- kfree(action);
- return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-/**
- * free_irq - free an interrupt
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
- *
- * Remove an interrupt handler. The handler is removed and if the
- * interrupt line is no longer in use by any driver it is disabled.
- * On a shared IRQ the caller must ensure the interrupt is disabled
- * on the card it drives before calling this function.
- *
- * This function must not be called from interrupt context.
- */
-void free_irq(unsigned int irq, void *dev_id)
-{
- struct irqaction * action, **p;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !irq_desc[irq].valid) {
- printk(KERN_ERR "Trying to free IRQ%d\n",irq);
- dump_stack();
- return;
- }
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
- if (action->dev_id != dev_id)
- continue;
-
- /* Found it - now free it */
- *p = action->next;
- break;
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-
- if (!action) {
- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
- dump_stack();
- } else {
- synchronize_irq(irq);
- kfree(action);
- }
-}
-
-EXPORT_SYMBOL(free_irq);
-
-static DECLARE_MUTEX(probe_sem);
-
-/* Start the interrupt probing. Unlike other architectures,
- * we don't return a mask of interrupts from probe_irq_on,
- * but return the number of interrupts enabled for the probe.
- * The interrupts which have been enabled for probing is
- * instead recorded in the irq_desc structure.
- */
-unsigned long probe_irq_on(void)
-{
- unsigned int i, irqs = 0;
- unsigned long delay;
-
- down(&probe_sem);
-
- /*
- * first snaffle up any unassigned but
- * probe-able interrupts
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (!irq_desc[i].probe_ok || irq_desc[i].action)
- continue;
-
- irq_desc[i].probing = 1;
- irq_desc[i].triggered = 0;
- if (irq_desc[i].chip->set_type)
- irq_desc[i].chip->set_type(i, IRQT_PROBE);
- irq_desc[i].chip->unmask(i);
- irqs += 1;
- }
- spin_unlock_irq(&irq_controller_lock);
-
- /*
- * wait for spurious interrupts to mask themselves out again
- */
- for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
- /* min 100ms delay */;
-
- /*
- * now filter out any obviously spurious interrupts
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (irq_desc[i].probing && irq_desc[i].triggered) {
- irq_desc[i].probing = 0;
- irqs -= 1;
- }
- }
- spin_unlock_irq(&irq_controller_lock);
-
- return irqs;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-unsigned int probe_irq_mask(unsigned long irqs)
-{
- unsigned int mask = 0, i;
-
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < 16 && i < NR_IRQS; i++)
- if (irq_desc[i].probing && irq_desc[i].triggered)
- mask |= 1 << i;
- spin_unlock_irq(&irq_controller_lock);
-
- up(&probe_sem);
-
- return mask;
-}
-EXPORT_SYMBOL(probe_irq_mask);
-
-/*
- * Possible return values:
- * >= 0 - interrupt number
- * -1 - no interrupt/many interrupts
- */
-int probe_irq_off(unsigned long irqs)
-{
- unsigned int i;
- int irq_found = NO_IRQ;
-
- /*
- * look at the interrupts, and find exactly one
- * that we were probing has been triggered
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (irq_desc[i].probing &&
- irq_desc[i].triggered) {
- if (irq_found != NO_IRQ) {
- irq_found = NO_IRQ;
- goto out;
- }
- irq_found = i;
- }
- }
-
- if (irq_found == -1)
- irq_found = NO_IRQ;
-out:
- spin_unlock_irq(&irq_controller_lock);
-
- up(&probe_sem);
-
- return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-#ifdef CONFIG_SMP
-static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
-{
- pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu);
-
- spin_lock_irq(&irq_controller_lock);
- desc->cpu = cpu;
- desc->chip->set_cpu(desc, irq, cpu);
- spin_unlock_irq(&irq_controller_lock);
-}
-
-#ifdef CONFIG_PROC_FS
-static int
-irq_affinity_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- struct irqdesc *desc = irq_desc + ((int)data);
- int len = cpumask_scnprintf(page, count, desc->affinity);
-
- if (count - len < 2)
- return -EINVAL;
- page[len++] = '\n';
- page[len] = '\0';
-
- return len;
-}
-
-static int
-irq_affinity_write_proc(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- unsigned int irq = (unsigned int)data;
- struct irqdesc *desc = irq_desc + irq;
- cpumask_t affinity, tmp;
- int ret = -EIO;
-
- if (!desc->chip->set_cpu)
- goto out;
-
- ret = cpumask_parse(buffer, count, affinity);
- if (ret)
- goto out;
-
- cpus_and(tmp, affinity, cpu_online_map);
- if (cpus_empty(tmp)) {
- ret = -EINVAL;
- goto out;
- }
-
- desc->affinity = affinity;
- route_irq(desc, irq, first_cpu(tmp));
- ret = count;
-
- out:
- return ret;
-}
-#endif
-#endif
-
-void __init init_irq_proc(void)
-{
-#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS)
- struct proc_dir_entry *dir;
- int irq;
-
- dir = proc_mkdir("irq", NULL);
- if (!dir)
- return;
-
- for (irq = 0; irq < NR_IRQS; irq++) {
- struct proc_dir_entry *entry;
- struct irqdesc *desc;
- char name[16];
-
- desc = irq_desc + irq;
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name) - 1, "%u", irq);
-
- desc->procdir = proc_mkdir(name, dir);
- if (!desc->procdir)
- continue;
-
- entry = create_proc_entry("smp_affinity", 0600, desc->procdir);
- if (entry) {
- entry->nlink = 1;
- entry->data = (void *)irq;
- entry->read_proc = irq_affinity_read_proc;
- entry->write_proc = irq_affinity_write_proc;
- }
- }
-#endif
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ if (iflags & IRQF_VALID)
+ desc->status &= ~IRQ_NOREQUEST;
+ if (iflags & IRQF_PROBE)
+ desc->status &= ~IRQ_NOPROBE;
+ spin_unlock_irqrestore(&desc->lock, flags);
}

void __init init_IRQ(void)
{
- struct irqdesc *desc;
+ extern void init_dma(void);
int irq;

+ for (irq = 0; irq < NR_IRQS; irq++)
+ irq_desc[irq].status |= IRQ_NOREQUEST;
+
#ifdef CONFIG_SMP
bad_irq_desc.affinity = CPU_MASK_ALL;
bad_irq_desc.cpu = smp_processor_id();
#endif
-
- for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
- *desc = bad_irq_desc;
- INIT_LIST_HEAD(&desc->pend);
- }
-
init_arch_irq();
}

-static int __init noirqdebug_setup(char *str)
-{
- noirqdebug = 1;
- return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
-
#ifdef CONFIG_HOTPLUG_CPU
/*
* The CPU has been marked offline. Migrate IRQs off this CPU. If
Index: linux-2.6.16-git/include/asm-arm/dyntick.h
===================================================================
--- /dev/null
+++ linux-2.6.16-git/include/asm-arm/dyntick.h
@@ -0,0 +1,6 @@
+#ifndef _ASMARM_DYNTICK_H
+#define _ASMARM_DYNTICK_H
+
+#include <asm/mach/time.h>
+
+#endif /* _ASMARM_DYNTICK_H */
Index: linux-2.6.16-git/include/asm-arm/hw_irq.h
===================================================================
--- /dev/null
+++ linux-2.6.16-git/include/asm-arm/hw_irq.h
@@ -0,0 +1,9 @@
+/*
+ * Nothing to see here yet
+ */
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+#include <asm/mach/irq.h>
+
+#endif
Index: linux-2.6.16-git/include/asm-arm/irq.h
===================================================================
--- linux-2.6.16-git.orig/include/asm-arm/irq.h
+++ linux-2.6.16-git/include/asm-arm/irq.h
@@ -21,18 +21,13 @@

struct irqaction;

-extern void disable_irq_nosync(unsigned int);
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
/*
- * These correspond with the SA_TRIGGER_* defines, and therefore the
- * IORESOURCE_IRQ_* defines.
+ * Migration helpers
*/
-#define __IRQT_RISEDGE (1 << 0)
-#define __IRQT_FALEDGE (1 << 1)
-#define __IRQT_HIGHLVL (1 << 2)
-#define __IRQT_LOWLVL (1 << 3)
+#define __IRQT_FALEDGE IRQ_TYPE_EDGEL
+#define __IRQT_RISEDGE IRQ_TYPE_EDGEH
+#define __IRQT_LOWLVL IRQ_TYPE_LEVELL
+#define __IRQT_HIGHLVL IRQ_TYPE_LEVELH

#define IRQT_NOEDGE (0)
#define IRQT_RISING (__IRQT_RISEDGE)
@@ -40,17 +35,8 @@ extern void enable_irq(unsigned int);
#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
#define IRQT_LOW (__IRQT_LOWLVL)
#define IRQT_HIGH (__IRQT_HIGHLVL)
-#define IRQT_PROBE (1 << 4)
-
-int set_irq_type(unsigned int irq, unsigned int type);
-void disable_irq_wake(unsigned int irq);
-void enable_irq_wake(unsigned int irq);
-int setup_irq(unsigned int, struct irqaction *);

-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
+#define IRQT_PROBE (1 << 7)

extern void migrate_irqs(void);
#endif
-
Index: linux-2.6.16-git/include/asm-arm/mach/irq.h
===================================================================
--- linux-2.6.16-git.orig/include/asm-arm/mach/irq.h
+++ linux-2.6.16-git/include/asm-arm/mach/irq.h
@@ -10,95 +10,9 @@
#ifndef __ASM_ARM_MACH_IRQ_H
#define __ASM_ARM_MACH_IRQ_H

-struct irqdesc;
-struct pt_regs;
-struct seq_file;
-
-typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
-typedef void (*irq_control_t)(unsigned int);
-
-struct irqchip {
- /*
- * Acknowledge the IRQ.
- * If this is a level-based IRQ, then it is expected to mask the IRQ
- * as well.
- */
- void (*ack)(unsigned int);
- /*
- * Mask the IRQ in hardware.
- */
- void (*mask)(unsigned int);
- /*
- * Unmask the IRQ in hardware.
- */
- void (*unmask)(unsigned int);
- /*
- * Ask the hardware to re-trigger the IRQ.
- * Note: This method _must_ _not_ call the interrupt handler.
- * If you are unable to retrigger the interrupt, do not
- * provide a function, or if you do, return non-zero.
- */
- int (*retrigger)(unsigned int);
- /*
- * Set the type of the IRQ.
- */
- int (*set_type)(unsigned int, unsigned int);
- /*
- * Set wakeup-enable on the selected IRQ
- */
- int (*set_wake)(unsigned int, unsigned int);
-
-#ifdef CONFIG_SMP
- /*
- * Route an interrupt to a CPU
- */
- void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu);
-#endif
-};
-
-struct irqdesc {
- irq_handler_t handle;
- struct irqchip *chip;
- struct irqaction *action;
- struct list_head pend;
- void __iomem *base;
- void *data;
- unsigned int disable_depth;
-
- unsigned int triggered: 1; /* IRQ has occurred */
- unsigned int running : 1; /* IRQ is running */
- unsigned int pending : 1; /* IRQ is pending */
- unsigned int probing : 1; /* IRQ in use for a probe */
- unsigned int probe_ok : 1; /* IRQ can be used for probe */
- unsigned int valid : 1; /* IRQ claimable */
- unsigned int noautoenable : 1; /* don't automatically enable IRQ */
- unsigned int unused :25;
-
- unsigned int irqs_unhandled;
- struct proc_dir_entry *procdir;
-
-#ifdef CONFIG_SMP
- cpumask_t affinity;
- unsigned int cpu;
-#endif
+#include <linux/irq.h>

- /*
- * IRQ lock detection
- */
- unsigned int lck_cnt;
- unsigned int lck_pc;
- unsigned int lck_jif;
-};
-
-extern struct irqdesc irq_desc[];
-
-/*
- * Helpful inline function for calling irq descriptor handlers.
- */
-static inline void desc_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- desc->handle(irq, desc, regs);
-}
+struct seq_file;

/*
* This is internal. Do not use it.
@@ -106,18 +20,15 @@ static inline void desc_handle_irq(unsig
extern void (*init_arch_irq)(void);
extern void init_FIQ(void);
extern int show_fiq_list(struct seq_file *, void *);
-void __set_irq_handler(unsigned int irq, irq_handler_t, int);
+void __set_irq_handler(unsigned int irq, struct irq_type *, int);

/*
- * External stuff.
+ * Function wrappers
*/
-#define set_irq_handler(irq,handler) __set_irq_handler(irq,handler,0)
-#define set_irq_chained_handler(irq,handler) __set_irq_handler(irq,handler,1)
-#define set_irq_data(irq,d) do { irq_desc[irq].data = d; } while (0)
-#define set_irq_chipdata(irq,d) do { irq_desc[irq].base = d; } while (0)
-#define get_irq_chipdata(irq) (irq_desc[irq].base)
+#define set_irq_handler(irq,handler) __set_irq_handler(irq,handler,0)
+#define set_irq_chipdata(irq,d) set_irq_chip_data(irq, d)
+#define get_irq_chipdata(irq) get_irq_chip_data(irq)

-void set_irq_chip(unsigned int irq, struct irqchip *);
void set_irq_flags(unsigned int irq, unsigned int flags);

#define IRQF_VALID (1 << 0)
@@ -125,12 +36,41 @@ void set_irq_flags(unsigned int irq, uns
#define IRQF_NOAUTOEN (1 << 2)

/*
- * Built-in IRQ handlers.
+ * ARM uses the retrigger functions in desc->chip or software retrigger
+ */
+static inline void hw_resend_irq(struct irq_type *t, unsigned int i) { }
+
+/*
+ * This is for easy migration, but should be changed in the source
+ */
+#define do_level_IRQ (&default_level_type)
+#define do_edge_IRQ (&default_edge_type)
+#define do_simple_IRQ (&default_simple_type)
+
+/*
+ * Workaround to get set_irq_chained_handler(nr, NULL) solved
*/
-void do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void dummy_mask_unmask_irq(unsigned int irq);
+#define irq_NULL_type no_irq_type
+#define set_irq_chained_handler(irq,handler) \
+ __set_irq_handler(irq,&irq_##handler##_type,1)
+
+#define DEFINE_IRQ_CHAINED_TYPE(function) \
+struct irq_type irq_##function##_type = { \
+ .typename = #function"-chained_type", \
+ .handle_irq = function, \
+}
+
+#define do_bad_IRQ(irq,desc,regs) \
+do { \
+ spin_lock(&desc->lock); \
+ handle_bad_irq(irq, desc, regs); \
+ spin_unlock(&desc->lock); \
+} while(0)
+
+extern unsigned long irq_err_count;
+static inline void ack_bad_irq(int irq)
+{
+ irq_err_count++;
+}

#endif

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:51 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-omap1/board-osk.c | 2 +-
arch/arm/mach-omap1/fpga.c | 2 ++
arch/arm/mach-omap1/serial.c | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/arch/arm/mach-omap1/board-osk.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-omap1/board-osk.c
+++ linux-2.6.16-git/arch/arm/mach-omap1/board-osk.c
@@ -29,7 +29,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
Index: linux-2.6.16-git/arch/arm/mach-omap1/fpga.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-omap1/fpga.c
+++ linux-2.6.16-git/arch/arm/mach-omap1/fpga.c
@@ -120,6 +120,8 @@ static struct irqchip omap_fpga_irq = {
.unmask = fpga_unmask_irq,
};

+static DEFINE_IRQ_CHAINED_TYPE(innovator_fpga_IRQ_demux);
+
/*
* All of the FPGA interrupt request inputs except for the touchscreen are
* edge-sensitive; the touchscreen is level-sensitive. The edge-sensitive
Index: linux-2.6.16-git/arch/arm/mach-omap1/serial.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-omap1/serial.c
+++ linux-2.6.16-git/arch/arm/mach-omap1/serial.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/serial.h>
#include <linux/tty.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:07 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/input/touchscreen/corgi_ts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.16-git/drivers/input/touchscreen/corgi_ts.c
===================================================================
--- linux-2.6.16-git.orig/drivers/input/touchscreen/corgi_ts.c
+++ linux-2.6.16-git/drivers/input/touchscreen/corgi_ts.c
@@ -15,9 +15,9 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <asm/irq.h>

#include <asm/arch/sharpsl.h>
#include <asm/arch/hardware.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:04 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/i2c/chips/tps65010.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.16-git/drivers/i2c/chips/tps65010.c
===================================================================
--- linux-2.6.16-git.orig/drivers/i2c/chips/tps65010.c
+++ linux-2.6.16-git/drivers/i2c/chips/tps65010.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/delay.h>
@@ -34,7 +35,6 @@
#include <linux/seq_file.h>
#include <linux/mutex.h>

-#include <asm/irq.h>
#include <asm/mach-types.h>

#include <asm/arch/gpio.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:58 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-versatile/core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/arch/arm/mach-versatile/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-versatile/core.c
+++ linux-2.6.16-git/arch/arm/mach-versatile/core.c
@@ -96,6 +96,8 @@ sic_handle_irq(unsigned int irq, struct
} while (status);
}

+static DEFINE_IRQ_CHAINED_TYPE(sic_handle_irq);
+
#if 1
#define IRQ_MMCI0A IRQ_VICSOURCE22
#define IRQ_AACI IRQ_VICSOURCE24
@@ -114,7 +116,7 @@ void __init versatile_init_irq(void)

vic_init(VA_VIC_BASE, IRQ_VIC_START, ~(1 << 31));

- set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
+ set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
enable_irq(IRQ_VICSOURCE31);

/* Do second interrupt controller */

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Catalin Marinas
2006-04-10 09:40:02 UTC
Permalink
Post by Thomas Gleixner
Fixup the conversion to generic irq subsystem.
[...]
Post by Thomas Gleixner
Index: linux-2.6.16-git/arch/arm/mach-versatile/core.c
[...]
Post by Thomas Gleixner
@@ -114,7 +116,7 @@ void __init versatile_init_irq(void)
vic_init(VA_VIC_BASE, IRQ_VIC_START, ~(1 << 31));
- set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
+ set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
enable_irq(IRQ_VICSOURCE31);
I'm not sure but is enable_irq() still needed if you use
set_irq_chained_handler()? The latter seems to unmask the IRQ anyway.
--
Catalin


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-10 14:03:57 UTC
Permalink
Catalin,
Post by Catalin Marinas
Post by Thomas Gleixner
vic_init(VA_VIC_BASE, IRQ_VIC_START, ~(1 << 31));
- set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
+ set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
enable_irq(IRQ_VICSOURCE31);
I'm not sure but is enable_irq() still needed if you use
set_irq_chained_handler()? The latter seems to unmask the IRQ anyway.
It's even not needed with the current mainline ARM code. Chained
handlers are enabled inside __set_irq_handler() too.

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-10 10:04:05 UTC
Permalink
Catalin,
Please merge this patch into "[PATCH 22/32] ARM: Convert versatile to
generic irq handling".
Applied, thanks.

Can I take that as an confirmation, that the patch works on
mach-versatile ?

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Catalin Marinas
2006-05-10 10:08:22 UTC
Permalink
Post by Thomas Gleixner
Please merge this patch into "[PATCH 22/32] ARM: Convert versatile to
generic irq handling".
Applied, thanks.
Can I take that as an confirmation, that the patch works on
mach-versatile ?
Yes, it seems to work fine.
--
Catalin

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Catalin Marinas
2006-05-10 09:53:09 UTC
Permalink
From: Catalin Marinas <***@arm.com>

Since set_irq_chained_handler() in versatile_init_irq
(arch/arm/mach-versatile/core.c) enables the IRQ anyway, the
subsequent call to enable_irq() is no longer needed. Having it causes
a warning in kernel/irq/manage.c:124.

Please merge this patch into "[PATCH 22/32] ARM: Convert versatile to
generic irq handling".

Signed-off-by: Catalin Marinas <***@arm.com>
---

arch/arm/mach-versatile/core.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 084b8dd..d914e3a 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -117,7 +117,6 @@ void __init versatile_init_irq(void)
vic_init(VA_VIC_BASE, IRQ_VIC_START, ~(1 << 31));

set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
- enable_irq(IRQ_VICSOURCE31);

/* Do second interrupt controller */
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:08 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/net/smc91x.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/drivers/net/smc91x.c
===================================================================
--- linux-2.6.16-git.orig/drivers/net/smc91x.c
+++ linux-2.6.16-git/drivers/net/smc91x.c
@@ -74,6 +74,7 @@ static const char version[] =
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/crc32.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:01 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-ep93xx/core.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-ep93xx/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ep93xx/core.c
+++ linux-2.6.16-git/arch/arm/mach-ep93xx/core.c
@@ -342,6 +342,7 @@ static struct irqchip ep93xx_gpio_ab_irq
.set_type = ep93xx_gpio_ab_irq_type,
};

+static DEFINE_IRQ_CHAINED_TYPE(ep93xx_gpio_ab_irq_handler);

void __init ep93xx_init_irq(void)
{

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:00 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-at91rm9200/gpio.c | 10 ++++++----
arch/arm/mach-at91rm9200/time.c | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-at91rm9200/gpio.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-at91rm9200/gpio.c
+++ linux-2.6.16-git/arch/arm/mach-at91rm9200/gpio.c
@@ -261,7 +261,7 @@ static void gpio_irq_handler(unsigned ir
void __iomem *pio;
u32 isr;

- pio = desc->base;
+ pio = get_irq_chip_data(irq);

/* temporarily mask (level sensitive) parent IRQ */
desc->chip->ack(irq);
@@ -270,12 +270,12 @@ static void gpio_irq_handler(unsigned ir
if (!isr)
break;

- pin = (unsigned) desc->data;
+ pin = (unsigned) get_irq_data(irq);
gpio = &irq_desc[pin];

while (isr) {
if (isr & 1) {
- if (unlikely(gpio->disable_depth)) {
+ if (unlikely(gpio->depth)) {
/*
* The core ARM interrupt handler lazily disables IRQs so
* another IRQ must be generated before it actually gets
@@ -284,7 +284,7 @@ static void gpio_irq_handler(unsigned ir
gpio_irq_mask(pin);
}
else
- gpio->handle(pin, gpio, regs);
+ desc_handle_irq(pin, gpio, regs);
}
pin++;
gpio++;
@@ -295,6 +295,8 @@ static void gpio_irq_handler(unsigned ir
/* now it may re-trigger */
}

+static DEFINE_IRQ_CHAINED_TYPE(gpio_irq_handler);
+
/* call this from board-specific init_irq */
void __init at91_gpio_irq_setup(unsigned banks)
{
Index: linux-2.6.16-git/arch/arm/mach-at91rm9200/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-at91rm9200/time.c
+++ linux-2.6.16-git/arch/arm/mach-at91rm9200/time.c
@@ -22,13 +22,13 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>

#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/mach/time.h>

/*

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:02 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-ixp23xx/core.c | 4 +++-
arch/arm/mach-ixp23xx/ixdp2351.c | 13 ++++++++-----
2 files changed, 11 insertions(+), 6 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-ixp23xx/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp23xx/core.c
+++ linux-2.6.16-git/arch/arm/mach-ixp23xx/core.c
@@ -260,11 +260,13 @@ static void pci_handler(unsigned int irq
}

int_desc = irq_desc + irqno;
- int_desc->handle(irqno, int_desc, regs);
+ desc_handle_irq(irqno, int_desc, regs);

desc->chip->unmask(irq);
}

+static DEFINE_IRQ_CHAINED_TYPE(pci_handler);
+
static struct irqchip ixp23xx_pci_irq_chip = {
.ack = ixp23xx_pci_irq_mask,
.mask = ixp23xx_pci_irq_mask,
Index: linux-2.6.16-git/arch/arm/mach-ixp23xx/ixdp2351.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp23xx/ixdp2351.c
+++ linux-2.6.16-git/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
@@ -37,7 +38,6 @@
#include <asm/memory.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
-#include <asm/irq.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
@@ -75,7 +75,7 @@ static void ixdp2351_inta_handler(unsign
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
cpld_desc = irq_desc + cpld_irq;
- cpld_desc->handle(cpld_irq, cpld_desc, regs);
+ desc_handle_irq(cpld_irq, cpld_desc, regs);
}
}

@@ -112,7 +112,7 @@ static void ixdp2351_intb_handler(unsign
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
cpld_desc = irq_desc + cpld_irq;
- cpld_desc->handle(cpld_irq, cpld_desc, regs);
+ desc_handle_irq(cpld_irq, cpld_desc, regs);
}
}

@@ -125,6 +125,9 @@ static struct irqchip ixdp2351_intb_chip
.unmask = ixdp2351_intb_unmask
};

+static DEFINE_IRQ_CHAINED_TYPE(ixdp2351_inta_handler);
+static DEFINE_IRQ_CHAINED_TYPE(ixdp2351_intb_handler);
+
void ixdp2351_init_irq(void)
{
int irq;
@@ -159,8 +162,8 @@ void ixdp2351_init_irq(void)
}
}

- set_irq_chained_handler(IRQ_IXP23XX_INTA, &ixdp2351_inta_handler);
- set_irq_chained_handler(IRQ_IXP23XX_INTB, &ixdp2351_intb_handler);
+ set_irq_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler);
+ set_irq_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler);
}

/*

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:52 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-pxa/idp.c | 1 +
arch/arm/mach-pxa/irq.c | 1 +
arch/arm/mach-pxa/lubbock.c | 2 ++
arch/arm/mach-pxa/mainstone.c | 2 ++
arch/arm/mach-pxa/sharpsl_pm.c | 2 +-
5 files changed, 7 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/arch/arm/mach-pxa/idp.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-pxa/idp.c
+++ linux-2.6.16-git/arch/arm/mach-pxa/idp.c
@@ -18,6 +18,7 @@

#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/fb.h>

Index: linux-2.6.16-git/arch/arm/mach-pxa/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-pxa/irq.c
+++ linux-2.6.16-git/arch/arm/mach-pxa/irq.c
@@ -244,6 +244,7 @@ static struct irqchip pxa_muxed_gpio_chi
.set_type = pxa_gpio_irq_type,
};

+static DEFINE_IRQ_CHAINED_TYPE(pxa_gpio_demux_handler);

void __init pxa_init_irq(void)
{
Index: linux-2.6.16-git/arch/arm/mach-pxa/lubbock.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-pxa/lubbock.c
+++ linux-2.6.16-git/arch/arm/mach-pxa/lubbock.c
@@ -95,6 +95,8 @@ static void lubbock_irq_handler(unsigned
} while (pending);
}

+static DEFINE_IRQ_CHAINED_TYPE(lubbock_irq_handler);
+
static void __init lubbock_init_irq(void)
{
int irq;
Index: linux-2.6.16-git/arch/arm/mach-pxa/mainstone.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-pxa/mainstone.c
+++ linux-2.6.16-git/arch/arm/mach-pxa/mainstone.c
@@ -85,6 +85,8 @@ static void mainstone_irq_handler(unsign
} while (pending);
}

+static DEFINE_IRQ_CHAINED_TYPE(mainstone_irq_handler);
+
static void __init mainstone_init_irq(void)
{
int irq;
Index: linux-2.6.16-git/arch/arm/mach-pxa/sharpsl_pm.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-pxa/sharpsl_pm.c
+++ linux-2.6.16-git/arch/arm/mach-pxa/sharpsl_pm.c
@@ -18,11 +18,11 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/platform_device.h>

#include <asm/hardware.h>
#include <asm/mach-types.h>
-#include <asm/irq.h>
#include <asm/apm.h>
#include <asm/arch/pm.h>
#include <asm/arch/pxa-regs.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:57 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-shark/core.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-shark/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-shark/core.c
+++ linux-2.6.16-git/arch/arm/mach-shark/core.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/serial_8250.h>


--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:55 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-sa1100/cerf.c | 1 +
arch/arm/mach-sa1100/h3600.c | 4 +++-
arch/arm/mach-sa1100/irq.c | 5 ++++-
arch/arm/mach-sa1100/neponset.c | 2 ++
arch/arm/mach-sa1100/pleb.c | 1 +
arch/arm/mach-sa1100/time.c | 1 +
6 files changed, 12 insertions(+), 2 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-sa1100/cerf.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/cerf.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/cerf.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/platform_device.h>
+#include <linux/irq.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>

Index: linux-2.6.16-git/arch/arm/mach-sa1100/h3600.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/h3600.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/h3600.c
@@ -798,6 +798,8 @@ static void h3800_unmask_gpio_irq(unsign
H3800_ASIC2_GPIINTSTAT |= mask;
}

+static DEFINE_IRQ_CHAINED_TYPE(h3800_IRQ_demux);
+
static void __init h3800_init_irq(void)
{
int i;
@@ -836,7 +838,7 @@ static void __init h3800_init_irq(void)
}
#endif
set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING);
- set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, &h3800_IRQ_demux);
+ set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
}


Index: linux-2.6.16-git/arch/arm/mach-sa1100/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/irq.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/irq.c
@@ -11,12 +11,13 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/sysdev.h>

#include <asm/hardware.h>
-#include <asm/irq.h>
#include <asm/mach/irq.h>

#include "generic.h"
@@ -281,6 +282,8 @@ static int __init sa1100irq_init_devicef
return sysdev_register(&sa1100irq_device);
}

+static DEFINE_IRQ_CHAINED_TYPE(sa1100_high_gpio_handler);
+
device_initcall(sa1100irq_init_devicefs);

void __init sa1100_init_irq(void)
Index: linux-2.6.16-git/arch/arm/mach-sa1100/neponset.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/neponset.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/neponset.c
@@ -137,6 +137,8 @@ static struct sa1100_port_fns neponset_p
.get_mctrl = neponset_get_mctrl,
};

+static DEFINE_IRQ_CHAINED_TYPE(neponset_irq_handler);
+
static int neponset_probe(struct platform_device *dev)
{
sa1100_register_uart_fns(&neponset_port_fns);
Index: linux-2.6.16-git/arch/arm/mach-sa1100/pleb.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/pleb.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/pleb.c
@@ -7,6 +7,7 @@
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
+#include <linux/irq.h>

#include <linux/mtd/partitions.h>

Index: linux-2.6.16-git/arch/arm/mach-sa1100/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-sa1100/time.c
+++ linux-2.6.16-git/arch/arm/mach-sa1100/time.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/signal.h>


--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:41 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-clps7500/core.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-clps7500/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-clps7500/core.c
+++ linux-2.6.16-git/arch/arm/mach-clps7500/core.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/init.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:53 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-rpc/irq.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-rpc/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-rpc/irq.c
+++ linux-2.6.16-git/arch/arm/mach-rpc/irq.c
@@ -112,6 +112,15 @@ static struct irqchip iomd_fiq_chip = {
.unmask = iomd_unmask_irq_fiq,
};

+static unsigned int startup_irq_disabled(unsigned int irq)
+{
+ return 0;
+}
+
+/* Interrupt type for irqs which must not be
+ * automatically enabled in reqeust_irq */
+static struct irq_type level_type_nostart;
+
void __init rpc_init_irq(void)
{
unsigned int irq, flags;
@@ -121,16 +130,19 @@ void __init rpc_init_irq(void)
iomd_writeb(0, IOMD_FIQMASK);
iomd_writeb(0, IOMD_DMAMASK);

+ /*
+ * Copy the defalut type fields. This is a migration
+ * solution.
+ */
+ level_type_nostart = default_level_type;
+ level_type_nostart.startup = startup_irq_disabled;
+
for (irq = 0; irq < NR_IRQS; irq++) {
flags = IRQF_VALID;

if (irq <= 6 || (irq >= 9 && irq <= 15))
flags |= IRQF_PROBE;

- if (irq == 21 || (irq >= 16 && irq <= 19) ||
- irq == IRQ_KEYBOARDTX)
- flags |= IRQF_NOAUTOEN;
-
switch (irq) {
case 0 ... 7:
set_irq_chip(irq, &iomd_a_chip);
@@ -155,6 +167,10 @@ void __init rpc_init_irq(void)
set_irq_flags(irq, IRQF_VALID);
break;
}
+
+ if (irq == 21 || (irq >= 16 && irq <= 19) ||
+ irq == IRQ_KEYBOARDTX)
+ set_irq_handler(irq, &level_type_nostart);
}

init_FIQ();

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:47 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-ixp2000/core.c | 6 +++++-
arch/arm/mach-ixp2000/ixdp2x00.c | 4 +++-
arch/arm/mach-ixp2000/ixdp2x01.c | 4 +++-
3 files changed, 11 insertions(+), 3 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-ixp2000/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp2000/core.c
+++ linux-2.6.16-git/arch/arm/mach-ixp2000/core.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
@@ -407,7 +408,7 @@ static void ixp2000_err_irq_handler(unsi
for(i = 31; i >= 0; i--) {
if(status & (1 << i)) {
desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
- desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
+ desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
}
}
}
@@ -452,6 +453,9 @@ static struct irqchip ixp2000_irq_chip =
.unmask = ixp2000_irq_unmask
};

+static DEFINE_IRQ_CHAINED_TYPE(ixp2000_GPIO_irq_handler);
+static DEFINE_IRQ_CHAINED_TYPE(ixp2000_err_irq_handler);
+
void __init ixp2000_init_irq(void)
{
int irq;
Index: linux-2.6.16-git/arch/arm/mach-ixp2000/ixdp2x00.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp2000/ixdp2x00.c
+++ linux-2.6.16-git/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -146,6 +146,8 @@ static struct irqchip ixdp2x00_cpld_irq_
.unmask = ixdp2x00_irq_unmask
};

+static DEFINE_IRQ_CHAINED_TYPE(ixdp2x00_irq_handler);
+
void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
{
unsigned int irq;
@@ -168,7 +170,7 @@ void ixdp2x00_init_irq(volatile unsigned
}

/* Hook into PCI interrupt */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x00_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}

/*************************************************************************
Index: linux-2.6.16-git/arch/arm/mach-ixp2000/ixdp2x01.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-ixp2000/ixdp2x01.c
+++ linux-2.6.16-git/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -96,6 +96,8 @@ static struct irqchip ixdp2x01_irq_chip
.unmask = ixdp2x01_irq_unmask
};

+static DEFINE_IRQ_CHAINED_TYPE(ixdp2x01_irq_handler);
+
/*
* We only do anything if we are the master NPU on the board.
* The slave NPU only has the ethernet chip going directly to
@@ -128,7 +130,7 @@ void __init ixdp2x01_init_irq(void)
}

/* Hook into PCI interrupts */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x01_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
}



--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:44 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-imx/irq.c | 5 +++++
arch/arm/mach-imx/time.c | 1 +
2 files changed, 6 insertions(+)

Index: linux-2.6.16-git/arch/arm/mach-imx/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-imx/irq.c
+++ linux-2.6.16-git/arch/arm/mach-imx/irq.c
@@ -217,6 +217,11 @@ static struct irqchip imx_gpio_chip = {
.set_type = imx_gpio_irq_type,
};

+static DEFINE_IRQ_CHAINED_TYPE(imx_gpioa_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpiob_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpioc_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpiod_demux_handler);
+
void __init
imx_init_irq(void)
{
Index: linux-2.6.16-git/arch/arm/mach-imx/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-imx/time.c
+++ linux-2.6.16-git/arch/arm/mach-imx/time.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/time.h>

#include <asm/hardware.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:54 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-s3c2410/bast-irq.c | 8 +++++---
arch/arm/mach-s3c2410/irq.c | 5 +++++
arch/arm/mach-s3c2410/s3c2440-irq.c | 3 +++
arch/arm/mach-s3c2410/time.c | 1 +
4 files changed, 14 insertions(+), 3 deletions(-)

Index: linux-2.6.16-git/arch/arm/mach-s3c2410/bast-irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-s3c2410/bast-irq.c
+++ linux-2.6.16-git/arch/arm/mach-s3c2410/bast-irq.c
@@ -136,13 +136,15 @@ bast_irq_pc104_demux(unsigned int irq,
for (i = 0; stat != 0; i++, stat >>= 1) {
if (stat & 1) {
irqno = bast_pc104_irqs[i];
-
- desc_handle_irq(irqno, irq_desc + irqno, regs);
+ desc = irq_desc + irqno;
+ desc_handle_irq(irqno, desc, regs);
}
}
}
}

+static DEFINE_IRQ_CHAINED_TYPE(bast_irq_pc104_demux);
+
static __init int bast_irq_init(void)
{
unsigned int i;
@@ -156,7 +158,7 @@ static __init int bast_irq_init(void)

set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);

- /* reigster our IRQs */
+ /* register our IRQs */

for (i = 0; i < 4; i++) {
unsigned int irqno = bast_pc104_irqs[i];
Index: linux-2.6.16-git/arch/arm/mach-s3c2410/irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-s3c2410/irq.c
+++ linux-2.6.16-git/arch/arm/mach-s3c2410/irq.c
@@ -573,6 +573,11 @@ s3c_irq_demux_uart2(unsigned int irq,
}


+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart0);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart1);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart2);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_adc);
+
/* s3c24xx_init_irq
*
* Initialise S3C2410 IRQ system
Index: linux-2.6.16-git/arch/arm/mach-s3c2410/s3c2440-irq.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ linux-2.6.16-git/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -157,6 +157,9 @@ static struct irqchip s3c_irq_cam = {
.ack = s3c_irq_cam_ack,
};

+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_wdtac97);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_cam);
+
static int s3c2440_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
Index: linux-2.6.16-git/arch/arm/mach-s3c2410/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-s3c2410/time.c
+++ linux-2.6.16-git/arch/arm/mach-s3c2410/time.c
@@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/err.h>
#include <linux/clk.h>


--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:43 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-h720x/common.c | 6 ++++++
arch/arm/mach-h720x/cpu-h7202.c | 2 ++
2 files changed, 8 insertions(+)

Index: linux-2.6.16-git/arch/arm/mach-h720x/common.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-h720x/common.c
+++ linux-2.6.16-git/arch/arm/mach-h720x/common.c
@@ -163,6 +163,11 @@ h720x_gpiod_demux_handler(unsigned int i
h720x_gpio_handler(mask, irq, desc, regs);
}

+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioa_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpiob_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioc_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpiod_demux_handler);
+
#ifdef CONFIG_CPU_H7202
static void
h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
@@ -175,6 +180,7 @@ h720x_gpioe_demux_handler(unsigned int i
IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
h720x_gpio_handler(mask, irq, desc, regs);
}
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioe_demux_handler);
#endif

static struct irqchip h720x_global_chip = {
Index: linux-2.6.16-git/arch/arm/mach-h720x/cpu-h7202.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-h720x/cpu-h7202.c
+++ linux-2.6.16-git/arch/arm/mach-h720x/cpu-h7202.c
@@ -175,6 +175,8 @@ static struct irqaction h7202_timer_irq
.handler = h7202_timer_interrupt,
};

+static DEFINE_IRQ_CHAINED_TYPE(h7202_timerx_demux_handler);
+
/*
* Setup TIMER0 as system timer
*/

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:38 UTC
Permalink
Convert the files in arch/arm/common to use the generic
irq handling functions.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/common/locomo.c | 6 ++++++
arch/arm/common/sa1111.c | 8 +++++---
arch/arm/common/time-acorn.c | 1 +
3 files changed, 12 insertions(+), 3 deletions(-)

Index: linux-2.6.16-git/arch/arm/common/locomo.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/common/locomo.c
+++ linux-2.6.16-git/arch/arm/common/locomo.c
@@ -425,6 +425,12 @@ static struct irqchip locomo_spi_chip =
.unmask = locomo_spi_unmask_irq,
};

+static DEFINE_IRQ_CHAINED_TYPE(locomo_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_key_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_gpio_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_lt_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_spi_handler);
+
static void locomo_setup_irq(struct locomo *lchip)
{
int irq;
Index: linux-2.6.16-git/arch/arm/common/sa1111.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/common/sa1111.c
+++ linux-2.6.16-git/arch/arm/common/sa1111.c
@@ -151,7 +151,7 @@ static void
sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
unsigned int stat0, stat1, i;
- void __iomem *base = desc->data;
+ void __iomem *base = get_irq_data(irq);

stat0 = sa1111_readl(base + SA1111_INTSTATCLR0);
stat1 = sa1111_readl(base + SA1111_INTSTATCLR1);
@@ -169,11 +169,11 @@ sa1111_irq_handler(unsigned int irq, str

for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
if (stat0 & 1)
- do_edge_IRQ(i, irq_desc + i, regs);
+ handle_edge_irq(i, irq_desc + i, regs);

for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
- do_edge_IRQ(i, irq_desc + i, regs);
+ handle_edge_irq(i, irq_desc + i, regs);

/* For level-based interrupts */
desc->chip->unmask(irq);
@@ -378,6 +378,8 @@ static struct irqchip sa1111_high_chip =
.set_wake = sa1111_wake_highirq,
};

+static DEFINE_IRQ_CHAINED_TYPE(sa1111_irq_handler);
+
static void sa1111_setup_irq(struct sa1111 *sachip)
{
void __iomem *irqbase = sachip->base + SA1111_INTC;
Index: linux-2.6.16-git/arch/arm/common/time-acorn.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/common/time-acorn.c
+++ linux-2.6.16-git/arch/arm/common/time-acorn.c
@@ -16,6 +16,7 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>

#include <asm/hardware.h>
#include <asm/io.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:35 UTC
Permalink
The current design of the generic irq handler uses an all-in-one
superhandler __do_IRQ to handle any type of interrupt. This turned out
to be not suitable for ARM SoCs and led to an ARM specific interrupt
handling implementation. The ARM implementation uses a different
abstraction of the hardware.

The extension of the generic IRQ subsystem consolidates the hardware
abstraction by seperation of 'type flow control' and the 'chip'. Each
interrupt type has its own optimized flow control handler and allows
the association of a a chip type to each interrupt.

In order to allow a smooth conversion the __do_IRQ() super-handler
remains unchanged.

More detailed information can be found in the docbook documentation.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

include/linux/irq.h | 244 +++++++++++++++++++++++------
kernel/irq/Makefile | 2
kernel/irq/handle.c | 432 +++++++++++++++++++++++++++++++++++++++++++++++-----
kernel/irq/manage.c | 192 +++++++++++++++++++++--
kernel/irq/resend.c | 82 +++++++++
5 files changed, 853 insertions(+), 99 deletions(-)

Index: linux-2.6.16-git/include/linux/irq.h
===================================================================
--- linux-2.6.16-git.orig/include/linux/irq.h
+++ linux-2.6.16-git/include/linux/irq.h
@@ -1,14 +1,6 @@
#ifndef __irq_h
#define __irq_h

-/*
- * Please do not include this file in generic code. There is currently
- * no requirement for any architecture to implement anything held
- * within this file.
- *
- * Thanks. --rmk
- */
-
#include <linux/config.h>
#include <linux/smp.h>

@@ -40,48 +32,146 @@
# define CHECK_IRQ_PER_CPU(var) 0
#endif

+#define IRQ_NOPROBE 512 /* IRQ is not valid for probing */
+#define IRQ_NOREQUEST 1024 /* IRQ cannot be requested */
+
+/*
+ * IRQ types
+ */
+#define IRQ_TYPE_NONE 0x0000 /* Default, unspecified type */
+#define IRQ_TYPE_EDGEL 0x0001 /* Edge low/falling type */
+#define IRQ_TYPE_EDGEH 0x0002 /* Edge high/rising type */
+#define IRQ_TYPE_EDGEB \
+ (IRQ_TYPE_EDGEL | IRQ_TYPE_EDGEH) /* Edge low+high/both type */
+#define IRQ_TYPE_LEVELL 0x0004 /* Level low type */
+#define IRQ_TYPE_LEVELH 0x0008 /* Level high type */
+#define IRQ_TYPE_SIMPLE 0x0010 /* Simple type */
+
+
/*
- * Interrupt controller descriptor. This is all we need
- * to describe about the low-level hardware.
+ * IRQ wakeup control modes
+ */
+#define IRQ_WAKE_NORESUME 0x0000 /* Do not resume on this irq */
+#define IRQ_WAKE_RESUME 0x0001 /* Enable resume on this irq */
+
+/**
+ * struct irq_chip - Low level interrupt controller hardware descriptor
+ *
+ * @ack: acknowledge IRQ
+ * @mask: mask the IRQ
+ * @mask_ack: acknowledge and mask the IRQ
+ * @unmask: unmask the IRQ
+ * @retrigger: retrigger the IRQ in hardware, if possible.
+ * Return 0 on success.
+ * @set_type: set the IRQ type (level, edge[high,low,both])
+ * @set_wake: Set the IRQ PM-wakeup function
+ * @options: option field to store type, wake information
+ * @lock: locking for SMP
+ * @chip_data: platform-specific private data for the chip
+ */
+struct irq_chip {
+ spinlock_t lock;
+ void (*ack)(unsigned int irq);
+ void (*mask)(unsigned int irq);
+ void (*mask_ack)(unsigned int irq);
+ void (*unmask)(unsigned int irq);
+ int (*retrigger)(unsigned int irq);
+ int (*set_type)(unsigned int irq, unsigned int hw_type);
+ int (*set_wake)(unsigned int irq, unsigned int mode);
+ unsigned long options;
+ void *chip_data;
+};
+
+struct irq_desc;
+struct irq_type;
+
+/**
+ * struct irq_type - high level hardware interrupt type descriptor
+ *
+ * @typename: name for /proc/interrupts
+ * @startup: start up the interrupt (defaults to ->enable if NULL)
+ * @shutdown: shut down the interrupt (defaults to ->disable if NULL)
+ * @enable: enable the interrupt (defaults to chip->unmask if NULL)
+ * @disable: disable the interrupt (defaults to chip->mask if NULL)
+ * @handle_irq: irq flow handler called from the arch IRQ glue code
+ * @ack: start of new interrupt. (Should be renamed to 'start')
+ * @hold: same interrupt while the handler is running
+ * @end: end of interrupt
+ * @set_affinity: set the CPU affinity on SMP machines
+ * @set_type: set the interrupt type (level, edge[high,low,both]),
+ * returns a pointer to the irq_type structure which can
+ * handle the requested type or NULL, if the type cannot
+ * be handled.
+ * @release: release function solely used by UML
*/
-struct hw_interrupt_type {
- const char * typename;
- unsigned int (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
- void (*ack)(unsigned int irq);
- void (*end)(unsigned int irq);
- void (*set_affinity)(unsigned int irq, cpumask_t dest);
+struct irq_type {
+ const char *typename;
+ unsigned int (*startup)(unsigned int irq);
+ void (*shutdown)(unsigned int irq);
+ void (*enable)(unsigned int irq);
+ void (*disable)(unsigned int irq);
+
+ void (*handle_irq)(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+
+ /* (*start) Will be renamed */
+ void (*ack)(unsigned int irq);
+ void (*hold)(unsigned int irq);
+ void (*end)(unsigned int irq);
+ void (*set_affinity)(unsigned int irq, cpumask_t dest);
+ struct irq_type *(*set_type)(unsigned int irq, unsigned int type);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id);
#endif
};

-typedef struct hw_interrupt_type hw_irq_controller;
-
-/*
- * This is the "IRQ descriptor", which contains various information
- * about the irq, including what kind of hardware handling it has,
- * whether it is disabled etc etc.
+/**
+ * struct irq_desc - interrupt descriptor
+ *
+ * @handler: interrupt type dependent handler functions,
+ * (this should be renamed to 'type')
+ * @handler_data: data for the type handlers
+ * @chip_data: platform-specific private data for the chip to
+ * allow shared chip implementations for
+ * @chip: low level hardware access functions - comes from type
+ * @action: the irq action chain
+ * @status: status information
+ * @depth: disable-depth, for nested irq_disable() calls
+ * @irq_count: stats field to detect stalled irqs
+ * @irqs_unhandled: stats field for spurious unhandled interrupts
+ * @lock: locking for SMP
+ * @move_irq: Flag need to re-target interrupt destination
*
* Pad this out to 32 bytes for cache and indexing reasons.
*/
typedef struct irq_desc {
- hw_irq_controller *handler;
- void *handler_data;
- struct irqaction *action; /* IRQ action list */
- unsigned int status; /* IRQ status */
- unsigned int depth; /* nested irq disables */
- unsigned int irq_count; /* For detecting broken interrupts */
- unsigned int irqs_unhandled;
- spinlock_t lock;
+ struct irq_type *handler;
+ void *handler_data;
+ struct irq_chip *chip;
+ void *chip_data;
+ struct irqaction *action;
+ unsigned int status;
+
+ unsigned int depth;
+ unsigned int irq_count;
+ unsigned int irqs_unhandled;
+ spinlock_t lock;
#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
- unsigned int move_irq; /* Flag need to re-target intr dest*/
+ unsigned int move_irq;
#endif
} ____cacheline_aligned irq_desc_t;

+
+/*
+ * Migration helpers for obsolete names, they will go away:
+ */
+#define irqdesc irq_desc
+#define irqchip irq_chip
+#define hw_interrupt_type irq_type
+#define set_irq_type set_hwirq_type
+typedef struct irq_type hw_irq_controller;
+
extern irq_desc_t irq_desc [NR_IRQS];

/* Return a pointer to the irq descriptor for IRQ. */
@@ -165,18 +255,6 @@ static inline void set_irq_info(int irq,

#endif // CONFIG_SMP

-extern int no_irq_affinity;
-extern int noirqdebug_setup(char *str);
-
-extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
- struct irqaction *action);
-extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
- int action_ret, struct pt_regs *regs);
-extern int can_request_irq(unsigned int irq, unsigned long irqflags);
-
-extern void init_irq_proc(void);
-
#ifdef CONFIG_AUTO_IRQ_AFFINITY
extern int select_smp_affinity(unsigned int irq);
#else
@@ -187,6 +265,80 @@ select_smp_affinity(unsigned int irq)
}
#endif

+extern int no_irq_affinity;
+
+/* Handle irq action chains */
+extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
+ struct irqaction *action);
+
+/*
+ * Built-in IRQ handlers for various IRQ types,
+ * callable via desc->handler->handle_irq()
+ */
+extern void handle_level_irq(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+
+#define desc_handle_irq(irq, desc, regs) \
+do { \
+ spin_lock(&(desc)->lock); \
+ (desc)->handler->handle_irq(irq, (desc), regs); \
+ spin_unlock(&(desc)->lock); \
+} while(0)
+
+/* Monolithic do_IRQ implementation */
+extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
+
+/* Handling of unhandled and spurious interrupts */
+extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
+ int action_ret, struct pt_regs *regs);
+
+/* Resending of interrupts */
+void check_irq_resend(irq_desc_t *desc, unsigned int irq);
+
+/* Proc filesystem */
+extern void init_irq_proc(void);
+
+/* Enable/disable irq debugging output */
+extern int noirqdebug_setup(char *str);
+
+/* Set/get irq type */
+extern int set_irq_type(unsigned int irq, unsigned int type);
+extern int get_irq_type(unsigned int irq, unsigned int type);
+
+/* Irq wakeup (PM) control) */
+extern int set_irq_wake(unsigned int irq, unsigned int mode);
+#define enable_irq_wake(irq) set_irq_wake(irq, IRQ_WAKE_RESUME)
+#define disable_irq_wake(irq) set_irq_wake(irq, IRQ_WAKE_NORESUME)
+
+/* Checks whether the interrupt can be requested by request_irq() */
+extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+
+/* Set type control/chip/data for an interrupt */
+extern int generic_set_irq_type(unsigned int irq, struct irq_type *type);
+extern int set_irq_data(unsigned int irq, void *data);
+extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
+extern int set_irq_chip_data(unsigned int irq, void *data);
+
+/* Get chip/data for an interrupt */
+#define get_irq_chip(irq) (irq_desc[irq].chip)
+#define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
+#define get_irq_data(irq) (irq_desc[irq].handler_data)
+
+/* Interrupt type default implementations */
+extern struct irq_type no_irq_type;
+extern struct irq_type default_edge_type;
+extern struct irq_type default_level_type;
+extern struct irq_type default_simple_type;
+extern struct irq_type default_percpu_type;
+
#endif

extern hw_irq_controller no_irq_type; /* needed in every arch ? */
Index: linux-2.6.16-git/kernel/irq/Makefile
===================================================================
--- linux-2.6.16-git.orig/kernel/irq/Makefile
+++ linux-2.6.16-git/kernel/irq/Makefile
@@ -1,4 +1,4 @@

-obj-y := handle.o manage.o spurious.o migration.o
+obj-y := handle.o manage.o spurious.o migration.o resend.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_PROC_FS) += proc.o
Index: linux-2.6.16-git/kernel/irq/handle.c
===================================================================
--- linux-2.6.16-git.orig/kernel/irq/handle.c
+++ linux-2.6.16-git/kernel/irq/handle.c
@@ -1,9 +1,13 @@
/*
* linux/kernel/irq/handle.c
*
- * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner, Russell King
*
* This file contains the core interrupt handling code.
+ *
+ * Detailed information is available in Documentation/DocBook/genericirq
+ *
*/

#include <linux/irq.h>
@@ -12,57 +16,57 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>

+#if defined(CONFIG_NO_IDLE_HZ)
+#include <asm/dyntick.h>
+#endif
+
#include "internals.h"

/*
- * Linux has a controller-independent interrupt architecture.
- * Every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * The code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic or
- * having to touch the generic code.
- *
- * Controller mappings for all interrupt sources:
+ * Default initialization for all interrupt sources
*/
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.handler = &no_irq_type,
- .lock = SPIN_LOCK_UNLOCKED
+ .lock = SPIN_LOCK_UNLOCKED,
+ .depth = 1,
}
};

/*
- * Generic 'no controller' code
+ * What should we do if we get a hw irq event on an illegal vector?
+ * Each architecture has to answer this themself.
*/
-static void end_none(unsigned int irq) { }
-static void enable_none(unsigned int irq) { }
-static void disable_none(unsigned int irq) { }
-static void shutdown_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-
-static void ack_none(unsigned int irq)
+static void ack_bad(unsigned int irq)
{
- /*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themself.
- */
ack_bad_irq(irq);
}

-struct hw_interrupt_type no_irq_type = {
- .typename = "none",
- .startup = startup_none,
- .shutdown = shutdown_none,
- .enable = enable_none,
- .disable = disable_none,
- .ack = ack_none,
- .end = end_none,
- .set_affinity = NULL
+/*
+ * NOP functions
+ */
+static void noop(unsigned int irq)
+{
+}
+
+static unsigned int noop_ret(unsigned int irq)
+{
+ return 0;
+}
+
+/*
+ * Generic no controller implementation
+ */
+struct irq_type no_irq_type = {
+ .typename = "none",
+ .startup = noop_ret,
+ .shutdown = noop,
+ .enable = noop,
+ .disable = noop,
+ .ack = ack_bad,
+ .end = noop,
+ .handle_irq = handle_bad_irq,
};

/*
@@ -74,7 +78,148 @@ irqreturn_t no_action(int cpl, void *dev
}

/*
- * Have got an event to handle:
+ * default ack function
+ */
+static void default_ack(unsigned int irq)
+{
+ irq_desc[irq].chip->ack(irq);
+}
+
+/*
+ * default mask ack function
+ */
+static void default_mask_ack(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (desc->chip->mask_ack) {
+ desc->chip->mask_ack(irq);
+ } else {
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+ }
+}
+
+/*
+ * default enable function
+ */
+static void default_enable(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ desc->chip->unmask(irq);
+ desc->status &= ~IRQ_MASKED;
+}
+
+/*
+ * default end function
+ */
+static void default_end(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (!desc->depth)
+ desc->chip->unmask(irq);
+}
+
+/*
+ * default disable function
+ */
+static void default_disable(unsigned int irq)
+{
+ irq_desc[irq].chip->mask(irq);
+}
+
+/*
+ * Default set type function
+ */
+static struct irq_type *default_set_type(unsigned int irq, unsigned int type)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (desc->chip->set_type)
+ if (desc->chip->set_type(irq, type))
+ return NULL;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ return &no_irq_type;
+
+ case IRQ_TYPE_EDGEL:
+ case IRQ_TYPE_EDGEH:
+ case IRQ_TYPE_EDGEB:
+ return &default_edge_type;
+ case IRQ_TYPE_LEVELL:
+ case IRQ_TYPE_LEVELH:
+ return &default_level_type;
+ case IRQ_TYPE_SIMPLE:
+ return &default_simple_type;
+ }
+ return NULL;
+}
+
+/*
+ * Generic edge type interrupt
+ *
+ */
+struct irq_type default_edge_type = {
+ .typename = "default_edge",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_ack,
+ .hold = default_mask_ack,
+ .end = noop,
+ .handle_irq = handle_edge_irq,
+ .set_type = default_set_type,
+};
+
+/*
+ * Generic level type interrupt
+ */
+struct irq_type default_level_type = {
+ .typename = "default_level",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_mask_ack,
+ .end = default_end,
+ .handle_irq = handle_level_irq,
+ .set_type = default_set_type,
+};
+
+/*
+ * Generic simple type interrupt
+ *
+ * No hardware handling necessary
+ */
+struct irq_type default_simple_type = {
+ .typename = "default_simple",
+ .enable = default_enable,
+ .disable = default_disable,
+ .set_type = default_set_type,
+ .handle_irq = handle_simple_irq,
+};
+
+#ifdef CONFIG_SMP
+/*
+ * Generic per cpu type interrupt
+ */
+struct irq_type default_percpu_type = {
+ .typename = "default_percpu",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_ack,
+ .end = default_end,
+ .handle_irq = handle_percpu_irq,
+};
+#endif
+
+/**
+ * handle_IRQ_event - irq action chain handler
+ * @irq: the interrupt number
+ * @regs: pointer to a register structure
+ * @action: the interrupt action chain for this irq
+ *
+ * Handles the action chain of an irq event
*/
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
struct irqaction *action)
@@ -84,6 +229,15 @@ fastcall int handle_IRQ_event(unsigned i
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();

+#if defined(CONFIG_NO_IDLE_HZ)
+ if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
+ write_seqlock(&xtime_lock);
+ if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+ system_timer->dyn_tick->handler(irq, 0, regs);
+ write_sequnlock(&xtime_lock);
+ }
+#endif
+
do {
ret = action->handler(irq, action->dev_id, regs);
if (ret == IRQ_HANDLED)
@@ -99,10 +253,210 @@ fastcall int handle_IRQ_event(unsigned i
return retval;
}

-/*
- * do_IRQ handles all normal device IRQ's (the special
+/**
+ * handle_bad_irq - handle spurious and unhandled irqs
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ */
+void handle_bad_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+}
+
+/**
+ * handle_simple_irq - Simple and software-decoded IRQs.
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Simple interrupts are either sent from a demultiplexing interrupt
+ * handler or come from hardware, where no interrupt hardware control
+ * is necessary.
+ *
+ * Note: The caller is expected to handle the ack, clear, mask and
+ * unmask issues if necessary.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_simple_irq(unsigned int irq, irq_desc_t *desc,
+ struct pt_regs *regs)
+{
+ struct irqaction *action;
+ irqreturn_t action_ret;
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ action = desc->action;
+ if (unlikely(!action || desc->depth))
+ return;
+
+ desc->status |= IRQ_INPROGRESS;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+ desc->status &= ~IRQ_INPROGRESS;
+}
+
+/**
+ * handle_level_irq - Level type irq handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Level type interrupts are active as long as the hardware line has
+ * the active level. This may require to mask the interrupt and unmask it
+ * after the associated handler has acknowledged the device, so the
+ * interrupt line is back to inactive.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_level_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ irqreturn_t action_ret;
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ desc->handler->ack(irq);
+
+ /*
+ * If its disabled or no action available
+ * keep it masked and get out of here
+ */
+ action = desc->action;
+ if (unlikely(!action || desc->depth))
+ goto out;
+
+ desc->status |= IRQ_INPROGRESS;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+
+ desc->status &= ~IRQ_INPROGRESS;
+out:
+ desc->handler->end(irq);
+}
+
+/**
+ * handle_edge_irq - edge type IRQ handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Interrupt occures on the falling and/or rising edge of a hardware
+ * signal. The occurence is latched into the irq controller hardware
+ * and must be acked in order to be reenabled. After the ack another
+ * interrupt can happen on the same source even before the first one
+ * is handled by the assosiacted event handler. If this happens it
+ * might be necessary to disable (mask) the interrupt depending on the
+ * controller hardware. This requires to reenable the interrupt inside
+ * of the loop which handles the interrupts which have arrived while
+ * the handler was running. If all pending interrupts are handled, the
+ * loop is left and depending on the hardware controller some final
+ * ack might be necessary.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_edge_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ /*
+ * If we're currently running this IRQ, or its disabled,
+ * we shouldn't process the IRQ. Mark it pending, handle
+ * the necessary masking and go out
+ */
+ if (unlikely((desc->status & IRQ_INPROGRESS) || desc->depth ||
+ !desc->action)) {
+ desc->status |= (IRQ_PENDING | IRQ_MASKED);
+ desc->handler->hold(irq);
+ return;
+ }
+
+ /* Start handling the irq */
+ desc->handler->ack(irq);
+
+ /* Mark the IRQ currently in progress.*/
+ desc->status |= IRQ_INPROGRESS;
+
+ do {
+ struct irqaction *action = desc->action;
+ irqreturn_t action_ret;
+
+ if (unlikely(!action)) {
+ desc->handler->disable(irq);
+ return;
+ }
+
+ /*
+ * When another irq arrived while we were handling
+ * one, we could have masked the irq.
+ * Renable it, if it was not disabled in meantime.
+ */
+ if (unlikely(((desc->status & (IRQ_PENDING | IRQ_MASKED)) ==
+ (IRQ_PENDING | IRQ_MASKED)) && !desc->depth))
+ desc->handler->enable(irq);
+
+ desc->status &= ~IRQ_PENDING;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+
+ } while ((desc->status & IRQ_PENDING) && !desc->depth);
+
+ desc->status &= ~IRQ_INPROGRESS;
+ desc->handler->end(irq);
+}
+
+#ifdef CONFIG_SMP
+/**
+ * handle_percpu_IRQ - Per CPU local irq handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Per CPU interrupts on SMP machines without locking requirements
+ */
+void handle_percpu_irq(unsigned int irq, irq_desc_t *desc,
+ struct pt_regs *regs)
+{
+ irqreturn_t action_ret;
+
+ kstat_this_cpu.irqs[irq]++;
+ desc->handler->ack(irq);
+ action_ret = handle_IRQ_event(irq, regs, desc->action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ desc->handler->end(irq);
+}
+#endif /* CONFIG_SMP */
+
+/**
+ * __do_IRQ - original all in one handler
+ * @irq: the interrupt number
+ * @regs: pointer to a register structure
+ *
+ * __do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
- * handlers).
+ * handlers). * This is the original x86 implementation which is used for every
+ * type of interrupt.
+ *
*/
fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
{
Index: linux-2.6.16-git/kernel/irq/manage.c
===================================================================
--- linux-2.6.16-git.orig/kernel/irq/manage.c
+++ linux-2.6.16-git/kernel/irq/manage.c
@@ -1,7 +1,8 @@
/*
* linux/kernel/irq/manage.c
*
- * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner
*
* This file contains driver APIs to the irq subsystem.
*/
@@ -128,11 +129,9 @@ void enable_irq(unsigned int irq)
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;

- desc->status = status;
- if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
- desc->status = status | IRQ_REPLAY;
- hw_resend_irq(desc->handler,irq);
- }
+ /* Prevent probing on this irq */
+ desc->status = status | IRQ_NOPROBE;
+ check_irq_resend(desc, irq);
desc->handler->enable(irq);
/* fall-through */
}
@@ -144,6 +143,28 @@ void enable_irq(unsigned int irq)

EXPORT_SYMBOL(enable_irq);

+/**
+ * set_irq_wake - control irq power management wakeup
+ * @irq: Interrupt to control
+ * @mode: power management wakeup mode
+ *
+ * Enable/disable power management wakeup mode
+ */
+int set_irq_wake(unsigned int irq, unsigned int mode)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ int ret = -ENXIO;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->chip && desc->chip->set_wake)
+ ret = desc->chip->set_wake(irq, mode);
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return ret;
+}
+
+EXPORT_SYMBOL(set_irq_wake);
+
/*
* Internal function that tells the architecture code whether a
* particular irq has been exclusively allocated or is available
@@ -153,7 +174,7 @@ int can_request_irq(unsigned int irq, un
{
struct irqaction *action;

- if (irq >= NR_IRQS)
+ if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
return 0;

action = irq_desc[irq].action;
@@ -200,7 +221,7 @@ int setup_irq(unsigned int irq, struct i
/*
* The following block of code has to be executed atomically
*/
- spin_lock_irqsave(&desc->lock,flags);
+ spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
@@ -235,7 +256,7 @@ int setup_irq(unsigned int irq, struct i
else
desc->handler->enable(irq);
}
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);

new->irq = irq;
register_irq_proc(irq);
@@ -276,7 +297,7 @@ void free_irq(unsigned int irq, void *de
return;

desc = irq_desc + irq;
- spin_lock_irqsave(&desc->lock,flags);
+ spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;
for (;;) {
struct irqaction * action = *p;
@@ -304,7 +325,7 @@ void free_irq(unsigned int irq, void *de
else
desc->handler->disable(irq);
}
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
unregister_handler_proc(irq, action);

/* Make sure it's not being used on another CPU */
@@ -312,8 +333,8 @@ void free_irq(unsigned int irq, void *de
kfree(action);
return;
}
- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
- spin_unlock_irqrestore(&desc->lock,flags);
+ printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
+ spin_unlock_irqrestore(&desc->lock, flags);
return;
}
}
@@ -366,6 +387,8 @@ int request_irq(unsigned int irq,
return -EINVAL;
if (irq >= NR_IRQS)
return -EINVAL;
+ if (irq_desc[irq].status & IRQ_NOREQUEST)
+ return -EINVAL;
if (!handler)
return -EINVAL;

@@ -391,3 +414,146 @@ int request_irq(unsigned int irq,

EXPORT_SYMBOL(request_irq);

+/**
+ * generic_set_irq_type - set the hardware irq type structure for an irq
+ * @irq: Interrupt number
+ * @type: Pointer to irq_type structure
+ */
+int generic_set_irq_type(unsigned int irq, struct irq_type *type)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install type for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ if (!type)
+ type = &no_irq_type;
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->handler = type;
+ spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(generic_set_irq_type);
+
+/**
+ * set_irq_data - set irq type data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to interrupt specific data
+ *
+ * Set the hardware irq controller data for an irq
+ */
+int set_irq_data(unsigned int irq, void *data)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR
+ "Trying to install controller data for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->handler_data = data;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_data);
+
+/**
+ * set_irq_chip - set irq chip for an IRQ
+ * @irq: Interrupt number
+ * @chip: Pointer to irq_chip structure
+ *
+ * Set the hardware chip structure for an IRQ
+ */
+int set_irq_chip(unsigned int irq, struct irq_chip *chip)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->chip = chip;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_chip);
+
+/**
+ * set_irq_chip_data - set irq chip data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to chip specific data
+ *
+ * Set the hardware irq chip data for an irq
+ */
+int set_irq_chip_data(unsigned int irq, void *data)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS || !desc->handler || !desc->chip) {
+ printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->chip_data = data;
+ spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_chip_data);
+
+/*
+ * set_hwirq_type - Set the irq type (level/edge/simple/percpu)
+ * @irq: Interrupt number
+ * @hw_type: interrupt type (see constants in include/linux/irq.h)
+ *
+ * Called from device drivers to configure GPIO interrupts
+ * according to their requirements. The set_type function of the
+ * handler returns a pointer to an irq_type structure which is
+ * able to handle this interrupt type. The handler in the irq
+ * descriptor structure is set to the new handler type.
+ *
+ */
+int set_hwirq_type(unsigned int irq, unsigned int hw_type)
+{
+ struct irq_type *type = NULL;
+ unsigned long flags;
+ irq_desc_t *desc;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
+ return -ENODEV;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->handler->set_type) {
+ type = desc->handler->set_type(irq, hw_type);
+ if (type)
+ desc->handler = type;
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return type ? 0 : -ENXIO;
+}
+
+EXPORT_SYMBOL(set_hwirq_type);
+
Index: linux-2.6.16-git/kernel/irq/resend.c
===================================================================
--- /dev/null
+++ linux-2.6.16-git/kernel/irq/resend.c
@@ -0,0 +1,82 @@
+/*
+ * linux/kernel/irq/resend.c
+ *
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner
+ *
+ * This file contains the tasklet-based IRQ-resend code
+ */
+
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/interrupt.h>
+
+#include "internals.h"
+
+/* Bitmap to handle software resend of interrupts: */
+static DECLARE_BITMAP(irqs_resend, NR_IRQS);
+
+/*
+ * Run software resends of IRQ's
+ */
+static void resend_irqs(unsigned long arg)
+{
+ unsigned long flags;
+ int irq;
+
+ for (;;) {
+ if (bitmap_empty(irqs_resend, NR_IRQS))
+ break;
+ irq = find_first_bit(irqs_resend, NR_IRQS);
+ clear_bit(irq, irqs_resend);
+ local_irq_save(flags);
+ desc_handle_irq(irq, (irq_desc + irq), NULL);
+ local_irq_restore(flags);
+ }
+}
+
+/* Tasklet to handle resend: */
+static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
+
+/*
+ * Handle irq resend
+ *
+ * If the interrupt is waiting to be processed, try to re-run it. We
+ * can't directly run it from here since the caller might be in an
+ * interrupt-protected region. Not all irq controller chips can
+ * retrigger interrupts at hardware level. For edge type interrupts it
+ * is necessary to resend them by software. At the moment the pending
+ * list is handled at the end of asm_do_IRQ. That means the next
+ * interrupt (on any irq line) will invoke the do_pending function. It
+ * could also be done by a thread which is woken up by the
+ * check_irq_resend function.
+ *
+ * Is called with interrupts disabled and desc->lock held
+ */
+void check_irq_resend(irq_desc_t *desc, unsigned int irq)
+{
+
+ /* Chipless implementation. This should vanish in the long run */
+ if (!desc->chip) {
+ unsigned int status = desc->status;
+ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+ desc->status = status | IRQ_REPLAY;
+ hw_resend_irq(desc->handler, irq);
+ }
+ return;
+ }
+
+ /* Chip based implementation */
+ if ((desc->status & IRQ_PENDING) && !test_bit(irq, irqs_resend)) {
+ desc->status &= ~IRQ_PENDING;
+ /* Try to retrigger it in hardware */
+ if (!desc->chip || !desc->chip->retrigger ||
+ desc->chip->retrigger(irq)) {
+ /* Mark it pending */
+ set_bit(irq, irqs_resend);
+ tasklet_schedule(&resend_tasklet);
+ }
+ }
+}
+

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:59 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/plat-omap/gpio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6.16-git/arch/arm/plat-omap/gpio.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/plat-omap/gpio.c
+++ linux-2.6.16-git/arch/arm/plat-omap/gpio.c
@@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned in

desc->chip->ack(irq);

- bank = (struct gpio_bank *) desc->data;
+ bank = get_irq_data(irq);
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
#ifdef CONFIG_ARCH_OMAP15XX
@@ -873,6 +873,8 @@ static struct irqchip mpuio_irq_chip = {
.unmask = mpuio_unmask_irq
};

+static DEFINE_IRQ_CHAINED_TYPE(gpio_irq_handler);
+
static int initialized;
static struct clk * gpio_ick;
static struct clk * gpio_fck;

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:09 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/pcmcia/soc_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.16-git/drivers/pcmcia/soc_common.c
===================================================================
--- linux-2.6.16-git.orig/drivers/pcmcia/soc_common.c
+++ linux-2.6.16-git/drivers/pcmcia/soc_common.c
@@ -39,12 +39,12 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/spinlock.h>
#include <linux/cpufreq.h>

#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/system.h>

#include "soc_common.h"

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:40 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-clps711x/time.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-clps711x/time.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-clps711x/time.c
+++ linux-2.6.16-git/arch/arm/mach-clps711x/time.c
@@ -19,6 +19,7 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/sched.h>

#include <asm/hardware.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:45:49 UTC
Permalink
Fixup the conversion to generic irq subsystem.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

arch/arm/mach-l7200/core.c | 1 +
1 file changed, 1 insertion(+)

Index: linux-2.6.16-git/arch/arm/mach-l7200/core.c
===================================================================
--- linux-2.6.16-git.orig/arch/arm/mach-l7200/core.c
+++ linux-2.6.16-git/arch/arm/mach-l7200/core.c
@@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/device.h>

#include <asm/types.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-07 19:46:03 UTC
Permalink
Include the generic header file instead of the ARM specific one.

Signed-off-by: Thomas Gleixner <***@linutronix.de>
Signed-off-by: Ingo Molnar <***@elte.hu>

drivers/char/s3c2410-rtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.16-git/drivers/char/s3c2410-rtc.c
===================================================================
--- linux-2.6.16-git.orig/drivers/char/s3c2410-rtc.c
+++ linux-2.6.16-git/drivers/char/s3c2410-rtc.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/clk.h>
@@ -29,7 +30,6 @@
#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/rtc.h>

#include <asm/mach/time.h>

--


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Russell King - ARM Linux
2006-04-26 23:05:43 UTC
Permalink
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
latest versions can be found at:

http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patches.tar.bz2

(please check for later versions! - note though that www.tglx.de's isp is
having issues atm.)

Basically, there's two ways that we can merge these patches:

1. These patches can be tested by a large number of folk prior to merging,
and confidence in the patch can be gained, and any issues fixed. Then
we can merge them into 2.6.17 with reasonable confidence that they
should cause minimal (if any) instability.

2. I can merge them as is after 2.6.17, and then you will have to debug
any stability issues when you upgrade to later kernels.

I don't know about most people, but I think (1) is a far better way of
proceeding. So, if you're reading this _and_ you're involved in platform
development, please try running these patches on your board and reporting
success and failure stories.

I'm not asking you to ship products with these patches, I'm just asking
for testing and feedback.

Obviously it would be preferable that any testing should exercise the
interrupt subsystem, so heavy use of CF, IDE, network interfaces, serial
devices, etc would probably be a good test.

Maybe leave a development board running hdparm -t on your CF and ping -f
tests on the network overnight for just one night. Or maybe send a very
large file via serial to your target, or cat /dev/zero out from your
target, again over night while you're not there (but obviously logging
the kernel messages) and check whether it's still going next morning.

Should you see any failures, please attempt to verify whether these
failures occur without the patches before reporting as a failure of
these patches.

Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.

Let's try to get this well tested before 2.6.17's finally released.

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Deepak Saxena
2006-04-27 05:14:21 UTC
Permalink
Post by Russell King - ARM Linux
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patches.tar.bz2
<snip>
Post by Russell King - ARM Linux
Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.
I will test IXP4xx and IXP23xx and post results to the list.

~Deepak
--
Deepak Saxena - ***@plexity.net - http://www.plexity.net

I am not a consumer. My existence on this planet is not defined by my
relationship to a producer of goods. I was not put on this planet to
consume goods from a company for their profit. - Michael W.

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Lennert Buytenhek
2006-04-28 23:18:39 UTC
Permalink
Post by Deepak Saxena
Post by Russell King - ARM Linux
We require people's help on this list concerning these patches. The
http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patches.tar.bz2
<snip>
Post by Russell King - ARM Linux
Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.
I will test IXP4xx and IXP23xx and post results to the list.
ixp23xx with 2.6.17-rc3-armirq1 boots fine for me, will beat on it
a bit more.


cheers,
Lennert

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Deepak Saxena
2006-05-01 16:55:19 UTC
Permalink
Post by Deepak Saxena
I will test IXP4xx and IXP23xx and post results to the list.
48 hours network stress on ixp4xx and no problems.

~Deepak
--
Deepak Saxena - ***@plexity.net - http://www.plexity.net

I am not a consumer. My existence on this planet is not defined by my
relationship to a producer of goods. I was not put on this planet to
consume goods from a company for their profit. - Michael W.

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Manfred Gruber
2006-04-27 06:35:06 UTC
Permalink
Post by Russell King - ARM Linux
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patc
hes.tar.bz2
Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.
I will test it on cirrus logic EP9315 and EP9302.

regards manfred

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Sascha Hauer
2006-04-27 09:53:44 UTC
Permalink
Post by Russell King - ARM Linux
Should you see any failures, please attempt to verify whether these
failures occur without the patches before reporting as a failure of
these patches.
Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.
I'm currently running tests on i.MX and h7202.
I'm using mmc, ping -f and serial ports on i.MX; ping -f and serial
ports on h7202. No problems so far, but the tests are only running for
10 minutes now.

Sascha


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Sascha Hauer
2006-04-28 09:03:48 UTC
Permalink
Post by Sascha Hauer
I'm currently running tests on i.MX and h7202.
I'm using mmc, ping -f and serial ports on i.MX; ping -f and serial
ports on h7202. No problems so far, but the tests are only running for
10 minutes now.
about 200mio interrupts later...

mx1ads> cat /proc/interrupts
CPU0
20: 0 IMX-uart
23: 4984329 IMX-uart
24: 1626 IMX-uart
26: 0 IMX-uart
29: 3582 IMX-uart
30: 17 IMX-uart
35: 3244834 imx-mmc
59: 8497604 i.MX Timer Tick
60: 0 DMA
61: 1548321 DMA
145: 75667998 eth0
Err: 0

h7202> cat /proc/interrupts
CPU0
8: 32203 serial
9: 22785065 serial
15: 8494216 h7202 Timer Tick
72: 44353685 eth0
Err: 0

Everything is still running smoothly. btw I applied the armirq patch on
top of 2.6.17-rc3, not -rc1.

Sometimes the i.MX mmc driver says:

imx-mmc imx-mmc.0: RESP TIMEOUT, hardware stucked STATUS = 0xbf40 IMASK = 0x007b
imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0201, MMC_BLK_LEN = 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088
imx-mmc imx-mmc.0: CMD13, bus 4-bit, dma_size = 0x200

But I think this has nothing to do with the genirq patch and happens in
vanilla kernels aswell (Pavel?)

Sascha


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Pavel Pisa
2006-04-28 23:38:49 UTC
Permalink
Post by Sascha Hauer
Post by Sascha Hauer
I'm currently running tests on i.MX and h7202.
I'm using mmc, ping -f and serial ports on i.MX; ping -f and serial
ports on h7202. No problems so far, but the tests are only running for
10 minutes now.
Everything is still running smoothly. btw I applied the armirq patch on
top of 2.6.17-rc3, not -rc1.
imx-mmc imx-mmc.0: RESP TIMEOUT, hardware stucked STATUS = 0xbf40 IMASK =
0x007b imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0201, MMC_BLK_LEN = 0x0200,
MMC_NOB = 0x0001, DMA_CCR = 0x00002088 imx-mmc imx-mmc.0: CMD13, bus 4-bit,
dma_size = 0x200
But I think this has nothing to do with the genirq patch and happens in
vanilla kernels aswell (Pavel?)
Hello Thomas and Sascha,

I have tested 2.6.17-rc3-armirq1 now, but I do not have so much luck
as Sascha with MMC/SD on i.MX. But is likely SDHC problem and
should not have any impact on generic IRQ handling integration.
I would be happy, if it is included.

=================================================================
Little more observations of SDHC troubles.

The kernel seems to be stable but I see severe problems with MMC/SD
interface. I have done more tests with 2.6.16 not so long ago
and with "imxmmc-start-fix.patch" it have survive my torture
only with some non-harmfull messages about missing IRQ.
Same as reported by Sascha for patched 2.6.17-rc3.
But under patched 2.6.17-rc3 I see more fatal errors

| imx-mmc imx-mmc.0: card inserted
| imx-mmc imx-mmc.0: busy wait for 2 usec in imxmci_tasklet_fnc resp (ERRATUM #4), STATUS = 0xa140 (0x202f)
| ...
This should be there, this is documented hardware flaw
and reliable workaround is in the place

| mx-mmc imx-mmc.0: busy wait for 8 usec in imxmci_tasklet_fnc data, STATUS = 0xbf40 (0x1000)

But I see some of these after card initialization, which should not be
there or at least are not documented as features of unfortunate SDHC silicon.
Strange enough, I observe these only on combination of our PiMX1 board
with MX_DIS1 board. I do not observe this on other PiMX1 placed
on unpopulated IX_PWR2 (used only to connect MMC/SD socket)
powered from USB.

| imx-mmc imx-mmc.0: RESP TIMEOUT, hardware stucked STATUS = 0xbf40 IMASK = 0x007b
| imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0201, MMC_BLK_LEN = 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088
| imx-mmc imx-mmc.0: CMD13 after CMD24, bus 4-bit, dma_size = 0x200

This seems, that data are present after above expressed busy loop,
but response for next command is missing. It seems to be problem
with waiting for end of write block operation. But there is
used feature for waiting for end of the transfer provided/documented
by SDHC hardware. There has to be some problem in this part of the code.

| imx-mmc imx-mmc.0: busy wait for 16 usec in imxmci_tasklet_fnc data, STATUS = 0xbf40 (0x1000)
| imx-mmc imx-mmc.0: busy wait for 2 usec in imxmci_tasklet_fnc data, STATUS = 0xbf40 (0x1000)
| imx-mmc imx-mmc.0: busy wait for 16 usec in imxmci_tasklet_fnc data, STATUS = 0xbf40 (0x1000)

Again some delays. They could be caused by different IRQ timing for
generic IRQ code. The SDHC has such flaws, that it assert sometimes
IRQ before it asserts status bits and these busy loops are trying
to adjust that. But I have never seen this after card initialization
and clock going above 8MHz. So the appearance of this means,
that there could be some problem with clock rate setup
(I have added some printks and they didnot show anything unusual).
Problem observed only on PiMX1+MX_DIS1 again.

| imx-mmc imx-mmc.0: RESP TIMEOUT, hardware stucked STATUS = 0xbf40 IMASK = 0x007b
| imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0201, MMC_BLK_LEN = 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088
| imx-mmc imx-mmc.0: CMD13 after CMD24, bus 4-bit, dma_size = 0x200
| imx-mmc imx-mmc.0: RESP+DMA TIMEOUT, hardware stucked STATUS = 0xa740 IMASK = 0x0078
| imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0219, MMC_BLK_LEN = 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088
| imx-mmc imx-mmc.0: CMD24 after CMD13, bus 4-bit, dma_size = 0x200
| mmcblk0: error 1 sending read/write command
| end_request: I/O error, dev mmcblk0, sector 5357
| end_request: I/O error, dev mmcblk0, sector 5360

There things get really wrong and data are screwed.
Again, I have not observed this on 2.6.16. It is very
likely on PiMX1 board with MX_DIS1 with 2.6.17-rc3
and occasional on USB powered PiMX1.

But observation are interresting. Things are timing sensitive.
It seems that there is problem with wait for end
for block write finishing. I try to investigate this.
Things get really bad, when not only status is missing
but when even next write fails. With "imxmmc-start-fix.patch"
there is no permanent lock, which seems to be significant
progress.

Each help, suggestions, constructive critique are welcomed.

=================================================================

As for generic IRQ patch, I am really happy for these changes
and I think, that broken SDHC should not delay its adoption.
It seems to be SDHC problem or some of mine or my predecessor
assumption fail.

The core kernel seems to be stable even under simple
UART and ETHERNET torture.

PiMX1 # cat /proc/interrupts
CPU0
26: 6996039 IMX-uart
29: 21806 IMX-uart
30: 1371 IMX-uart
35: 145385 imx-mmc
59: 323727 i.MX Timer Tick
60: 0 DMA
61: 36438 DMA
155: 31932 eth0
Err: 0

I really need more reports from people using MMC/SD on i.MX.
The kernel version, hardware, observed problems or even
lack of problems. All my testing has been done with preemption
enabled. Is that your case, Sascha, as well?

I have even tested fully preemptive kernel on PiMX1 around 2.6.14
and I like it much as right solution of realtime shortcoming of official
Linux kernel. It worked with LinCAN and I expect, that IRQ part of that
patch has been similar to actual generic IRQ changes.

I have not got to test LinCAN with 2.6.17-rc3-armirq1, because actual
kernel build system seems to have some new bloody feature to delete
(without asking) my Makefile in the directory for building out
of tree modules.

Best wishes

Pavel Pisa
e-mail: ***@cmp.felk.cvut.cz
www: http://cmp.felk.cvut.cz/~pisa
work: http://www.pikron.com

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-29 07:51:36 UTC
Permalink
Post by Pavel Pisa
Hello Thomas and Sascha,
I have tested 2.6.17-rc3-armirq1 now, but I do not have so much luck
as Sascha with MMC/SD on i.MX. But is likely SDHC problem and
should not have any impact on generic IRQ handling integration.
I would be happy, if it is included.
Pavel,

there was a problem related to IRQ edge polarity in 2.6.17-rc3-armirq1.
Kevin Hilman found it and sent a patch. It's in 2.6.17-rc3-armirq2.

Can you try again please?

Thanks,

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Pavel Pisa
2006-04-29 12:25:31 UTC
Permalink
Post by Thomas Gleixner
Post by Pavel Pisa
Hello Thomas and Sascha,
I have tested 2.6.17-rc3-armirq1 now, but I do not have so much luck
as Sascha with MMC/SD on i.MX. But is likely SDHC problem and
should not have any impact on generic IRQ handling integration.
I would be happy, if it is included.
Pavel,
there was a problem related to IRQ edge polarity in 2.6.17-rc3-armirq1.
Kevin Hilman found it and sent a patch. It's in 2.6.17-rc3-armirq2.
Thomas

thanks for care, I have noticed that on the list, but it is not
source of my problems. All my GPIO interrupts are level trigerred
and SDHC in integrated peripheral, so it is again not problem
of your GPIO chaining IRQ changes.

I have updated LinCAN for 2.6.17-rc1+ and have tortured board little more.

PiMX1 # cat /proc/interrupts
CPU0
26: 48516415 IMX-uart
29: 48 IMX-uart
30: 0 IMX-uart
35: 6 imx-mmc
59: 149567 i.MX Timer Tick
60: 0 DMA
61: 0 DMA
113: 373632 can
155: 2199 eth0
Err: 0

I have found why the PiMX1+MX_DIS1 behaves different way.
There is RTS pin without pull-up on this board and I have
not connected it to level shifter and PC during last test.
It generates really non-deterministic and huge load (IRQ 26).
I decided to left it in this state to check throughly drivers
and your code :-)

IRQ 113 (can) and IRQ 155 (eth0) are GPIO level trigerred
chained interrupts. They seem to perform like a charm.

There is one result of CAN tests run between host (./canping -m 5 -w 0 -v)
and MX1 target (./canping -s 5). Five threads in parallel

Total count: 194457, Timeouts: 0
Summary statistics:
Id 1000: count = 39000 mean = 1500.33 stddev = 330.80 min = 615 max = 3433 [us] loss = 0% (0)
Id 1002: count = 38999 mean = 1448.29 stddev = 353.80 min = 613 max = 3789 [us] loss = 0% (0)
Id 1004: count = 39000 mean = 1428.95 stddev = 359.55 min = 612 max = 3887 [us] loss = 0% (0)
Id 1006: count = 38999 mean = 1484.60 stddev = 342.36 min = 615 max = 3532 [us] loss = 0% (0)
Id 1008: count = 38999 mean = 1461.21 stddev = 354.17 min = 613 max = 3779 [us] loss = 0% (0)

No lost CAN message under full line fill. That is not bad.

I am curious, if CAN latencies can get better when it would be
possible to test 2.6.17 with fully preemptive kernel patches,
when 2.6.17 is released. My results with 2.6.14-rt5 has showed
significant improvement.

What worries me a little is why RTS loaded kernel does print next messages
| imx-mmc imx-mmc.0: busy wait for 16 usec in imxmci_tasklet_fnc data, STATUS = 0xbf40 (0x1000)
I have never seen that before. It could be produced, if there
is some delayed IRQ from previous MMC DMA transfer or some superfluous
IRQ reported to SDHC code. Other possibility is, that new code
has lower latency between IRQ and bottom halves activation.
Other wild theory could be, that there are two subsequent SDHC IRQs
appearing at same time which are now recognized and processed
as two events thanks to updated masking scheme.
If you have idea, what change between 2.6.16 and 2.6.17-rc3-armirq1
can have influence on it, it would not bother me if you can send me a hint.

Lines bellow are my problems for sure and have nothing to do with your changes.
| imx-mmc imx-mmc.0: RESP+DMA TIMEOUT, hardware stucked STATUS = 0xa740 IMASK = 0x0078
| imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0219, MMC_BLK_LEN = 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088
| imx-mmc imx-mmc.0: CMD24 after CMD13, bus 4-bit, dma_size = 0x200

Thanks for your work

Pavel

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Pavel Pisa
2006-05-15 23:58:21 UTC
Permalink
Hello Thomas and Sascha,

there is succeed report for our PiMX1 board.

~ # uname -a
Linux (none) 2.6.17-rc3-armirq7 #14 PREEMPT Mon May 15 03:43:50 CEST 2006 armv4tl unknown

/mnt/mmcsd # cat /proc/interrupts
CPU0
26: 17955455 IMX-uart
29: 256057 IMX-uart
30: 15 IMX-uart
35: 1421445 imx-mmc
59: 722440 i.MX Timer Tick
60: 0 DMA
61: 379348 DMA
113: 9905461 can
155: 228802 eth0
Err: 0
Post by Pavel Pisa
Post by Thomas Gleixner
there was a problem related to IRQ edge polarity in 2.6.17-rc3-armirq1.
Kevin Hilman found it and sent a patch. It's in 2.6.17-rc3-armirq2.
Lines bellow are my problems for sure and have nothing to do with your changes.
| imx-mmc imx-mmc.0: RESP+DMA TIMEOUT, hardware stucked STATUS = 0xa740
| IMASK = 0x0078 imx-mmc imx-mmc.0: CMD_DAT_CONT = 0x0219, MMC_BLK_LEN =
| 0x0200, MMC_NOB = 0x0001, DMA_CCR = 0x00002088 imx-mmc imx-mmc.0: CMD24
| after CMD13, bus 4-bit, dma_size = 0x200
The latest provided SDHC patches seems to solve all reported MMC/SD troubles.

Throughput 1.579 MB/s for SD read and copy over NFS.
Throughput 3.536 MB/s for copy to /dev/null
It would be interesting to compare these to MX1 board
with full 32-bit SDRAM and CPU clock above our default 96 MHz.
I try to retest with 150 and 200 MHz clock on our board some day too.
I would be interested in typical MMC/SD throughputs
of other platforms as well.

GPIO IRQs for CAN and DM9000 working well.

Only catch next ETHERNET drivers very rare complains under overload condition
NETDEV WATCHDOG: eth0: transmit timed out
But I am highly confident, that it is really unrelated to armirq.
This occurred only when board has been tortured with 4 CAN ping threads
running mad without delays and more other load sources
(cat /dev/zero /dev/ttyS0, etc).
Even multiple ping floods did not cause this, if board is not overloaded
by other tests.

Thanks for your work

Pavel

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Richard Purdie
2006-05-07 23:36:14 UTC
Permalink
I just tested 2.6.17-rc3-armirq4 on a PXA270 based Sharp Zaurus C3000.
Compiling failed with:

| CC drivers/rtc/rtc-sa1100.o
| drivers/rtc/rtc-sa1100.c: In function `sa1100_rtc_set_alarm':
| drivers/rtc/rtc-sa1100.c:287: warning: implicit declaration of function `enable_irq_wake'
| drivers/rtc/rtc-sa1100.c:289: warning: implicit declaration of function `disable_irq_wake'

It needs an #include <linux/irq.h>.

I've noticed problems with the CF card insertion detection but this
appears to happen without the irq patch so it looks like a problem
elsewhere.

I also caused an oops on bootup by having an MMC card inserted. If I
don't have the MMC card inserted whilst booting, this doesn't happen. An
insertion after init starts works fine.

Registered led device: spitz:amber
Registered led device: spitz:green
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
Probing IDE interface ide0...
mmcblk0: mmc0:a95c SD128 123008KiB
mmcblk0:<2>kernel BUG at kernel/posix-cpu-timers.c:1279!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 8f5 [#1]
Modules linked in:
CPU: 0
PC is at __bug+0x40/0x54
LR is at 0x1
pc : [<c0020268>] lr : [<00000001>] Not tainted
sp : c01fde24 ip : 60000093 fp : c01fde34
r10: c01fdf58 r9 : 00000017 r8 : 00000000
r7 : c01fdf58 r6 : c0201608 r5 : 00000000 r4 : 00000000
r3 : 00000000 r2 : 00010004 r1 : c01fc000 r0 : 00000001
Flags: nZCv IRQs on FIQs on Mode SVC_32 Segment kernel
Control: 397F Table: A0004000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc01fc1a0)
Stack: (0xc01fde24 to 0xc01fe000)
de20: c0201608 c01fde88 c01fde38 c004ec18 c0020234 c01fde44 c0032b48
de40: c0201608 c01fde88 c01fde54 c0032698 c001fbf4 c01fc000 c01fde58 c01fde58
de60: c0201608 00000000 c024f210 c01fdf58 00000000 00000017 c01fdf58 c01fdea0
de80: c01fde8c c0041478 c004eb68 c01fdf58 c024f210 c01fdebc c01fdea4 c001ff90
dea0: c004141c c01fc000 c024f210 c024f210 c01fdedc c01fdec0 c00280dc c001fed4
dec0: 00000000 c3cea280 c024f210 00000000 c01fdef0 c01fdee0 c00281fc c0028084
dee0: c01fc000 c01fdf1c c01fdef4 c0057c58 c00281c0 c01fc000 c01fe600 00000017
df00: c3cea280 c01fdf58 c01fc000 a0018c04 c01fdf40 c01fdf20 c0057e48 c0057bc8
df20: c01fc000 c01fdf8c 00800000 00000002 00000001 c01fdf54 c01fdf44 c001c6ec
df40: c0057dbc ffffffff c01fdfac c01fdf58 c001b9d8 c001c6b0 00000001 005fb5f4
df60: 00000000 60000013 c001c9c4 c01fc000 c0202404 c0260fa0 a0018c9c 69054114
df80: a0018c04 c01fdfac f2a00000 c01fdfa0 c001ca0c c001ca18 60000013 ffffffff
dfa0: c01fdfc4 c01fdfb0 c001ca68 c001c9d0 c01fc000 c0249224 c01fdfd8 c01fdfc8
dfc0: c001b048 c001ca2c c0251a24 c01fdff4 c01fdfdc c00087fc c001b00c c00082e4
dfe0: c0249288 0000397d 00000000 c01fdff8 a0008030 c0008668 00000000 00000000
Backtrace:
[<c0020228>] (__bug+0x0/0x54) from [<c004ec18>] (run_posix_cpu_timers+0xbc/0x82) r4 = C0201608
[<c004eb5c>] (run_posix_cpu_timers+0x0/0x820) from [<c0041478>] (update_process)[<c0041410>] (update_process_times+0x0/0x6c) from [<c001ff90>] (timer_tick+0xc8) r5 = C024F210 r4 = C01FDF58
[<c001fec8>] (timer_tick+0x0/0xe4) from [<c00280dc>] (pxa_timer_interrupt+0x64/) r6 = C024F210 r5 = C024F210 r4 = C01FC000
[<c0028078>] (pxa_timer_interrupt+0x0/0xd8) from [<c00281fc>] (pxa_dyn_tick_han) r7 = 00000000 r6 = C024F210 r5 = C3CEA280 r4 = 00000000
[<c00281b4>] (pxa_dyn_tick_handler+0x0/0x5c) from [<c0057c58>] (handle_IRQ_even) r4 = C01FC000
[<c0057bbc>] (handle_IRQ_event+0x0/0x118) from [<c0057e48>] (handle_level_irq+0)[<c0057db0>] (handle_level_irq+0x0/0xec) from [<c001c6ec>] (asm_do_IRQ+0x48/0x7) r8 = 00000001 r7 = 00000002 r6 = 00800000 r5 = C01FDF8C
r4 = C01FC000
[<c001c6a4>] (asm_do_IRQ+0x0/0x70) from [<c001b9d8>] (__irq_svc+0x38/0x70)
r4 = FFFFFFFF
[<c001c9c4>] (default_idle+0x0/0x5c) from [<c001ca68>] (cpu_idle+0x48/0x84)
[<c001ca20>] (cpu_idle+0x0/0x84) from [<c001b048>] (__init_end+0x48/0x50)
r5 = C0249224 r4 = C01FC000
[<c001b000>] (__init_end+0x0/0x50) from [<c00087fc>] (start_kernel+0x1a0/0x1e8)
r4 = C0251A24
[<c000865c>] (start_kernel+0x0/0x1e8) from [<a0008030>] (0xa0008030)
r4 = 0000397D
Code: 1b005e1d e59f0014 eb005e1b e3a03000 (e5833000)
<0>Kernel panic - not syncing: Aiee, killing interrupt handler!
--
Richard





-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-08 07:05:16 UTC
Permalink
Richard,
Post by Richard Purdie
I just tested 2.6.17-rc3-armirq4 on a PXA270 based Sharp Zaurus C3000.
| CC drivers/rtc/rtc-sa1100.o
| drivers/rtc/rtc-sa1100.c:287: warning: implicit declaration of function `enable_irq_wake'
| drivers/rtc/rtc-sa1100.c:289: warning: implicit declaration of function `disable_irq_wake'
It needs an #include <linux/irq.h>.
I think moving xxx_irq_wake declarations to linux/interrupt.h is the
correct solution.
Post by Richard Purdie
I've noticed problems with the CF card insertion detection but this
appears to happen without the irq patch so it looks like a problem
elsewhere.
I also caused an oops on bootup by having an MMC card inserted. If I
don't have the MMC card inserted whilst booting, this doesn't happen. An
insertion after init starts works fine.
It's not related to the mmc card. Can you try the patch below ?

Thanks

tglx



Index: linux-2.6.17-rc3/kernel/irq/handle.c
===================================================================
--- linux-2.6.17-rc3.orig/kernel/irq/handle.c
+++ linux-2.6.17-rc3/kernel/irq/handle.c
@@ -226,9 +248,6 @@ fastcall int handle_IRQ_event(unsigned i
{
int ret, retval = 0, status = 0;

- if (!(action->flags & SA_INTERRUPT))
- local_irq_enable();
-
#if defined(CONFIG_NO_IDLE_HZ) && defined(CONFIG_ARM)
if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
write_seqlock(&xtime_lock);
@@ -238,6 +257,9 @@ fastcall int handle_IRQ_event(unsigned i
}
#endif

+ if (!(action->flags & SA_INTERRUPT))
+ local_irq_enable();
+
do {
ret = action->handler(irq, action->dev_id, regs);
if (ret == IRQ_HANDLED)



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Richard Purdie
2006-05-08 08:37:41 UTC
Permalink
Post by Thomas Gleixner
Post by Richard Purdie
I've noticed problems with the CF card insertion detection but this
appears to happen without the irq patch so it looks like a problem
elsewhere.
I also caused an oops on bootup by having an MMC card inserted. If I
don't have the MMC card inserted whilst booting, this doesn't happen. An
insertion after init starts works fine.
It's not related to the mmc card. Can you try the patch below ?
With that patch applied, I can't generate the oops.

Thanks,

Richard



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Richard Purdie
2006-05-09 08:01:59 UTC
Permalink
I updated to 2.6.17-rc3-armirq5 and the previous issues I mentioned are
fixed, thanks.

I was trying to debug that CF memory card issue I mentioned and found
further problems which I've isolated to the irq patch. Basically, if I
insert my spectrum_cs CF wifi card I get the oops below. It appears that
the PCMCIA irq isn't getting freed properly.

The firmware upload failure is irrelevant as this happens without the
irq patch (probably my recent udev upgrade broke things). When
spectrum_cs fails, it tries hostap_cs. It looks like IRQ resources
aren't getting freed so the subsequent driver can't access the resource,
triggering an oops in the case of hostap_cs (bad error handling?).

I then got a similar oops and RequestIRQ messages if I insert my
hostap_cs card, remove it and insert it again.

Without the irq patch, I don't see any of the "1.0: RequestIRQ: Resource
in use" errors or this oops.

Richard

pccard: PCMCIA card inserted into slot 1
pcmcia: registering new device pcmcia1.0
orinoco 0.15rc3 (David Gibson <***@gibson.dropbear.id.au>, Pavel Roskin <***@gnu.org>, et al)
spectrum_cs 0.15rc3 (Pavel Roskin <***@gnu.org>, David Gibson <***@gibson.dropbear.id.au>, et al)
spectrum_cs: Primary firmware download failed
spectrum_cs: Firmware download failed
eth0: failed to initialize firmware (err = -16)
spectrum_cs: register_netdev() failed
1.0: RequestIRQ: Resource in use
pccard: card ejected from slot 1
pccard: PCMCIA card inserted into slot 1
pcmcia: registering new device pcmcia1.0
orinoco_cs 0.15rc3 (David Gibson <***@gibson.dropbear.id.au>, Pavel Roskin <***@gnu.org>, et al)
1.0: RequestIRQ: Resource in use
ieee80211_crypt: registered algorithm 'NULL'
hostap_cs: 0.4.4-kernel (Jouni Malinen <***@cc.hut.fi>)
hostap_cs: setting Vcc=33 (constant)
Checking CFTABLE_ENTRY 0x01 (default 0x01)
IO window settings: cfg->io.nwin=1 dflt.io.nwin=1
io->flags = 0x0046, io.base=0x0000, len=64
hostap_cs: Registered netdevice wifi0
1.0: RequestIRQ: Resource in use
Unable to handle kernel NULL pointer dereference at virtual address 00000032
pgd = c18e4000
[00000032] *pgd=a1b85031, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1]
Modules linked in: hostap_cs hostap ieee80211_crypt orinoco_cs spectrum_cs orinoco hermes uinput ohci_hcd usbcore mousedev snd_soc_spitz snd_soc_pxa2xx_i2s snd_soc_wm8750 snd_soc_pxa2xx snd_soc_core snd_pcm_oss snd_pcm snd_timer snd_page_alloc snd_mixer_oss snd soundcore rfcomm pxaficp_ir ircomm_tty ircomm irda ipv6 hidp l2cap bluetooth
CPU: 0
PC is at hfa384x_events_only_cmd+0x14/0x1c [hostap_cs]
LR is at prism2_hw_shutdown+0x20/0xc8 [hostap_cs]
pc : [<bf148d88>] lr : [<bf149040>] Not tainted
sp : c1491b50 ip : c1491b60 fp : c1491b5c
r10: c3267e00 r9 : 00000000 r8 : c145c000
r7 : 0000001e r6 : 00000000 r5 : c145c344 r4 : c145c000
r3 : 00000000 r2 : 00000010 r1 : 00000000 r0 : c145c000
Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment user
Control: 397F Table: A18E4000 DAC: 00000015
Process modprobe (pid: 3522, stack limit = 0xc14901a0)
Stack: (0xc1491b50 to 0xc1492000)
1b40: c1491b7c c1491b60 bf149040 bf148d80
1b60: c1491b7c c145c260 c3267800 c3267800 c1491b94 c1491b80 bf14e06c bf14902c
1b80: 0000002e c145c344 c1491e74 c1491b98 bf14f014 bf14e04c 000200d2 c020719c
1ba0: c145c260 c326788c c2314a20 00000001 c145c344 c005f1d4 c005ecec 000200d2
1bc0: 00000000 c1491be4 c1491bd4 c028bce0 a14e70ff c3a0bf94 00000064 c1490000
1be0: c3bcd960 40019000 c1491c58 c1491bf8 c0068f08 c00229b4 c0031c10 c03bed60
1c00: c1491db0 c1491d84 0098966f 0098966f c1491dac c0249d48 c1491dac c1d78864
1c20: 00000000 c18e5000 00016401 00000301 00000077 00050910 000493e0 00057e40
1c40: 74736f00 002dc6c0 002dc6c0 000186a0 64646100 56454400 48544150 75622f3d
1c60: 63702f73 6169636d 6972642f 73726576 736f6800 5f706174 53007363 59534255
1c80: 4d455453 6972643d 73726576 51455300 00000000 00383335 00000000 312f6169
1ca0: 00000000 59534255 00000146 00000000 00000040 00000000 00000000 00000000
1cc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1ce0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1d20: 00000000 00000000 00000000 000000ff 0000ffff 00000000 00000000 00000000
1d40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1d60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c03bed00
1da0: 00000000 00000021 00000021 00000021 c1491dbc c0031ed4 c0031cc4 0098966f
1dc0: c0249d78 00000000 c1491e20 c1491dd8 c01c6f6c c0031dbc c0393078 c1490000
1de0: c3ffe8e0 c3ffe8e0 00000000 771901c1 b5351eb5 0536363c ffffff46 c3ffe8e0
1e00: 00000000 c1491e24 c1490000 60000013 00000000 00000000 c1491e50 c0336c00
1e20: c3ffe8e0 c1491e4c c1491e34 00000000 c0032b1b 00000110 00000000 00000074
1e40: 4000101b c1491e10 c1491dec c3267800 bf155df8 c326788c 00000000 00000001
1e60: c1490000 00000000 c1491e98 c1491e78 c014bffc bf14e2d8 c326788c c014bf30
1e80: 00000000 bf155e10 ffffffff c1491eb8 c1491e9c c012a030 c014bf3c c3267958
1ea0: c326788c c012a150 bf155e10 c1491ed0 c1491ebc c012a1d0 c0129fdc 00000000
1ec0: c1491ed4 c1491efc c1491ed4 c01294d0 c012a15c c0214290 c0214290 c32678d4
1ee0: bf155e24 bf155e10 bf155c14 c0214190 c1491f0c c1491f00 c012a250 c012948c
1f00: c1491f34 c1491f10 c0129a38 c012a23c bf155e10 bf155df8 bf155c14 bf155bf0
1f20: ffffffff 00000000 c1491f4c c1491f38 c012a75c c01299d8 00000080 00000000
1f40: c1491f74 c1491f50 c014be6c c012a6d0 c0037af0 00012a6e bf155f00 00000000
1f60: 00000080 c001bf84 c1491f84 c1491f78 bf158028 c014bd98 c1491fa4 c1491f88
1f80: c0054158 bf15800c 0000941c 00000000 00000000 00000080 00000000 c1491fa8
1fa0: c001bde0 c005409c 0000941c 00000000 40144000 00012a6e 00016570 00016570
1fc0: 0000941c 00000000 00000000 00000000 000164b8 000160e8 00000000 000164c4
1fe0: 00015100 be9eea5c 0000a434 400e642c 60000010 40144000 3d3b3d3b 3d3b3d3b
Backtrace:
[<bf148d74>] (hfa384x_events_only_cmd+0x0/0x1c [hostap_cs]) from [<bf149040>] (prism2_hw_shutdown+0x20/0xc8 [hostap_cs])
[<bf149020>] (prism2_hw_shutdown+0x0/0xc8 [hostap_cs]) from [<bf14e06c>] (prism2_release+0x2c/0x44 [hostap_cs])
r6 = C3267800 r5 = C3267800 r4 = C145C260
[<bf14e040>] (prism2_release+0x0/0x44 [hostap_cs]) from [<bf14f014>] (hostap_cs_probe+0xd48/0xeb4 [hostap_cs])
r5 = C145C344 r4 = 0000002E
[<bf14e2cc>] (hostap_cs_probe+0x0/0xeb4 [hostap_cs]) from [<c014bffc>] (pcmcia_device_probe+0xcc/0x1ac)
[<c014bf30>] (pcmcia_device_probe+0x0/0x1ac) from [<c012a030>] (driver_probe_device+0x60/0xd4)
r8 = FFFFFFFF r7 = BF155E10 r6 = 00000000 r5 = C014BF30
r4 = C326788C
[<c0129fd0>] (driver_probe_device+0x0/0xd4) from [<c012a1d0>] (__driver_attach+0x80/0xe0)
r7 = BF155E10 r6 = C012A150 r5 = C326788C r4 = C3267958
[<c012a150>] (__driver_attach+0x0/0xe0) from [<c01294d0>] (bus_for_each_dev+0x50/0x84)
r5 = C1491ED4 r4 = 00000000
[<c0129480>] (bus_for_each_dev+0x0/0x84) from [<c012a250>] (driver_attach+0x20/0x28)
r7 = C0214190 r6 = BF155C14 r5 = BF155E10 r4 = BF155E24
[<c012a230>] (driver_attach+0x0/0x28) from [<c0129a38>] (bus_add_driver+0x6c/0x134)
[<c01299cc>] (bus_add_driver+0x0/0x134) from [<c012a75c>] (driver_register+0x98/0xa8)
[<c012a6c4>] (driver_register+0x0/0xa8) from [<c014be6c>] (pcmcia_register_driver+0xe0/0xf4)
r4 = 00000000
[<c014bd8c>] (pcmcia_register_driver+0x0/0xf4) from [<bf158028>] (init_prism2_pccard+0x28/0x3c [hostap_cs])
r8 = C001BF84 r7 = 00000080 r6 = 00000000 r5 = BF155F00
r4 = 00012A6E
[<bf158000>] (init_prism2_pccard+0x0/0x3c [hostap_cs]) from [<c0054158>] (sys_init_module+0xc8/0x20c)
[<c0054090>] (sys_init_module+0x0/0x20c) from [<c001bde0>] (ret_fast_syscall+0x0/0x2c)
r7 = 00000080 r6 = 00000000 r5 = 00000000 r4 = 0000941C
Code: e92dd800 e24cb004 e5903020 e3a02010 (e1c323b2)






-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-27 17:10:32 UTC
Permalink
Post by Russell King - ARM Linux
We require people's help on this list concerning these patches. The
http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patches.tar.bz2
(please check for later versions!
I'm going to rebase the patches on 2.6.17-rc3 tonight.
Post by Russell King - ARM Linux
- note though that www.tglx.de's isp is
having issues atm.)
Should be fixed by now, but I will mirror the patches to kernel.org
later tonight.
Post by Russell King - ARM Linux
Oh, and we need a willing victim^Wvolunteer to track preferably both the
testing folk do and the results.
I guess I'm the vi^Holunteer.

I have setup a page on my website to track the results.
http://www.linutronix.de/index.php?page=46

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-04-28 15:59:11 UTC
Permalink
Post by Thomas Gleixner
I have setup a page on my website to track the results.
http://www.linutronix.de/index.php?page=46
A new set of patches against -rc3 is available at
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq1.patches.tar.bz2

Changes since -rc1-armirq5

- request_irq SA_TRIGGER_XXX functionality fixed

- arch/arm/common/gic.c locking fixed
Russell, can you please review those? I have no access to ARM SMP

tglx




-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Lennert Buytenhek
2006-04-28 22:44:34 UTC
Permalink
Post by Thomas Gleixner
I'm going to rebase the patches on 2.6.17-rc3 tonight.
2.6.17-rc3-armirq1 boots fine on an enp2611 (ixp2400) and seems to
work fine otherwise. I'll put some more load on it and let you know
about the results.

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Marc Singer
2006-04-27 19:00:15 UTC
Permalink
Post by Russell King - ARM Linux
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
[deletia]
Post by Russell King - ARM Linux
1. These patches can be tested by a large number of folk prior to merging,
and confidence in the patch can be gained, and any issues fixed. Then
we can merge them into 2.6.17 with reasonable confidence that they
should cause minimal (if any) instability.
2. I can merge them as is after 2.6.17, and then you will have to debug
any stability issues when you upgrade to later kernels.
I don't know about most people, but I think (1) is a far better way of
proceeding. So, if you're reading this _and_ you're involved in platform
development, please try running these patches on your board and reporting
success and failure stories.
This sounds like a reasonable course. Unfortunately, the exigencies
of my schedule make it unlikely that I'll be able to look at this in
the next month.


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Adam Brooks
2006-04-28 00:05:29 UTC
Permalink
I will test the changes out for the IOP3xx boards.

-Adam Brooks
Post by Marc Singer
Post by Russell King - ARM Linux
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
[deletia]
Post by Russell King - ARM Linux
1. These patches can be tested by a large number of folk prior to merging,
and confidence in the patch can be gained, and any issues fixed. Then
we can merge them into 2.6.17 with reasonable confidence that they
should cause minimal (if any) instability.
2. I can merge them as is after 2.6.17, and then you will have to debug
any stability issues when you upgrade to later kernels.
I don't know about most people, but I think (1) is a far better way of
proceeding. So, if you're reading this _and_ you're involved in platform
development, please try running these patches on your board and reporting
success and failure stories.
This sounds like a reasonable course. Unfortunately, the exigencies
of my schedule make it unlikely that I'll be able to look at this in
the next month.
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Kevin Hilman
2006-04-28 22:07:53 UTC
Permalink
Post by Russell King - ARM Linux
Post by Thomas Gleixner
Our patchset, which converts ARM to the generic irq subsystem has
reached a stable state and we ask for inclusion.
We require people's help on this list concerning these patches. The
http://www.tglx.de/projects/armirq/
http://www.tglx.de/projects/armirq/2.6.17-rc1/patch-2.6.17-rc1-armirq5.patches.tar.bz2
(please check for later versions! - note though that www.tglx.de's isp is
having issues atm.)
I am testing these on OMAP.

First pass shows that smc91x interrupts are getting lost. They are GPIO
interrupts on most OMAP platforms and pass through a chained gpio handler. I'm
still investigating, but I'm guessing it as something to do with SA_TRIGGER_*
flags used in the smc91x driver for OMAP.

I don't see handling of SA_TRIGGER_* in the generic layer. Is there a new way
of handling these?

Kevin
Thomas Gleixner
2006-04-28 22:38:46 UTC
Permalink
R am testing these on OMAP.
First pass shows that smc91x interrupts are getting lost. They are GPIO
interrupts on most OMAP platforms and pass through a chained gpio handler. I'm
still investigating, but I'm guessing it as something to do with SA_TRIGGER_*
flags used in the smc91x driver for OMAP.
I don't see handling of SA_TRIGGER_* in the generic layer. Is there a new way
of handling these?
No. That chunk got lost unfortunately. Can you retry with the new patch
against -rc3 please ?

http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq1.patches.tar.bz2

Thanks,

tglx


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Kevin Hilman
2006-04-28 23:17:22 UTC
Permalink
Post by Thomas Gleixner
R am testing these on OMAP.
First pass shows that smc91x interrupts are getting lost. They are GPIO
interrupts on most OMAP platforms and pass through a chained gpio handler. I'm
still investigating, but I'm guessing it as something to do with SA_TRIGGER_*
flags used in the smc91x driver for OMAP.
I don't see handling of SA_TRIGGER_* in the generic layer. Is there a new way
of handling these?
No. That chunk got lost unfortunately. Can you retry with the new patch
against -rc3 please ?
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq1.patches.tar.bz2
ok, I tried with -rc3 and I still dont see any GPIO interrupts.

After looking closer at the IRQ_TYPE_* flags, I noticed that they didn't match
the SA_TRIGGER_* flags for _FALLING or _RISING. The following patch swaps the
two and make OMAP happy. It's now booting, and things seem sane. Will do some
more intensive testing

Kevin



Index: linux-omap-2.6/include/linux/irq.h
===================================================================
--- linux-omap-2.6.orig/include/linux/irq.h
+++ linux-omap-2.6/include/linux/irq.h
@@ -39,8 +39,8 @@
* IRQ types, see also include/linux/interrupt.h
*/
#define IRQ_TYPE_NONE 0x0000 /* Default, unspecified type */
-#define IRQ_TYPE_EDGE_FALLING 0x0001 /* Edge falling type */
-#define IRQ_TYPE_EDGE_RISING 0x0002 /* Edge rising type */
+#define IRQ_TYPE_EDGE_RISING 0x0001 /* Edge rising type */
+#define IRQ_TYPE_EDGE_FALLING 0x0002 /* Edge falling type */
#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH 0x0004 /* Level high type */
#define IRQ_TYPE_LEVEL_LOW 0x0008 /* Level low type */
Thomas Gleixner
2006-04-29 10:08:28 UTC
Permalink
Post by Kevin Hilman
ok, I tried with -rc3 and I still dont see any GPIO interrupts.
After looking closer at the IRQ_TYPE_* flags, I noticed that they didn't match
the SA_TRIGGER_* flags for _FALLING or _RISING. The following patch swaps the
two and make OMAP happy. It's now booting, and things seem sane. Will do some
more intensive testing
Kevin
Sigh. I knew I'd screw that one up.

Applied and released -rc3-armirq2.

Thanks,

tglx
Post by Kevin Hilman
Index: linux-omap-2.6/include/linux/irq.h
===================================================================
--- linux-omap-2.6.orig/include/linux/irq.h
+++ linux-omap-2.6/include/linux/irq.h
@@ -39,8 +39,8 @@
* IRQ types, see also include/linux/interrupt.h
*/
#define IRQ_TYPE_NONE 0x0000 /* Default, unspecified type */
-#define IRQ_TYPE_EDGE_FALLING 0x0001 /* Edge falling type */
-#define IRQ_TYPE_EDGE_RISING 0x0002 /* Edge rising type */
+#define IRQ_TYPE_EDGE_RISING 0x0001 /* Edge rising type */
+#define IRQ_TYPE_EDGE_FALLING 0x0002 /* Edge falling type */
#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH 0x0004 /* Level high type */
#define IRQ_TYPE_LEVEL_LOW 0x0008 /* Level low type */
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Tony Lindgren
2006-05-02 11:59:15 UTC
Permalink
Post by Thomas Gleixner
Post by Kevin Hilman
ok, I tried with -rc3 and I still dont see any GPIO interrupts.
After looking closer at the IRQ_TYPE_* flags, I noticed that they didn't match
the SA_TRIGGER_* flags for _FALLING or _RISING. The following patch swaps the
two and make OMAP happy. It's now booting, and things seem sane. Will do some
more intensive testing
Kevin
Sigh. I knew I'd screw that one up.
Applied and released -rc3-armirq2.
Patches seem to work for me too on various omap boards. Also dyntick
works.

Should this part in kernel/irq/handle.c be CONFIG_ARM for now?

@@ -84,6 +229,15 @@ fastcall int handle_IRQ_event(unsigned i
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();

+#if defined(CONFIG_NO_IDLE_HZ)
+ if (!(action->flags & SA_TIMER) && system_timer->dyn_tick !=
NULL) {
+ write_seqlock(&xtime_lock);
+ if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+ system_timer->dyn_tick->handler(irq, 0, regs);
+ write_sequnlock(&xtime_lock);
+ }
+#endif
+
do {
ret = action->handler(irq, action->dev_id, regs);
if (ret == IRQ_HANDLED)

Regards,

Tony
Thomas Gleixner
2006-05-02 12:33:10 UTC
Permalink
Post by Tony Lindgren
Post by Thomas Gleixner
Applied and released -rc3-armirq2.
Patches seem to work for me too on various omap boards. Also dyntick
works.
Thanks for testing.
Post by Tony Lindgren
Should this part in kernel/irq/handle.c be CONFIG_ARM for now?
Yes, until we find a unified solution for dynamic ticks.

tglx




-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Adam Brooks
2006-05-02 18:18:23 UTC
Permalink
Everything appears to be working on the IOP3xx boards. There is one
thing I would like to confirm. None of the patches changed anything
in the mach-iop3xx directory. Was this because no changes were
required, or is our arch not actually using the new mechanism at this
point?

-Adam Brooks
Post by Thomas Gleixner
Post by Tony Lindgren
Post by Thomas Gleixner
Applied and released -rc3-armirq2.
Patches seem to work for me too on various omap boards. Also dyntick
works.
Thanks for testing.
Post by Tony Lindgren
Should this part in kernel/irq/handle.c be CONFIG_ARM for now?
Yes, until we find a unified solution for dynamic ticks.
tglx
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-02 19:16:26 UTC
Permalink
Adam,
Post by Adam Brooks
Everything appears to be working on the IOP3xx boards. There is one
thing I would like to confirm. None of the patches changed anything
in the mach-iop3xx directory. Was this because no changes were
required, or is our arch not actually using the new mechanism at this
point?
The arch is using the new mechanism, but there are no changes required
as it does not set up multiplexed (chained) handlers.

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Nicolas Pitre
2006-05-05 21:35:08 UTC
Permalink
I finally got remote access to a PXA-Mainstone board and fixed a subtle
problem with the PXA-style interrupt init handling.
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq3.patch
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq3.patches.tar.bz2
- Fix PXA irq handler overloading (e.g. IRQ_GPIO(0) in mainstone.c)
I see only one line added by your patch to mainstone.c (well 2 lines
with the blank line):

+static DEFINE_IRQ_CHAINED_TYPE(mainstone_irq_handler);

I tested with a Lubbock (I no longer have a working Mainstone) and,
although most things work as expected, even the chained IRQs like for
the SMC91C96 chip, the UCB1400 fails to probe its IRQ. Without your
patch it is fine. The ucb1x00_detect_irq() in
drivers/mfd/ucb1x00-core.c fails with your patch applied but succeeds
otherwise.


Nicolas

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-06 11:03:44 UTC
Permalink
Post by Nicolas Pitre
I tested with a Lubbock (I no longer have a working Mainstone) and,
although most things work as expected, even the chained IRQs like for
the SMC91C96 chip, the UCB1400 fails to probe its IRQ. Without your
patch it is fine. The ucb1x00_detect_irq() in
drivers/mfd/ucb1x00-core.c fails with your patch applied but succeeds
otherwise.
The patch below should fix that.

Thanks
tglx

Index: linux-2.6.17-rc3/arch/arm/Kconfig
===================================================================
--- linux-2.6.17-rc3.orig/arch/arm/Kconfig 2006-05-06 11:00:07.000000000 +0000
+++ linux-2.6.17-rc3/arch/arm/Kconfig 2006-05-06 10:59:43.000000000 +0000
@@ -51,6 +51,10 @@
bool
default y

+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
default y



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Nicolas Pitre
2006-05-06 17:16:01 UTC
Permalink
Post by Thomas Gleixner
Post by Nicolas Pitre
I tested with a Lubbock (I no longer have a working Mainstone) and,
although most things work as expected, even the chained IRQs like for
the SMC91C96 chip, the UCB1400 fails to probe its IRQ. Without your
patch it is fine. The ucb1x00_detect_irq() in
drivers/mfd/ucb1x00-core.c fails with your patch applied but succeeds
otherwise.
The patch below should fix that.
Advanced Linux Sound Architecture Driver Version 1.0.11rc4 (Wed Mar 22 10:27:24 2006 UTC).
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000 [00000000] *pgd=00000000
Internal error: Oops: 0 [#1]
Modules linked in:
CPU: 0
PC is at __init_begin+0x3fff8000/0x30
LR is at probe_irq_on+0x68/0x174
pc : [<00000000>] lr : [<c004fbb8>] Not tainted
[...]
Backtrace:
[<c004fb50>] (probe_irq_on+0x0/0x174) from [<c0117b0c>] (ucb1x00_probe+0xd4/0x350)

So there's a missing function pointer initialization missing somewhere.


Nicolas

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-08 14:49:45 UTC
Permalink
Post by Nicolas Pitre
So there's a missing function pointer initialization missing somewhere.
Correct. Can you please retest with -armirq5 ?

http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq5.patch
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq5.patches.tar.bz2

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Nicolas Pitre
2006-05-08 18:11:15 UTC
Permalink
Post by Thomas Gleixner
Post by Nicolas Pitre
So there's a missing function pointer initialization missing somewhere.
Correct. Can you please retest with -armirq5 ?
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq5.patch
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq5.patches.tar.bz2
Works fine now.


Nicolas

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-08 18:22:07 UTC
Permalink
Nico,
Post by Nicolas Pitre
Works fine now.
Thanks for testing.

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Egan, Tony
2006-05-05 14:35:28 UTC
Permalink
The Atmel AT91RM9200-EK using an NFS mounted RFS and primarily exercising eth0
appears to be stable.


-bash-2.05b# uname -a
Linux timesys-bsp 2.6.17-rc3-armirq2 #39 PREEMPT Tue May 2 16:08:07 EDT 2006 arx
-bash-2.05b# cat /proc/interrupts
CPU0
1: 6120292 at91_tick, at91_serial
10: 6 at91_mci
11: 0 at91_udc
23: 0 ohci_hcd:usb1
24: 1542719 eth0
91: 1 at91_mci
100: 1 eth0
132: 0 at91_udc
Err: 0
--
Regards,
Tony






-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Thomas Gleixner
2006-05-10 06:17:34 UTC
Permalink
Post by Richard Purdie
The firmware upload failure is irrelevant as this happens without the
irq patch (probably my recent udev upgrade broke things). When
spectrum_cs fails, it tries hostap_cs. It looks like IRQ resources
aren't getting freed so the subsequent driver can't access the resource,
triggering an oops in the case of hostap_cs (bad error handling?).
The oops happens due to missing error handling somewhere in the drivers.
The thinko in the armirq patch which led to this problem is fixed.

Latest version at:
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq6.patch
http://www.tglx.de/projects/armirq/2.6.17-rc3/patch-2.6.17-rc3-armirq6.patches.tar.bz2

Richard, thanks for your testing/debugging.

tglx



-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Continue reading on narkive:
Loading...