diff -urN --exclude=.hg linux-2.6.12/Documentation/DocBook/Makefile linux-2.6.12-armirq/Documentation/DocBook/Makefile
--- linux-2.6.12/Documentation/DocBook/Makefile 2005-07-18 15:41:22.000000000 +0200
+++ linux-2.6.12-armirq/Documentation/DocBook/Makefile 2005-07-13 14:34:11.000000000 +0200
@@ -10,7 +10,7 @@
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml scsidrivers.xml \
sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml
+ gadget.xml libata.xml mtdnand.xml librs.xml genericirq.xml
###
# The build process is as follows (targets):
diff -urN --exclude=.hg linux-2.6.12/Documentation/DocBook/genericirq.tmpl linux-2.6.12-armirq/Documentation/DocBook/genericirq.tmpl
--- linux-2.6.12/Documentation/DocBook/genericirq.tmpl 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12-armirq/Documentation/DocBook/genericirq.tmpl 2005-07-13 14:34:11.000000000 +0200
@@ -0,0 +1,559 @@
+
+
+
+
+ Linux generic IRQ handling
+
+
+
+ Thomas
+ Gleixner
+
+
+ tglx@linutronix.de
+
+
+
+
+ Ingo
+ Molnar
+
+
+ mingo@elte.hu
+
+
+
+
+
+
+ 2005
+ Thomas Gleixner
+
+
+ 2005
+ Ingo Molnar
+
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+ 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
+
+
+
+ For more details see the file COPYING in the source
+ distribution of Linux.
+
+
+
+
+
+
+
+ Introduction
+
+ 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.
+
+
+ This documentation is provided for developers who want to implement
+ architecture interrupt support based on the Generic IRQ handling layer.
+
+
+
+
+ Rationale
+
+ 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.
+
+
+ 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:
+
+ Level type
+ Edge type
+ Simple type
+
+ In the SMP world of the __do_IRQ() super-handler another type
+ was identified:
+
+ Per CPU type
+
+
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+
+ Known Bugs And Assumptions
+
+ None (hopefully).
+
+
+
+
+ Abstraction layers
+
+ There are three main levels of abstraction in the interrupt code:
+
+ Highlevel driver API
+ Abstract interrupt type
+ Chiplevel hardware encapsulation
+
+
+
+ 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.
+
+
+ Interrupt control flow
+
+ 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.
+
+
+ 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.
+
+
+
+ Highlevel Driver API
+
+ The highlevel Driver API consists of following functions:
+
+ request_irq()
+ free_irq()
+ disable_irq()
+ enable_irq()
+ disable_irq_nosync() (SMP only)
+ synchronize_irq() (SMP only)
+ set_irq_type()
+ set_irq_wake()
+ set_irq_data()
+ set_irq_chip()
+ set_irq_chip_data()
+
+ See the autogenerated function documentation for details.
+
+
+
+ Abstract interrupt type
+
+ 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:
+
+ default_level_type
+ default_edge_type
+ default_simple_type
+ default_percpu_type
+
+ The default type implementations use the generic type handlers.
+
+ handle_level_type
+ handle_edge_type
+ handle_simple_type
+ handle_percpu_type
+
+ The interrupt types (either predefined or architecture specific) are
+ assigned to specific interrupts by the architecture either during
+ bootup or during device initialization.
+
+
+ Default type implementations
+
+ Helper functions
+
+ The helper functions call the chip primitives and
+ are used by the default type implementations.
+ Following helper functions are implemented (simplified excerpt):
+
+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;
+}
+
+
+
+
+ Default Level IRQ type
+
+ The default Level IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_mask_ack
+ enddefault_enable
+ handle_irqhandle_level_irq
+ set_typedefault_set_type
+
+
+
+
+ Default Edge IRQ type
+
+ The default Edge IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_ack
+ holddefault_mask_ack
+ endnoop
+ handle_irqhandle_edge_irq
+ set_typedefault_set_type
+
+
+
+
+ Default simple IRQ type
+
+ The default simple IRQ type implements the functions
+
+ enablenoop
+ disablenoop
+ handle_irqhandle_simple_irq
+
+
+
+
+ Default per CPU IRQ type
+
+ The default per CPU IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_ack
+ enddefault_enable
+ handle_irqhandle_percpu_irq
+
+
+
+
+
+ Default type handler implementations
+
+ Default Level IRQ type handler
+
+ handle_level_type provides a generic implementation
+ for level type interrupts.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+
+
+
+
+ Default Edge IRQ type handler
+
+ handle_edge_type provides a generic implementation
+ for edge type interrupts.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+if (desc->status & running) {
+ desc->handler->hold();
+ desc->status |= pending | masked;
+ return;
+}
+desc->handler->start();
+desc->status |= running;
+do {
+ if (desc->status & masked)
+ desc->handler->enable();
+ desc-status &= ~pending;
+ handle_IRQ_event(desc->action);
+} while (status & pending);
+desc-status &= ~running;
+desc->handler->end();
+
+
+
+
+ Default simple IRQ type handler
+
+ handle_simple_type provides a generic implementation
+ for simple type interrupts.
+
+
+ Note: The simple type handler does not call any
+ handler/chip primitives.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+handle_IRQ_event(desc->action);
+
+
+
+
+ Default per CPU type handler
+
+ handle_percpu_type provides a generic implementation
+ for per CPU type interrupts.
+
+
+ Per CPU interrupts are only available on SMP and
+ the handler provides a simplified version without
+ locking.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+
+
+
+
+
+ Architecture specific type implementation
+
+ If an architecture needs to implement its own type structures, then
+ the following primitives have to be implemented:
+
+ handle_irq() - The handle_irq function pointer should preferably point to
+ one of the generic type handler functions
+ startup() - Optional
+ shutdown() - Optional
+ enable()
+ disable()
+ start()
+ hold() - For edge type interupts only
+ end()
+ set_type - Optional
+ set_affinity - SMP only
+
+
+
+
+ Quirks and optimizations
+
+ 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.
+
+
+ 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.
+
+
+
+
+ Chiplevel hardware encapsulation
+
+ The chip level hardware description structure irq_chip
+ contains all the direct chip relevant functions, which
+ can be utilized by the irq_type implementations.
+
+ ack()
+ mask_ack() - Optional, recommended for performance
+ mask()
+ unmask()
+ retrigger() - Optional
+ set_type() - Optional
+ set_wake() - Optional
+
+ 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.
+
+
+
+
+
+ __do_IRQ entry point
+
+ The original implementation __do_IRQ() is an alternative entry
+ point for all types of interrupts.
+
+
+ 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.
+
+
+ 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.
+
+
+
+
+ Locking on SMP
+
+ 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.
+
+
+
+ Structures
+
+ This chapter contains the autogenerated documentation of the structures which are
+ used in the generic IRQ layer.
+
+!Iinclude/linux/irq.h
+
+
+
+ Public Functions Provided
+
+ This chapter contains the autogenerated documentation of the kernel API functions
+ which are exported.
+
+!Ekernel/irq/manage.c
+
+
+
+ Internal Functions Provided
+
+ This chapter contains the autogenerated documentation of the internal functions.
+
+!Ikernel/irq/handle.c
+!Ikernel/irq/manage.c
+
+
+
+ Credits
+
+ The following people have contributed to this document:
+
+ Thomas Gleixnertglx@linutronix.de
+ Ingo Molnarmingo@elte.hu
+
+
+
+
diff -urN --exclude=.hg linux-2.6.12/Makefile linux-2.6.12-armirq/Makefile
--- linux-2.6.12/Makefile 2005-07-18 15:41:23.000000000 +0200
+++ linux-2.6.12-armirq/Makefile 2005-07-18 15:38:50.000000000 +0200
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 12
-EXTRAVERSION =
+EXTRAVERSION = -armirq-A5
NAME=Woozy Numbat
# *DOCUMENTATION*
diff -urN --exclude=.hg linux-2.6.12/arch/arm/Kconfig linux-2.6.12-armirq/arch/arm/Kconfig
--- linux-2.6.12/arch/arm/Kconfig 2005-07-18 15:41:23.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/Kconfig 2005-07-13 14:34:11.000000000 +0200
@@ -50,6 +50,10 @@
bool
default y
+config GENERIC_HARDIRQS
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
diff -urN --exclude=.hg linux-2.6.12/arch/arm/common/locomo.c linux-2.6.12-armirq/arch/arm/common/locomo.c
--- linux-2.6.12/arch/arm/common/locomo.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/common/locomo.c 2005-07-13 14:34:11.000000000 +0200
@@ -177,7 +177,7 @@
d = irq_desc + irq;
for (i = 0; i <= 3; i++, d++, irq++) {
if (req & (0x0100 << i)) {
- d->handle(irq, d, regs);
+ desc_lock_handle_irq(irq, d, regs);
}
}
@@ -220,7 +220,7 @@
if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
d = irq_desc + LOCOMO_IRQ_KEY_START;
- d->handle(LOCOMO_IRQ_KEY_START, d, regs);
+ desc_lock_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);
}
}
@@ -273,7 +273,7 @@
d = irq_desc + LOCOMO_IRQ_GPIO_START;
for (i = 0; i <= 15; i++, irq++, d++) {
if (req & (0x0001 << i)) {
- d->handle(irq, d, regs);
+ desc_lock_handle_irq(irq, d, regs);
}
}
}
@@ -328,7 +328,7 @@
if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
d = irq_desc + LOCOMO_IRQ_LT_START;
- d->handle(LOCOMO_IRQ_LT_START, d, regs);
+ desc_lock_handle_irq(LOCOMO_IRQ_LT_START, d, regs);
}
}
@@ -379,7 +379,7 @@
for (i = 0; i <= 3; i++, irq++, d++) {
if (req & (0x0001 << i)) {
- d->handle(irq, d, regs);
+ desc_lock_handle_irq(irq, d, regs);
}
}
}
@@ -426,6 +426,12 @@
.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;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/common/sa1111.c linux-2.6.12-armirq/arch/arm/common/sa1111.c
--- linux-2.6.12/arch/arm/common/sa1111.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/common/sa1111.c 2005-07-13 14:34:11.000000000 +0200
@@ -159,11 +159,11 @@
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);
@@ -268,8 +268,8 @@
.mask = sa1111_mask_lowirq,
.unmask = sa1111_unmask_lowirq,
.retrigger = sa1111_retrigger_lowirq,
- .type = sa1111_type_lowirq,
- .wake = sa1111_wake_lowirq,
+ .set_type = sa1111_type_lowirq,
+ .set_wake = sa1111_wake_lowirq,
};
static void sa1111_mask_highirq(unsigned int irq)
@@ -364,10 +364,12 @@
.mask = sa1111_mask_highirq,
.unmask = sa1111_unmask_highirq,
.retrigger = sa1111_retrigger_highirq,
- .type = sa1111_type_highirq,
- .wake = sa1111_wake_highirq,
+ .set_type = sa1111_type_highirq,
+ .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;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/common/time-acorn.c linux-2.6.12-armirq/arch/arm/common/time-acorn.c
--- linux-2.6.12/arch/arm/common/time-acorn.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/common/time-acorn.c 2005-07-13 14:34:11.000000000 +0200
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/kernel/ecard.c linux-2.6.12-armirq/arch/arm/kernel/ecard.c
--- linux-2.6.12/arch/arm/kernel/ecard.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/kernel/ecard.c 2005-07-13 14:34:11.000000000 +0200
@@ -585,7 +585,7 @@
if (pending) {
struct irqdesc *d = irq_desc + ec->irq;
- d->handle(ec->irq, d, regs);
+ desc_lock_handle_irq(ec->irq, d, regs);
called ++;
}
}
@@ -619,7 +619,7 @@
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:
@@ -632,7 +632,7 @@
* Serial cards should go in 0/1, ethernet/scsi in 2/3
* otherwise you will lose serial data at high speeds!
*/
- d->handle(ec->irq, d, regs);
+ desc_lock_handle_irq(ec->irq, d, regs);
} else {
printk(KERN_WARNING "card%d: interrupt from unclaimed "
"card???\n", slot);
@@ -1052,6 +1052,9 @@
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
@@ -1081,8 +1084,10 @@
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();
diff -urN --exclude=.hg linux-2.6.12/arch/arm/kernel/fiq.c linux-2.6.12-armirq/arch/arm/kernel/fiq.c
--- linux-2.6.12/arch/arm/kernel/fiq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/kernel/fiq.c 2005-07-13 14:34:11.000000000 +0200
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/kernel/irq.c linux-2.6.12-armirq/arch/arm/kernel/irq.c
--- linux-2.6.12/arch/arm/kernel/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/kernel/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -38,188 +38,8 @@
#include
#include
-/*
- * 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->wake)
- desc->chip->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->wake)
- desc->chip->wake(irq, 0);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_wake);
-
int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *) v, cpu;
@@ -238,7 +58,7 @@
}
if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_controller_lock, flags);
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
goto unlock;
@@ -252,7 +72,7 @@
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);
@@ -260,261 +80,21 @@
#ifdef CONFIG_SMP
show_ipi_list(p);
#endif
+#ifdef FIXME_TGLX
seq_printf(p, "Err: %10lu\n", irq_err_count);
+#endif
}
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 (!count || noirqdebug)
- return;
-
- count--;
-
- if (ret != IRQ_HANDLED && ret != IRQ_NONE) {
- printk("irq%u: bogus retval mask %x\n", irq, ret);
- } else {
- 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);
-
- 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(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'
*/
@@ -525,100 +105,58 @@
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
+ *
+ * TGLX_FIXME
*/
if (irq >= NR_IRQS)
- desc = &bad_irq_desc;
+ desc = &bad_irq;
irq_enter();
- spin_lock(&irq_controller_lock);
- desc->handle(irq, desc, regs);
- /*
- * Now re-run any pending interrupts.
- */
- if (!list_empty(&irq_pending))
- do_pending_irqs(regs);
-
- irq_finish(irq);
+ desc_lock_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)
+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 handler for IRQ%d\n", irq);
+ printk(KERN_ERR "Trying to install type control 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);
+ /* 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);
}
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-
-void set_irq_chip(unsigned int irq, struct irqchip *chip)
-{
- struct irqdesc *desc;
- unsigned long flags;
- if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ /* Install the irq_type */
+ if (generic_set_irq_type(irq, type))
return;
- }
- if (chip == NULL)
- chip = &bad_chip;
+ 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);
- 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->type) {
- spin_lock_irqsave(&irq_controller_lock, flags);
- ret = desc->chip->type(irq, type);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
+ 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)
{
@@ -631,408 +169,28 @@
}
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 */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
- 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 (!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->type)
- irq_desc[i].chip->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", 0);
- 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();
init_dma();
}
-
-static int __init noirqdebug_setup(char *str)
-{
- noirqdebug = 1;
- return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-clps711x/time.c linux-2.6.12-armirq/arch/arm/mach-clps711x/time.c
--- linux-2.6.12/arch/arm/mach-clps711x/time.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-clps711x/time.c 2005-07-13 14:34:11.000000000 +0200
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-clps7500/core.c linux-2.6.12-armirq/arch/arm/mach-clps7500/core.c
--- linux-2.6.12/arch/arm/mach-clps7500/core.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-clps7500/core.c 2005-07-13 14:34:11.000000000 +0200
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-footbridge/dc21285-timer.c linux-2.6.12-armirq/arch/arm/mach-footbridge/dc21285-timer.c
--- linux-2.6.12/arch/arm/mach-footbridge/dc21285-timer.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-footbridge/dc21285-timer.c 2005-07-13 14:34:11.000000000 +0200
@@ -6,6 +6,7 @@
*/
#include
#include
+#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-footbridge/isa-irq.c linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-irq.c
--- linux-2.6.12/arch/arm/mach-footbridge/isa-irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -95,13 +95,24 @@
}
desc = irq_desc + isa_irq;
- desc->handle(isa_irq, desc, regs);
+ desc_lock_handle_irq(isa_irq, desc, regs);
}
static struct irqaction irq_cascade = { .handler = no_action, .name = "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 @@
* 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);
+ }
}
}
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-footbridge/isa-timer.c linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-timer.c
--- linux-2.6.12/arch/arm/mach-footbridge/isa-timer.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-footbridge/isa-timer.c 2005-07-13 14:34:11.000000000 +0200
@@ -6,6 +6,7 @@
*/
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-h720x/common.c linux-2.6.12-armirq/arch/arm/mach-h720x/common.c
--- linux-2.6.12/arch/arm/mach-h720x/common.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-h720x/common.c 2005-07-13 14:34:11.000000000 +0200
@@ -108,7 +108,7 @@
while (mask) {
if (mask & 1) {
IRQDBG("handling irq %d\n", irq);
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
}
irq++;
desc++;
@@ -163,6 +163,11 @@
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 @@
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 = {
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-h720x/cpu-h7202.c linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7202.c
--- linux-2.6.12/arch/arm/mach-h720x/cpu-h7202.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-h720x/cpu-h7202.c 2005-07-13 14:34:11.000000000 +0200
@@ -126,7 +126,7 @@
desc = irq_desc + irq;
while (mask) {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
irq++;
desc++;
mask >>= 1;
@@ -175,6 +175,8 @@
.handler = h7202_timer_interrupt
};
+static DEFINE_IRQ_CHAINED_TYPE(h7202_timerx_demux_handler);
+
/*
* Setup TIMER0 as system timer
*/
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-imx/irq.c linux-2.6.12-armirq/arch/arm/mach-imx/irq.c
--- linux-2.6.12/arch/arm/mach-imx/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-imx/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -152,7 +152,7 @@
while (mask) {
if (mask & 1) {
DEBUG_IRQ("handling irq %d\n", irq);
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
}
irq++;
desc++;
@@ -214,9 +214,14 @@
.ack = imx_gpio_ack_irq,
.mask = imx_gpio_mask_irq,
.unmask = imx_gpio_unmask_irq,
- .type = imx_gpio_irq_type,
+ .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)
{
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-imx/time.c linux-2.6.12-armirq/arch/arm/mach-imx/time.c
--- linux-2.6.12/arch/arm/mach-imx/time.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-imx/time.c 2005-07-13 14:34:11.000000000 +0200
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-integrator/core.c linux-2.6.12-armirq/arch/arm/mach-integrator/core.c
--- linux-2.6.12/arch/arm/mach-integrator/core.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-integrator/core.c 2005-07-13 14:34:11.000000000 +0200
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-integrator/integrator_cp.c linux-2.6.12-armirq/arch/arm/mach-integrator/integrator_cp.c
--- linux-2.6.12/arch/arm/mach-integrator/integrator_cp.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-integrator/integrator_cp.c 2005-07-13 14:34:11.000000000 +0200
@@ -170,7 +170,7 @@
irq += IRQ_SIC_START;
desc = irq_desc + irq;
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
} while (status);
}
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-ixp2000/core.c linux-2.6.12-armirq/arch/arm/mach-ixp2000/core.c
--- linux-2.6.12/arch/arm/mach-ixp2000/core.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-ixp2000/core.c 2005-07-13 14:34:11.000000000 +0200
@@ -242,7 +242,7 @@
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
- irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0;
+ set_irq_flags(line+IRQ_IXP2000_GPIO0, 0);
} else if(style == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
}
@@ -262,7 +262,7 @@
for (i = 0; i <= 7; i++) {
if (status & (1<handle(i + IRQ_IXP2000_GPIO0, desc, regs);
+ desc_lock_handle_irq(i + IRQ_IXP2000_GPIO0, desc, regs);
}
}
}
@@ -329,6 +329,8 @@
.unmask = ixp2000_irq_unmask
};
+static DEFINE_IRQ_CHAINED_TYPE(ixp2000_GPIO_irq_handler);
+
void __init ixp2000_init_irq(void)
{
int irq;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-ixp2000/ixdp2x00.c linux-2.6.12-armirq/arch/arm/mach-ixp2000/ixdp2x00.c
--- linux-2.6.12/arch/arm/mach-ixp2000/ixdp2x00.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-ixp2000/ixdp2x00.c 2005-07-13 14:34:11.000000000 +0200
@@ -130,7 +130,7 @@
struct irqdesc *cpld_desc;
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
cpld_desc = irq_desc + cpld_irq;
- cpld_desc->handle(cpld_irq, cpld_desc, regs);
+ desc_lock_handle_irq(cpld_irq, cpld_desc, regs);
}
}
@@ -143,6 +143,8 @@
.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;
@@ -165,7 +167,7 @@
}
/* Hook into PCI interrupt */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x00_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}
/*************************************************************************
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-ixp2000/ixdp2x01.c linux-2.6.12-armirq/arch/arm/mach-ixp2000/ixdp2x01.c
--- linux-2.6.12/arch/arm/mach-ixp2000/ixdp2x01.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-ixp2000/ixdp2x01.c 2005-07-13 14:34:11.000000000 +0200
@@ -82,7 +82,7 @@
struct irqdesc *cpld_desc;
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
cpld_desc = irq_desc + cpld_irq;
- cpld_desc->handle(cpld_irq, cpld_desc, regs);
+ desc_lock_handle_irq(cpld_irq, cpld_desc, regs);
}
}
@@ -95,6 +95,8 @@
.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
@@ -127,7 +129,7 @@
}
/* Hook into PCI interrupts */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x01_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
}
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-l7200/core.c linux-2.6.12-armirq/arch/arm/mach-l7200/core.c
--- linux-2.6.12/arch/arm/mach-l7200/core.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-l7200/core.c 2005-07-13 14:34:11.000000000 +0200
@@ -7,6 +7,7 @@
*/
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/arch-kev7a400.c linux-2.6.12-armirq/arch/arm/mach-lh7a40x/arch-kev7a400.c
--- linux-2.6.12/arch/arm/mach-lh7a40x/arch-kev7a400.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/arch-kev7a400.c 2005-07-13 14:34:11.000000000 +0200
@@ -72,6 +72,8 @@
}
}
+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
void __init lh7a40x_init_board_irq (void)
{
int irq;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/arch-lpd7a40x.c linux-2.6.12-armirq/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
--- linux-2.6.12/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2005-07-13 14:34:11.000000000 +0200
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -173,6 +174,7 @@
desc->chip->unmask (irq); /* Level-triggered need this */
}
+static DEFINE_IRQ_CHAINED_TYPE(lpd7a40x_cpld_handler);
void __init lh7a40x_init_board_irq (void)
{
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/common.h linux-2.6.12-armirq/arch/arm/mach-lh7a40x/common.h
--- linux-2.6.12/arch/arm/mach-lh7a40x/common.h 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/common.h 2005-07-13 14:34:11.000000000 +0200
@@ -13,4 +13,4 @@
extern void lh7a400_init_irq (void);
extern void lh7a404_init_irq (void);
-#define IRQ_DISPATCH(irq) irq_desc[irq].handle ((irq), &irq_desc[irq], regs)
+#define IRQ_DISPATCH(irq) desc_lock_handle_irq((irq),(irq_desc + irq), regs)
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/irq-kev7a400.c linux-2.6.12-armirq/arch/arm/mach-lh7a40x/irq-kev7a400.c
--- linux-2.6.12/arch/arm/mach-lh7a40x/irq-kev7a400.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/irq-kev7a400.c 2005-07-13 14:34:11.000000000 +0200
@@ -60,6 +60,8 @@
}
}
+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
/* IRQ initialization */
void __init
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/irq-lpd7a40x.c linux-2.6.12-armirq/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
--- linux-2.6.12/arch/arm/mach-lh7a40x/irq-lpd7a40x.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/irq-lpd7a40x.c 2005-07-13 14:34:11.000000000 +0200
@@ -71,6 +71,7 @@
desc->chip->unmask (irq); /* Level-triggered need this */
}
+static DEFINE_IRQ_CHAINED_TYPE(lh7a40x_cpld_handler);
/* IRQ initialization */
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-lh7a40x/time.c linux-2.6.12-armirq/arch/arm/mach-lh7a40x/time.c
--- linux-2.6.12/arch/arm/mach-lh7a40x/time.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-lh7a40x/time.c 2005-07-13 14:34:11.000000000 +0200
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-omap/fpga.c linux-2.6.12-armirq/arch/arm/mach-omap/fpga.c
--- linux-2.6.12/arch/arm/mach-omap/fpga.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-omap/fpga.c 2005-07-13 14:34:11.000000000 +0200
@@ -102,7 +102,7 @@
fpga_irq++, stat >>= 1) {
if (stat & 1) {
d = irq_desc + fpga_irq;
- d->handle(fpga_irq, d, regs);
+ desc_lock_handle_irq(fpga_irq, d, regs);
}
}
}
@@ -120,6 +120,8 @@
.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
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-omap/gpio.c linux-2.6.12-armirq/arch/arm/mach-omap/gpio.c
--- linux-2.6.12/arch/arm/mach-omap/gpio.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-omap/gpio.c 2005-07-13 14:34:11.000000000 +0200
@@ -590,7 +590,7 @@
if (!(isr & 1))
continue;
d = irq_desc + gpio_irq;
- d->handle(gpio_irq, d, regs);
+ desc_lock_handle_irq(gpio_irq, d, regs);
}
}
@@ -656,6 +656,8 @@
.unmask = mpuio_unmask_irq
};
+static DEFINE_IRQ_CHAINED_TYPE(gpio_irq_handler);
+
static int initialized = 0;
static int __init _omap_gpio_init(void)
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-pxa/idp.c linux-2.6.12-armirq/arch/arm/mach-pxa/idp.c
--- linux-2.6.12/arch/arm/mach-pxa/idp.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-pxa/idp.c 2005-07-13 14:34:11.000000000 +0200
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-pxa/irq.c linux-2.6.12-armirq/arch/arm/mach-pxa/irq.c
--- linux-2.6.12/arch/arm/mach-pxa/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-pxa/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -133,7 +133,7 @@
.ack = pxa_ack_low_gpio,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
- .type = pxa_gpio_irq_type,
+ .set_type = pxa_gpio_irq_type,
};
/*
@@ -157,7 +157,7 @@
mask >>= 2;
do {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
irq++;
desc++;
mask >>= 1;
@@ -172,7 +172,7 @@
desc = irq_desc + irq;
do {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
irq++;
desc++;
mask >>= 1;
@@ -187,7 +187,7 @@
desc = irq_desc + irq;
do {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
irq++;
desc++;
mask >>= 1;
@@ -203,7 +203,7 @@
desc = irq_desc + irq;
do {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
irq++;
desc++;
mask >>= 1;
@@ -241,9 +241,10 @@
.ack = pxa_ack_muxed_gpio,
.mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio,
- .type = pxa_gpio_irq_type,
+ .set_type = pxa_gpio_irq_type,
};
+static DEFINE_IRQ_CHAINED_TYPE(pxa_gpio_demux_handler);
void __init pxa_init_irq(void)
{
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-pxa/lubbock.c linux-2.6.12-armirq/arch/arm/mach-pxa/lubbock.c
--- linux-2.6.12/arch/arm/mach-pxa/lubbock.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-pxa/lubbock.c 2005-07-13 14:34:11.000000000 +0200
@@ -84,12 +84,14 @@
if (likely(pending)) {
irq = LUBBOCK_IRQ(0) + __ffs(pending);
desc = irq_desc + irq;
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
}
pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
} while (pending);
}
+static DEFINE_IRQ_CHAINED_TYPE(lubbock_irq_handler);
+
static void __init lubbock_init_irq(void)
{
int irq;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-pxa/mainstone.c linux-2.6.12-armirq/arch/arm/mach-pxa/mainstone.c
--- linux-2.6.12/arch/arm/mach-pxa/mainstone.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-pxa/mainstone.c 2005-07-13 14:34:11.000000000 +0200
@@ -72,12 +72,14 @@
if (likely(pending)) {
irq = MAINSTONE_IRQ(0) + __ffs(pending);
desc = irq_desc + irq;
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
}
pending = MST_INTSETCLR & mainstone_irq_enabled;
} while (pending);
}
+static DEFINE_IRQ_CHAINED_TYPE(mainstone_irq_handler);
+
static void __init mainstone_init_irq(void)
{
int irq;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-rpc/irq.c linux-2.6.12-armirq/arch/arm/mach-rpc/irq.c
--- linux-2.6.12/arch/arm/mach-rpc/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-rpc/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -112,6 +112,15 @@
.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,15 @@
iomd_writeb(0, IOMD_FIQMASK);
iomd_writeb(0, IOMD_DMAMASK);
+ 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 +163,10 @@
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();
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-s3c2410/bast-irq.c linux-2.6.12-armirq/arch/arm/mach-s3c2410/bast-irq.c
--- linux-2.6.12/arch/arm/mach-s3c2410/bast-irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-s3c2410/bast-irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -124,7 +124,7 @@
irqno = bast_pc104_irqs[i];
desc = irq_desc + irqno;
- desc->handle(irqno, desc, regs);
+ desc_lock_handle_irq(irqno, desc, regs);
}
stat >>= 1;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-s3c2410/irq.c linux-2.6.12-armirq/arch/arm/mach-s3c2410/irq.c
--- linux-2.6.12/arch/arm/mach-s3c2410/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-s3c2410/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -182,14 +182,14 @@
.ack = s3c_irq_maskack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask,
- .wake = s3c_irq_wake
+ .set_wake = s3c_irq_wake
};
static struct irqchip s3c_irq_chip = {
.ack = s3c_irq_ack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask,
- .wake = s3c_irq_wake
+ .set_wake = s3c_irq_wake
};
/* S3C2410_EINTMASK
@@ -348,16 +348,16 @@
.mask = s3c_irqext_mask,
.unmask = s3c_irqext_unmask,
.ack = s3c_irqext_ack,
- .type = s3c_irqext_type,
- .wake = s3c_irqext_wake
+ .set_type = s3c_irqext_type,
+ .set_wake = s3c_irqext_wake
};
static struct irqchip s3c_irq_eint0t4 = {
.ack = s3c_irq_ack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask,
- .wake = s3c_irq_wake,
- .type = s3c_irqext_type,
+ .set_wake = s3c_irq_wake,
+ .set_type = s3c_irqext_type,
};
/* mask values for the parent registers for each of the interrupt types */
@@ -573,11 +573,11 @@
if (subsrc != 0) {
if (subsrc & 1) {
mydesc = irq_desc + IRQ_TC;
- mydesc->handle( IRQ_TC, mydesc, regs);
+ desc_lock_handle_irq( IRQ_TC, mydesc, regs);
}
if (subsrc & 2) {
mydesc = irq_desc + IRQ_ADC;
- mydesc->handle(IRQ_ADC, mydesc, regs);
+ desc_lock_handle_irq(IRQ_ADC, mydesc, regs);
}
}
}
@@ -606,17 +606,17 @@
desc = irq_desc + start;
if (subsrc & 1)
- desc->handle(start, desc, regs);
+ desc_lock_handle_irq(start, desc, regs);
desc++;
if (subsrc & 2)
- desc->handle(start+1, desc, regs);
+ desc_lock_handle_irq(start+1, desc, regs);
desc++;
if (subsrc & 4)
- desc->handle(start+2, desc, regs);
+ desc_lock_handle_irq(start+2, desc, regs);
}
}
@@ -650,6 +650,11 @@
}
+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
@@ -821,11 +826,11 @@
if (subsrc != 0) {
if (subsrc & 1) {
mydesc = irq_desc + IRQ_S3C2440_WDT;
- mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+ desc_lock_handle_irq(IRQ_S3C2440_WDT, mydesc, regs);
}
if (subsrc & 2) {
mydesc = irq_desc + IRQ_S3C2440_AC97;
- mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+ desc_lock_handle_irq(IRQ_S3C2440_AC97, mydesc, regs);
}
}
}
@@ -879,11 +884,11 @@
if (subsrc != 0) {
if (subsrc & 1) {
mydesc = irq_desc + IRQ_S3C2440_CAM_C;
- mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+ desc_lock_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
}
if (subsrc & 2) {
mydesc = irq_desc + IRQ_S3C2440_CAM_P;
- mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+ desc_lock_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
}
}
}
@@ -914,6 +919,9 @@
.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;
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-s3c2410/time.c linux-2.6.12-armirq/arch/arm/mach-s3c2410/time.c
--- linux-2.6.12/arch/arm/mach-s3c2410/time.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-s3c2410/time.c 2005-07-13 14:34:11.000000000 +0200
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/cerf.c linux-2.6.12-armirq/arch/arm/mach-sa1100/cerf.c
--- linux-2.6.12/arch/arm/mach-sa1100/cerf.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/cerf.c 2005-07-13 14:34:11.000000000 +0200
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/h3600.c linux-2.6.12-armirq/arch/arm/mach-sa1100/h3600.c
--- linux-2.6.12/arch/arm/mach-sa1100/h3600.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/h3600.c 2005-07-13 14:34:11.000000000 +0200
@@ -784,6 +784,8 @@
H3800_ASIC2_GPIINTSTAT |= mask;
}
+static DEFINE_IRQ_CHAINED_TYPE(h3800_IRQ_demux);
+
static void __init h3800_init_irq(void)
{
int i;
@@ -822,7 +824,7 @@
}
#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);
}
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/irq.c linux-2.6.12-armirq/arch/arm/mach-sa1100/irq.c
--- linux-2.6.12/arch/arm/mach-sa1100/irq.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -98,8 +98,8 @@
.ack = sa1100_low_gpio_ack,
.mask = sa1100_low_gpio_mask,
.unmask = sa1100_low_gpio_unmask,
- .type = sa1100_gpio_type,
- .wake = sa1100_low_gpio_wake,
+ .set_type = sa1100_gpio_type,
+ .set_wake = sa1100_low_gpio_wake,
};
/*
@@ -126,7 +126,7 @@
mask >>= 11;
do {
if (mask & 1)
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
mask >>= 1;
irq++;
desc++;
@@ -181,8 +181,8 @@
.ack = sa1100_high_gpio_ack,
.mask = sa1100_high_gpio_mask,
.unmask = sa1100_high_gpio_unmask,
- .type = sa1100_gpio_type,
- .wake = sa1100_high_gpio_wake,
+ .set_type = sa1100_gpio_type,
+ .set_wake = sa1100_high_gpio_wake,
};
/*
@@ -281,6 +281,8 @@
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)
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/neponset.c linux-2.6.12-armirq/arch/arm/mach-sa1100/neponset.c
--- linux-2.6.12/arch/arm/mach-sa1100/neponset.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/neponset.c 2005-07-13 14:34:11.000000000 +0200
@@ -61,12 +61,12 @@
if (irr & IRR_ETHERNET) {
d = irq_desc + IRQ_NEPONSET_SMC9196;
- d->handle(IRQ_NEPONSET_SMC9196, d, regs);
+ desc_lock_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
}
if (irr & IRR_USAR) {
d = irq_desc + IRQ_NEPONSET_USAR;
- d->handle(IRQ_NEPONSET_USAR, d, regs);
+ desc_lock_handle_irq(IRQ_NEPONSET_USAR, d, regs);
}
desc->chip->unmask(irq);
@@ -74,7 +74,7 @@
if (irr & IRR_SA1111) {
d = irq_desc + IRQ_NEPONSET_SA1111;
- d->handle(IRQ_NEPONSET_SA1111, d, regs);
+ desc_lock_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
}
}
}
@@ -137,6 +137,8 @@
.get_mctrl = neponset_get_mctrl,
};
+static DEFINE_IRQ_CHAINED_TYPE(neponset_irq_handler);
+
static int neponset_probe(struct device *dev)
{
sa1100_register_uart_fns(&neponset_port_fns);
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/pleb.c linux-2.6.12-armirq/arch/arm/mach-sa1100/pleb.c
--- linux-2.6.12/arch/arm/mach-sa1100/pleb.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/pleb.c 2005-07-13 14:34:11.000000000 +0200
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-sa1100/time.c linux-2.6.12-armirq/arch/arm/mach-sa1100/time.c
--- linux-2.6.12/arch/arm/mach-sa1100/time.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-sa1100/time.c 2005-07-13 14:34:11.000000000 +0200
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/arch/arm/mach-versatile/core.c linux-2.6.12-armirq/arch/arm/mach-versatile/core.c
--- linux-2.6.12/arch/arm/mach-versatile/core.c 2005-07-18 15:41:24.000000000 +0200
+++ linux-2.6.12-armirq/arch/arm/mach-versatile/core.c 2005-07-13 14:34:11.000000000 +0200
@@ -107,10 +107,12 @@
irq += IRQ_SIC_START;
desc = irq_desc + irq;
- desc->handle(irq, desc, regs);
+ desc_lock_handle_irq(irq, desc, regs);
} while (status);
}
+static DEFINE_IRQ_CHAINED_TYPE(sic_handle_irq);
+
#if 1
#define IRQ_MMCI0A IRQ_VICSOURCE22
#define IRQ_AACI IRQ_VICSOURCE24
@@ -160,7 +162,7 @@
}
}
- set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
+ set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
vic_unmask_irq(IRQ_VICSOURCE31);
/* Do second interrupt controller */
diff -urN --exclude=.hg linux-2.6.12/arch/ia64/sn/kernel/irq.c linux-2.6.12-armirq/arch/ia64/sn/kernel/irq.c
--- linux-2.6.12/arch/ia64/sn/kernel/irq.c 2005-07-18 15:41:25.000000000 +0200
+++ linux-2.6.12-armirq/arch/ia64/sn/kernel/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -183,14 +183,14 @@
}
struct hw_interrupt_type irq_type_sn = {
- "SN hub",
- sn_startup_irq,
- sn_shutdown_irq,
- sn_enable_irq,
- sn_disable_irq,
- sn_ack_irq,
- sn_end_irq,
- sn_set_affinity_irq
+ .typename = "SN hub",
+ .startup = sn_startup_irq,
+ .shutdown = sn_shutdown_irq,
+ .enable = sn_enable_irq,
+ .disable = sn_disable_irq,
+ .ack = sn_ack_irq,
+ .end = sn_end_irq,
+ .set_affinity = sn_set_affinity_irq
};
unsigned int sn_local_vector_to_irq(u8 vector)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_m32700ut.c linux-2.6.12-armirq/arch/m32r/kernel/setup_m32700ut.c
--- linux-2.6.12/arch/m32r/kernel/setup_m32700ut.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_m32700ut.c 2005-07-13 14:34:11.000000000 +0200
@@ -78,13 +78,13 @@
static struct hw_interrupt_type m32700ut_irq_type =
{
- "M32700UT-IRQ",
- startup_m32700ut_irq,
- shutdown_m32700ut_irq,
- enable_m32700ut_irq,
- disable_m32700ut_irq,
- mask_and_ack_m32700ut,
- end_m32700ut_irq
+ .typename = "M32700UT-IRQ",
+ .startup = startup_m32700ut_irq,
+ .shutdown = shutdown_m32700ut_irq,
+ .enable = enable_m32700ut_irq,
+ .disable = disable_m32700ut_irq,
+ .ack = mask_and_ack_m32700ut,
+ .end = end_m32700ut_irq
};
/*
@@ -155,13 +155,13 @@
static struct hw_interrupt_type m32700ut_pld_irq_type =
{
- "M32700UT-PLD-IRQ",
- startup_m32700ut_pld_irq,
- shutdown_m32700ut_pld_irq,
- enable_m32700ut_pld_irq,
- disable_m32700ut_pld_irq,
- mask_and_ack_m32700ut_pld,
- end_m32700ut_pld_irq
+ .typename = "M32700UT-PLD-IRQ",
+ .startup = startup_m32700ut_pld_irq,
+ .shutdown = shutdown_m32700ut_pld_irq,
+ .enable = enable_m32700ut_pld_irq,
+ .disable = disable_m32700ut_pld_irq,
+ .ack = mask_and_ack_m32700ut_pld,
+ .end = end_m32700ut_pld_irq
};
/*
@@ -224,13 +224,13 @@
static struct hw_interrupt_type m32700ut_lanpld_irq_type =
{
- "M32700UT-PLD-LAN-IRQ",
- startup_m32700ut_lanpld_irq,
- shutdown_m32700ut_lanpld_irq,
- enable_m32700ut_lanpld_irq,
- disable_m32700ut_lanpld_irq,
- mask_and_ack_m32700ut_lanpld,
- end_m32700ut_lanpld_irq
+ .typename = "M32700UT-PLD-LAN-IRQ",
+ .startup = startup_m32700ut_lanpld_irq,
+ .shutdown = shutdown_m32700ut_lanpld_irq,
+ .enable = enable_m32700ut_lanpld_irq,
+ .disable = disable_m32700ut_lanpld_irq,
+ .ack = mask_and_ack_m32700ut_lanpld,
+ .end = end_m32700ut_lanpld_irq
};
/*
@@ -293,13 +293,13 @@
static struct hw_interrupt_type m32700ut_lcdpld_irq_type =
{
- "M32700UT-PLD-LCD-IRQ",
- startup_m32700ut_lcdpld_irq,
- shutdown_m32700ut_lcdpld_irq,
- enable_m32700ut_lcdpld_irq,
- disable_m32700ut_lcdpld_irq,
- mask_and_ack_m32700ut_lcdpld,
- end_m32700ut_lcdpld_irq
+ .typename = "M32700UT-PLD-LCD-IRQ",
+ .startup = startup_m32700ut_lcdpld_irq,
+ .shutdown = shutdown_m32700ut_lcdpld_irq,
+ .enable = enable_m32700ut_lcdpld_irq,
+ .disable = disable_m32700ut_lcdpld_irq,
+ .ack = mask_and_ack_m32700ut_lcdpld,
+ .end = end_m32700ut_lcdpld_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_mappi.c linux-2.6.12-armirq/arch/m32r/kernel/setup_mappi.c
--- linux-2.6.12/arch/m32r/kernel/setup_mappi.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_mappi.c 2005-07-13 14:34:11.000000000 +0200
@@ -70,13 +70,13 @@
static struct hw_interrupt_type mappi_irq_type =
{
- "MAPPI-IRQ",
- startup_mappi_irq,
- shutdown_mappi_irq,
- enable_mappi_irq,
- disable_mappi_irq,
- mask_and_ack_mappi,
- end_mappi_irq
+ .typename = "MAPPI-IRQ",
+ .startup = startup_mappi_irq,
+ .shutdown = shutdown_mappi_irq,
+ .enable = enable_mappi_irq,
+ .disable = disable_mappi_irq,
+ .ack = mask_and_ack_mappi,
+ .end = end_mappi_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_mappi2.c linux-2.6.12-armirq/arch/m32r/kernel/setup_mappi2.c
--- linux-2.6.12/arch/m32r/kernel/setup_mappi2.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_mappi2.c 2005-07-13 14:34:11.000000000 +0200
@@ -79,13 +79,13 @@
static struct hw_interrupt_type mappi2_irq_type =
{
- "MAPPI2-IRQ",
- startup_mappi2_irq,
- shutdown_mappi2_irq,
- enable_mappi2_irq,
- disable_mappi2_irq,
- mask_and_ack_mappi2,
- end_mappi2_irq
+ .typename = "MAPPI2-IRQ",
+ .startup = startup_mappi2_irq,
+ .shutdown = shutdown_mappi2_irq,
+ .enable = enable_mappi2_irq,
+ .disable = disable_mappi2_irq,
+ .ack = mask_and_ack_mappi2,
+ .end = end_mappi2_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_oaks32r.c linux-2.6.12-armirq/arch/m32r/kernel/setup_oaks32r.c
--- linux-2.6.12/arch/m32r/kernel/setup_oaks32r.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_oaks32r.c 2005-07-13 14:34:11.000000000 +0200
@@ -70,13 +70,13 @@
static struct hw_interrupt_type oaks32r_irq_type =
{
- "OAKS32R-IRQ",
- startup_oaks32r_irq,
- shutdown_oaks32r_irq,
- enable_oaks32r_irq,
- disable_oaks32r_irq,
- mask_and_ack_mappi,
- end_oaks32r_irq
+ .typename = "OAKS32R-IRQ",
+ .startup = startup_oaks32r_irq,
+ .shutdown = shutdown_oaks32r_irq,
+ .enable = enable_oaks32r_irq,
+ .disable = disable_oaks32r_irq,
+ .ack = mask_and_ack_mappi,
+ .end = end_oaks32r_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_opsput.c linux-2.6.12-armirq/arch/m32r/kernel/setup_opsput.c
--- linux-2.6.12/arch/m32r/kernel/setup_opsput.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_opsput.c 2005-07-13 14:34:11.000000000 +0200
@@ -79,13 +79,13 @@
static struct hw_interrupt_type opsput_irq_type =
{
- "OPSPUT-IRQ",
- startup_opsput_irq,
- shutdown_opsput_irq,
- enable_opsput_irq,
- disable_opsput_irq,
- mask_and_ack_opsput,
- end_opsput_irq
+ .typename = "OPSPUT-IRQ",
+ .startup = startup_opsput_irq,
+ .shutdown = shutdown_opsput_irq,
+ .enable = enable_opsput_irq,
+ .disable = disable_opsput_irq,
+ .ack = mask_and_ack_opsput,
+ .end = end_opsput_irq
};
/*
@@ -156,13 +156,13 @@
static struct hw_interrupt_type opsput_pld_irq_type =
{
- "OPSPUT-PLD-IRQ",
- startup_opsput_pld_irq,
- shutdown_opsput_pld_irq,
- enable_opsput_pld_irq,
- disable_opsput_pld_irq,
- mask_and_ack_opsput_pld,
- end_opsput_pld_irq
+ .typename = "OPSPUT-PLD-IRQ",
+ .startup = startup_opsput_pld_irq,
+ .shutdown = shutdown_opsput_pld_irq,
+ .enable = enable_opsput_pld_irq,
+ .disable = disable_opsput_pld_irq,
+ .ack = mask_and_ack_opsput_pld,
+ .end = end_opsput_pld_irq
};
/*
@@ -225,13 +225,13 @@
static struct hw_interrupt_type opsput_lanpld_irq_type =
{
- "OPSPUT-PLD-LAN-IRQ",
- startup_opsput_lanpld_irq,
- shutdown_opsput_lanpld_irq,
- enable_opsput_lanpld_irq,
- disable_opsput_lanpld_irq,
- mask_and_ack_opsput_lanpld,
- end_opsput_lanpld_irq
+ .typename = "OPSPUT-PLD-LAN-IRQ",
+ .startup = startup_opsput_lanpld_irq,
+ .shutdown = shutdown_opsput_lanpld_irq,
+ .enable = enable_opsput_lanpld_irq,
+ .disable = disable_opsput_lanpld_irq,
+ .ack = mask_and_ack_opsput_lanpld,
+ .end = end_opsput_lanpld_irq
};
/*
@@ -294,13 +294,13 @@
static struct hw_interrupt_type opsput_lcdpld_irq_type =
{
- "OPSPUT-PLD-LCD-IRQ",
- startup_opsput_lcdpld_irq,
- shutdown_opsput_lcdpld_irq,
- enable_opsput_lcdpld_irq,
- disable_opsput_lcdpld_irq,
- mask_and_ack_opsput_lcdpld,
- end_opsput_lcdpld_irq
+ .type = "OPSPUT-PLD-LCD-IRQ",
+ .startup = startup_opsput_lcdpld_irq,
+ .shutdown = shutdown_opsput_lcdpld_irq,
+ .enable = enable_opsput_lcdpld_irq,
+ .disable = disable_opsput_lcdpld_irq,
+ .ack = mask_and_ack_opsput_lcdpld,
+ .end = end_opsput_lcdpld_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/m32r/kernel/setup_usrv.c linux-2.6.12-armirq/arch/m32r/kernel/setup_usrv.c
--- linux-2.6.12/arch/m32r/kernel/setup_usrv.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/m32r/kernel/setup_usrv.c 2005-07-13 14:34:11.000000000 +0200
@@ -70,13 +70,13 @@
static struct hw_interrupt_type mappi_irq_type =
{
- "M32700-IRQ",
- startup_mappi_irq,
- shutdown_mappi_irq,
- enable_mappi_irq,
- disable_mappi_irq,
- mask_and_ack_mappi,
- end_mappi_irq
+ .typename = "M32700-IRQ",
+ .startup = startup_mappi_irq,
+ .shutdown = shutdown_mappi_irq,
+ .enable = enable_mappi_irq,
+ .disable = disable_mappi_irq,
+ .ack = mask_and_ack_mappi,
+ .end = end_mappi_irq
};
/*
@@ -143,13 +143,13 @@
static struct hw_interrupt_type m32700ut_pld_irq_type =
{
- "USRV-PLD-IRQ",
- startup_m32700ut_pld_irq,
- shutdown_m32700ut_pld_irq,
- enable_m32700ut_pld_irq,
- disable_m32700ut_pld_irq,
- mask_and_ack_m32700ut_pld,
- end_m32700ut_pld_irq
+ .typename = "USRV-PLD-IRQ",
+ .startup = startup_m32700ut_pld_irq,
+ .shutdown = shutdown_m32700ut_pld_irq,
+ .enable = enable_m32700ut_pld_irq,
+ .disable = disable_m32700ut_pld_irq,
+ .ack = mask_and_ack_m32700ut_pld,
+ .end = end_m32700ut_pld_irq
};
void __init init_IRQ(void)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/au1000/common/irq.c linux-2.6.12-armirq/arch/mips/au1000/common/irq.c
--- linux-2.6.12/arch/mips/au1000/common/irq.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/au1000/common/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -253,47 +253,43 @@
static struct hw_interrupt_type rise_edge_irq_type = {
- "Au1000 Rise Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_rise_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_rise_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type fall_edge_irq_type = {
- "Au1000 Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_fall_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_fall_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type either_edge_irq_type = {
- "Au1000 Rise or Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_either_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise or Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_either_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type level_irq_type = {
- "Au1000 Level",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_level_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Level",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
};
#ifdef CONFIG_PM
diff -urN --exclude=.hg linux-2.6.12/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
--- linux-2.6.12/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2005-07-13 14:34:11.000000000 +0200
@@ -209,14 +209,13 @@
#define nile4_irq_shutdown nile4_disable_irq
static hw_irq_controller nile4_irq_controller = {
- "nile4",
- nile4_irq_startup,
- nile4_irq_shutdown,
- nile4_enable_irq,
- nile4_disable_irq,
- nile4_ack_irq,
- nile4_irq_end,
- NULL
+ .typename = "nile4",
+ .startup = nile4_irq_startup,
+ .shutdown = nile4_irq_shutdown,
+ .enable = nile4_enable_irq,
+ .disable = nile4_disable_irq,
+ .ack = nile4_ack_irq,
+ .end = nile4_irq_end,
};
void nile4_irq_setup(u32 base) {
diff -urN --exclude=.hg linux-2.6.12/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
--- linux-2.6.12/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -53,14 +53,13 @@
}
static hw_irq_controller vrc5476_irq_controller = {
- "vrc5476",
- vrc5476_irq_startup,
- vrc5476_irq_shutdown,
- vrc5476_irq_enable,
- vrc5476_irq_disable,
- vrc5476_irq_ack,
- vrc5476_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5476",
+ .startup = vrc5476_irq_startup,
+ .shutdown = vrc5476_irq_shutdown,
+ .enable = vrc5476_irq_enable,
+ .disable = vrc5476_irq_disable,
+ .ack = vrc5476_irq_ack,
+ .end = vrc5476_irq_end
};
void __init
diff -urN --exclude=.hg linux-2.6.12/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- linux-2.6.12/arch/mips/ddb5xxx/ddb5477/irq_5477.c 2005-07-18 15:41:26.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/ddb5xxx/ddb5477/irq_5477.c 2005-07-13 14:34:11.000000000 +0200
@@ -90,14 +90,13 @@
}
hw_irq_controller vrc5477_irq_controller = {
- "vrc5477_irq",
- vrc5477_irq_startup,
- vrc5477_irq_shutdown,
- vrc5477_irq_enable,
- vrc5477_irq_disable,
- vrc5477_irq_ack,
- vrc5477_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5477_irq",
+ .startup = vrc5477_irq_startup,
+ .shutdown = vrc5477_irq_shutdown,
+ .enable = vrc5477_irq_enable,
+ .disable = vrc5477_irq_disable,
+ .ack = vrc5477_irq_ack,
+ .end = vrc5477_irq_end
};
void __init vrc5477_irq_init(u32 irq_base)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/ite-boards/generic/irq.c linux-2.6.12-armirq/arch/mips/ite-boards/generic/irq.c
--- linux-2.6.12/arch/mips/ite-boards/generic/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/ite-boards/generic/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -138,14 +138,13 @@
}
static struct hw_interrupt_type it8172_irq_type = {
- "ITE8172",
- startup_ite_irq,
- shutdown_ite_irq,
- enable_it8172_irq,
- disable_it8172_irq,
- mask_and_ack_ite_irq,
- end_ite_irq,
- NULL
+ .typename = "ITE8172",
+ .startup = startup_ite_irq,
+ .shutdown = shutdown_ite_irq,
+ .enable = enable_it8172_irq,
+ .disable = disable_it8172_irq,
+ .ack = mask_and_ack_ite_irq,
+ .end = end_ite_irq,
};
@@ -159,13 +158,13 @@
#define end_none enable_none
static struct hw_interrupt_type cp0_irq_type = {
- "CP0 Count",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "CP0 Count",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
void enable_cpu_timer(void)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/jazz/irq.c linux-2.6.12-armirq/arch/mips/jazz/irq.c
--- linux-2.6.12/arch/mips/jazz/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/jazz/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -58,14 +58,13 @@
}
static struct hw_interrupt_type r4030_irq_type = {
- "R4030",
- startup_r4030_irq,
- shutdown_r4030_irq,
- enable_r4030_irq,
- disable_r4030_irq,
- mask_and_ack_r4030_irq,
- end_r4030_irq,
- NULL
+ .typename = "R4030",
+ .startup = startup_r4030_irq,
+ .shutdown = shutdown_r4030_irq,
+ .enable = enable_r4030_irq,
+ .disable = disable_r4030_irq,
+ .ack = mask_and_ack_r4030_irq,
+ .end = end_r4030_irq,
};
void __init init_r4030_ints(void)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/jmr3927/rbhma3100/irq.c linux-2.6.12-armirq/arch/mips/jmr3927/rbhma3100/irq.c
--- linux-2.6.12/arch/mips/jmr3927/rbhma3100/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/jmr3927/rbhma3100/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -412,13 +412,13 @@
}
static hw_irq_controller jmr3927_irq_controller = {
- "jmr3927_irq",
- jmr3927_irq_startup,
- jmr3927_irq_shutdown,
- jmr3927_irq_enable,
- jmr3927_irq_disable,
- jmr3927_irq_ack,
- jmr3927_irq_end,
+ .typename = "jmr3927_irq",
+ .startup = jmr3927_irq_startup,
+ .shutdown = jmr3927_irq_shutdown,
+ .enable = jmr3927_irq_enable,
+ .disable = jmr3927_irq_disable,
+ .ack = jmr3927_irq_ack,
+ .end = jmr3927_irq_end,
};
void jmr3927_irq_init(u32 irq_base)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/i8259.c linux-2.6.12-armirq/arch/mips/kernel/i8259.c
--- linux-2.6.12/arch/mips/kernel/i8259.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/i8259.c 2005-07-13 14:34:11.000000000 +0200
@@ -52,14 +52,13 @@
}
static struct hw_interrupt_type i8259A_irq_type = {
- "XT-PIC",
- startup_8259A_irq,
- shutdown_8259A_irq,
- enable_8259A_irq,
- disable_8259A_irq,
- mask_and_ack_8259A,
- end_8259A_irq,
- NULL
+ .typename = "XT-PIC",
+ .startup = startup_8259A_irq,
+ .shutdown = shutdown_8259A_irq,
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/irq-msc01.c linux-2.6.12-armirq/arch/mips/kernel/irq-msc01.c
--- linux-2.6.12/arch/mips/kernel/irq-msc01.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/irq-msc01.c 2005-07-13 14:34:11.000000000 +0200
@@ -129,25 +129,23 @@
#define shutdown_msc_irq disable_msc_irq
struct hw_interrupt_type msc_levelirq_type = {
- "SOC-it-Level",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- level_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Level",
+ .startup = startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = level_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
struct hw_interrupt_type msc_edgeirq_type = {
- "SOC-it-Edge",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- edge_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Edge",
+ .startup =startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = edge_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/irq-mv6434x.c linux-2.6.12-armirq/arch/mips/kernel/irq-mv6434x.c
--- linux-2.6.12/arch/mips/kernel/irq-mv6434x.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/irq-mv6434x.c 2005-07-13 14:34:11.000000000 +0200
@@ -135,14 +135,13 @@
#define shutdown_mv64340_irq disable_mv64340_irq
struct hw_interrupt_type mv64340_irq_type = {
- "MV-64340",
- startup_mv64340_irq,
- shutdown_mv64340_irq,
- enable_mv64340_irq,
- disable_mv64340_irq,
- mask_and_ack_mv64340_irq,
- end_mv64340_irq,
- NULL
+ .typename = "MV-64340",
+ .startup = startup_mv64340_irq,
+ .shutdown = shutdown_mv64340_irq,
+ .enable = enable_mv64340_irq,
+ .disable = disable_mv64340_irq,
+ .ack = mask_and_ack_mv64340_irq,
+ .end = end_mv64340_irq,
};
void __init mv64340_irq_init(unsigned int base)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/irq-rm7000.c linux-2.6.12-armirq/arch/mips/kernel/irq-rm7000.c
--- linux-2.6.12/arch/mips/kernel/irq-rm7000.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/irq-rm7000.c 2005-07-13 14:34:11.000000000 +0200
@@ -72,13 +72,13 @@
}
static hw_irq_controller rm7k_irq_controller = {
- "RM7000",
- rm7k_cpu_irq_startup,
- rm7k_cpu_irq_shutdown,
- rm7k_cpu_irq_enable,
- rm7k_cpu_irq_disable,
- rm7k_cpu_irq_ack,
- rm7k_cpu_irq_end,
+ .typename = "RM7000",
+ .startup = rm7k_cpu_irq_startup,
+ .shutdown = rm7k_cpu_irq_shutdown,
+ .enable = rm7k_cpu_irq_enable,
+ .disable = rm7k_cpu_irq_disable,
+ .ack = rm7k_cpu_irq_ack,
+ .end = rm7k_cpu_irq_end,
};
void __init rm7k_cpu_irq_init(int base)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/irq-rm9000.c linux-2.6.12-armirq/arch/mips/kernel/irq-rm9000.c
--- linux-2.6.12/arch/mips/kernel/irq-rm9000.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/irq-rm9000.c 2005-07-13 14:34:11.000000000 +0200
@@ -106,23 +106,23 @@
}
static hw_irq_controller rm9k_irq_controller = {
- "RM9000",
- rm9k_cpu_irq_startup,
- rm9k_cpu_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_cpu_irq_startup,
+ .shutdown = rm9k_cpu_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
static hw_irq_controller rm9k_perfcounter_irq = {
- "RM9000",
- rm9k_perfcounter_irq_startup,
- rm9k_perfcounter_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_perfcounter_irq_startup,
+ .shutdown = rm9k_perfcounter_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
unsigned int rm9000_perfcount_irq;
diff -urN --exclude=.hg linux-2.6.12/arch/mips/kernel/irq_cpu.c linux-2.6.12-armirq/arch/mips/kernel/irq_cpu.c
--- linux-2.6.12/arch/mips/kernel/irq_cpu.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/kernel/irq_cpu.c 2005-07-13 14:34:11.000000000 +0200
@@ -92,14 +92,13 @@
}
static hw_irq_controller mips_cpu_irq_controller = {
- "MIPS",
- mips_cpu_irq_startup,
- mips_cpu_irq_shutdown,
- mips_cpu_irq_enable,
- mips_cpu_irq_disable,
- mips_cpu_irq_ack,
- mips_cpu_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "MIPS",
+ .startup = mips_cpu_irq_startup,
+ .shutdown = mips_cpu_irq_shutdown,
+ .enable = mips_cpu_irq_enable,
+ .disable = mips_cpu_irq_disable,
+ .ack = mips_cpu_irq_ack,
+ .end = mips_cpu_irq_end,
};
diff -urN --exclude=.hg linux-2.6.12/arch/mips/lasat/interrupt.c linux-2.6.12-armirq/arch/mips/lasat/interrupt.c
--- linux-2.6.12/arch/mips/lasat/interrupt.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/lasat/interrupt.c 2005-07-13 14:34:11.000000000 +0200
@@ -71,14 +71,13 @@
}
static struct hw_interrupt_type lasat_irq_type = {
- "Lasat",
- startup_lasat_irq,
- shutdown_lasat_irq,
- enable_lasat_irq,
- disable_lasat_irq,
- mask_and_ack_lasat_irq,
- end_lasat_irq,
- NULL
+ .typename = "Lasat",
+ .startup = startup_lasat_irq,
+ .shutdown = shutdown_lasat_irq,
+ .enable = enable_lasat_irq,
+ .disable = disable_lasat_irq,
+ .ack = mask_and_ack_lasat_irq,
+ .end = end_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/mips-boards/atlas/atlas_int.c linux-2.6.12-armirq/arch/mips/mips-boards/atlas/atlas_int.c
--- linux-2.6.12/arch/mips/mips-boards/atlas/atlas_int.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/mips-boards/atlas/atlas_int.c 2005-07-13 14:34:11.000000000 +0200
@@ -76,14 +76,13 @@
}
static struct hw_interrupt_type atlas_irq_type = {
- "Atlas",
- startup_atlas_irq,
- shutdown_atlas_irq,
- enable_atlas_irq,
- disable_atlas_irq,
- mask_and_ack_atlas_irq,
- end_atlas_irq,
- NULL
+ .typename = "Atlas",
+ .startup = startup_atlas_irq,
+ .shutdown = shutdown_atlas_irq,
+ .enable = enable_atlas_irq,
+ .disable = disable_atlas_irq,
+ .ack = mask_and_ack_atlas_irq,
+ .end = end_atlas_irq,
};
static inline int ls1bit32(unsigned int x)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/momentum/ocelot_c/cpci-irq.c linux-2.6.12-armirq/arch/mips/momentum/ocelot_c/cpci-irq.c
--- linux-2.6.12/arch/mips/momentum/ocelot_c/cpci-irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/momentum/ocelot_c/cpci-irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -129,14 +129,13 @@
#define shutdown_cpci_irq disable_cpci_irq
struct hw_interrupt_type cpci_irq_type = {
- "CPCI/FPGA",
- startup_cpci_irq,
- shutdown_cpci_irq,
- enable_cpci_irq,
- disable_cpci_irq,
- mask_and_ack_cpci_irq,
- end_cpci_irq,
- NULL
+ .typename = "CPCI/FPGA",
+ .startup = startup_cpci_irq,
+ .shutdown = shutdown_cpci_irq,
+ .enable = enable_cpci_irq,
+ .disable = disable_cpci_irq,
+ .ack = mask_and_ack_cpci_irq,
+ .end = end_cpci_irq,
};
void cpci_irq_init(void)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/momentum/ocelot_c/uart-irq.c linux-2.6.12-armirq/arch/mips/momentum/ocelot_c/uart-irq.c
--- linux-2.6.12/arch/mips/momentum/ocelot_c/uart-irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/momentum/ocelot_c/uart-irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -122,14 +122,13 @@
#define shutdown_uart_irq disable_uart_irq
struct hw_interrupt_type uart_irq_type = {
- "UART/FPGA",
- startup_uart_irq,
- shutdown_uart_irq,
- enable_uart_irq,
- disable_uart_irq,
- mask_and_ack_uart_irq,
- end_uart_irq,
- NULL
+ .typename = "UART/FPGA",
+ .startup = startup_uart_irq,
+ .shutdown = shutdown_uart_irq,
+ .enable = enable_uart_irq,
+ .disable = disable_uart_irq,
+ .ack = mask_and_ack_uart_irq,
+ .end = end_uart_irq,
};
void uart_irq_init(void)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/sgi-ip32/ip32-irq.c linux-2.6.12-armirq/arch/mips/sgi-ip32/ip32-irq.c
--- linux-2.6.12/arch/mips/sgi-ip32/ip32-irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/sgi-ip32/ip32-irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -163,14 +163,13 @@
#define mask_and_ack_cpu_irq disable_cpu_irq
static struct hw_interrupt_type ip32_cpu_interrupt = {
- "IP32 CPU",
- startup_cpu_irq,
- shutdown_cpu_irq,
- enable_cpu_irq,
- disable_cpu_irq,
- mask_and_ack_cpu_irq,
- end_cpu_irq,
- NULL
+ .typename = "IP32 CPU",
+ .startup = startup_cpu_irq,
+ .shutdown = shutdown_cpu_irq,
+ .enable = enable_cpu_irq,
+ .disable = disable_cpu_irq,
+ .ack = mask_and_ack_cpu_irq,
+ .end = end_cpu_irq,
};
/*
@@ -234,14 +233,13 @@
#define shutdown_crime_irq disable_crime_irq
static struct hw_interrupt_type ip32_crime_interrupt = {
- "IP32 CRIME",
- startup_crime_irq,
- shutdown_crime_irq,
- enable_crime_irq,
- disable_crime_irq,
- mask_and_ack_crime_irq,
- end_crime_irq,
- NULL
+ .typename = "IP32 CRIME",
+ .startup = startup_crime_irq,
+ .shutdown = shutdown_crime_irq,
+ .enable = enable_crime_irq,
+ .disable = disable_crime_irq,
+ .ack = mask_and_ack_crime_irq,
+ .end = end_crime_irq,
};
/*
@@ -294,14 +292,13 @@
#define mask_and_ack_macepci_irq disable_macepci_irq
static struct hw_interrupt_type ip32_macepci_interrupt = {
- "IP32 MACE PCI",
- startup_macepci_irq,
- shutdown_macepci_irq,
- enable_macepci_irq,
- disable_macepci_irq,
- mask_and_ack_macepci_irq,
- end_macepci_irq,
- NULL
+ .typename = "IP32 MACE PCI",
+ .startup = startup_macepci_irq,
+ .shutdown = shutdown_macepci_irq,
+ .enable = enable_macepci_irq,
+ .disable = disable_macepci_irq,
+ .ack = mask_and_ack_macepci_irq,
+ .end = end_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
@@ -425,14 +422,13 @@
#define shutdown_maceisa_irq disable_maceisa_irq
static struct hw_interrupt_type ip32_maceisa_interrupt = {
- "IP32 MACE ISA",
- startup_maceisa_irq,
- shutdown_maceisa_irq,
- enable_maceisa_irq,
- disable_maceisa_irq,
- mask_and_ack_maceisa_irq,
- end_maceisa_irq,
- NULL
+ .typename = "IP32 MACE ISA",
+ .startup = startup_maceisa_irq,
+ .shutdown = shutdown_maceisa_irq,
+ .enable = enable_maceisa_irq,
+ .disable = disable_maceisa_irq,
+ .ack = mask_and_ack_maceisa_irq,
+ .end = end_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
@@ -476,14 +472,13 @@
#define mask_and_ack_mace_irq disable_mace_irq
static struct hw_interrupt_type ip32_mace_interrupt = {
- "IP32 MACE",
- startup_mace_irq,
- shutdown_mace_irq,
- enable_mace_irq,
- disable_mace_irq,
- mask_and_ack_mace_irq,
- end_mace_irq,
- NULL
+ .typename = "IP32 MACE",
+ .startup = startup_mace_irq,
+ .shutdown = shutdown_mace_irq,
+ .enable = enable_mace_irq,
+ .disable = disable_mace_irq,
+ .ack = mask_and_ack_mace_irq,
+ .end = end_mace_irq,
};
static void ip32_unknown_interrupt(struct pt_regs *regs)
diff -urN --exclude=.hg linux-2.6.12/arch/mips/sibyte/sb1250/irq.c linux-2.6.12-armirq/arch/mips/sibyte/sb1250/irq.c
--- linux-2.6.12/arch/mips/sibyte/sb1250/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/sibyte/sb1250/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -71,17 +71,15 @@
#endif
static struct hw_interrupt_type sb1250_irq_type = {
- "SB1250-IMR",
- startup_sb1250_irq,
- shutdown_sb1250_irq,
- enable_sb1250_irq,
- disable_sb1250_irq,
- ack_sb1250_irq,
- end_sb1250_irq,
+ .typename = "SB1250-IMR",
+ .startup = startup_sb1250_irq,
+ .shutdown = shutdown_sb1250_irq,
+ .enable = enable_sb1250_irq,
+ .disable = disable_sb1250_irq,
+ .ack = ack_sb1250_irq,
+ .end = end_sb1250_irq,
#ifdef CONFIG_SMP
- sb1250_set_affinity
-#else
- NULL
+ .set_affinity = sb1250_set_affinity
#endif
};
diff -urN --exclude=.hg linux-2.6.12/arch/mips/sni/irq.c linux-2.6.12-armirq/arch/mips/sni/irq.c
--- linux-2.6.12/arch/mips/sni/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/sni/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -58,14 +58,13 @@
}
static struct hw_interrupt_type pciasic_irq_type = {
- "ASIC-PCI",
- startup_pciasic_irq,
- shutdown_pciasic_irq,
- enable_pciasic_irq,
- disable_pciasic_irq,
- mask_and_ack_pciasic_irq,
- end_pciasic_irq,
- NULL
+ .typename = "ASIC-PCI",
+ .startup = startup_pciasic_irq,
+ .shutdown = shutdown_pciasic_irq,
+ .enable = enable_pciasic_irq,
+ .disable = disable_pciasic_irq,
+ .ack = mask_and_ack_pciasic_irq,
+ .end = end_pciasic_irq,
};
/*
diff -urN --exclude=.hg linux-2.6.12/arch/mips/vr4181/common/irq.c linux-2.6.12-armirq/arch/mips/vr4181/common/irq.c
--- linux-2.6.12/arch/mips/vr4181/common/irq.c 2005-07-18 15:41:27.000000000 +0200
+++ linux-2.6.12-armirq/arch/mips/vr4181/common/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -86,14 +86,13 @@
}
static hw_irq_controller sys_irq_controller = {
- "vr4181_sys_irq",
- sys_irq_startup,
- sys_irq_shutdown,
- sys_irq_enable,
- sys_irq_disable,
- sys_irq_ack,
- sys_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vr4181_sys_irq",
+ .startup = sys_irq_startup,
+ .shutdown = sys_irq_shutdown,
+ .enable = sys_irq_enable,
+ .disable = sys_irq_disable,
+ .ack = sys_irq_ack,
+ .end = sys_irq_end,
};
/* ---------------------- gpio irq ------------------------ */
@@ -162,14 +161,13 @@
}
static hw_irq_controller gpio_irq_controller = {
- "vr4181_gpio_irq",
- gpio_irq_startup,
- gpio_irq_shutdown,
- gpio_irq_enable,
- gpio_irq_disable,
- gpio_irq_ack,
- gpio_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vr4181_gpio_irq",
+ .startup = gpio_irq_startup,
+ .shutdown = gpio_irq_shutdown,
+ .enable = gpio_irq_enable,
+ .disable = gpio_irq_disable,
+ .ack = gpio_irq_ack,
+ .end = gpio_irq_end,
};
/* --------------------- IRQ init stuff ---------------------- */
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/platforms/adir_pic.c linux-2.6.12-armirq/arch/ppc/platforms/adir_pic.c
--- linux-2.6.12/arch/ppc/platforms/adir_pic.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/platforms/adir_pic.c 2005-07-13 14:34:11.000000000 +0200
@@ -73,14 +73,10 @@
}
static struct hw_interrupt_type adir_onboard_pic = {
- " ADIR PIC ",
- NULL,
- NULL,
- adir_onboard_pic_enable, /* unmask */
- adir_onboard_pic_disable, /* mask */
- adir_onboard_pic_disable, /* mask and ack */
- NULL,
- NULL
+ .typename = " ADIR PIC ",
+ .enable = adir_onboard_pic_enable, /* unmask */
+ .disable = adir_onboard_pic_disable, /* mask */
+ .ack = adir_onboard_pic_disable, /* mask and ack */
};
static struct irqaction noop_action = {
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/syslib/cpc700_pic.c linux-2.6.12-armirq/arch/ppc/syslib/cpc700_pic.c
--- linux-2.6.12/arch/ppc/syslib/cpc700_pic.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/syslib/cpc700_pic.c 2005-07-13 14:34:11.000000000 +0200
@@ -90,14 +90,10 @@
}
static struct hw_interrupt_type cpc700_pic = {
- "CPC700 PIC",
- NULL,
- NULL,
- cpc700_unmask_irq,
- cpc700_mask_irq,
- cpc700_mask_and_ack_irq,
- NULL,
- NULL
+ .typename = "CPC700 PIC",
+ .enable = cpc700_unmask_irq,
+ .disable = cpc700_mask_irq,
+ .ack = cpc700_mask_and_ack_irq,
};
__init static void
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/syslib/i8259.c linux-2.6.12-armirq/arch/ppc/syslib/i8259.c
--- linux-2.6.12/arch/ppc/syslib/i8259.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/syslib/i8259.c 2005-07-13 14:34:11.000000000 +0200
@@ -129,14 +129,11 @@
}
struct hw_interrupt_type i8259_pic = {
- " i8259 ",
- NULL,
- NULL,
- i8259_unmask_irq,
- i8259_mask_irq,
- i8259_mask_and_ack_irq,
- i8259_end_irq,
- NULL
+ .typename = " i8259 ",
+ .enable = i8259_unmask_irq,
+ .disable = i8259_mask_irq,
+ .ack = i8259_mask_and_ack_irq,
+ .end = i8259_end_irq,
};
static struct resource pic1_iores = {
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/syslib/open_pic2.c linux-2.6.12-armirq/arch/ppc/syslib/open_pic2.c
--- linux-2.6.12/arch/ppc/syslib/open_pic2.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/syslib/open_pic2.c 2005-07-13 14:34:11.000000000 +0200
@@ -83,13 +83,11 @@
static void openpic2_ack_irq(unsigned int irq_nr);
struct hw_interrupt_type open_pic2 = {
- " OpenPIC2 ",
- NULL,
- NULL,
- openpic2_enable_irq,
- openpic2_disable_irq,
- openpic2_ack_irq,
- openpic2_end_irq,
+ .typename = " OpenPIC2 ",
+ .enable = openpic2_enable_irq,
+ .disable = openpic2_disable_irq,
+ .ack = openpic2_ack_irq,
+ .end = openpic2_end_irq,
};
/*
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/syslib/ppc403_pic.c linux-2.6.12-armirq/arch/ppc/syslib/ppc403_pic.c
--- linux-2.6.12/arch/ppc/syslib/ppc403_pic.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/syslib/ppc403_pic.c 2005-07-13 14:34:11.000000000 +0200
@@ -34,13 +34,10 @@
static void ppc403_aic_disable_and_ack(unsigned int irq);
static struct hw_interrupt_type ppc403_aic = {
- "403GC AIC",
- NULL,
- NULL,
- ppc403_aic_enable,
- ppc403_aic_disable,
- ppc403_aic_disable_and_ack,
- 0
+ .typename = "403GC AIC",
+ .enable = ppc403_aic_enable,
+ .disable = ppc403_aic_disable,
+ .ack = ppc403_aic_disable_and_ack,
};
int
diff -urN --exclude=.hg linux-2.6.12/arch/ppc/syslib/xilinx_pic.c linux-2.6.12-armirq/arch/ppc/syslib/xilinx_pic.c
--- linux-2.6.12/arch/ppc/syslib/xilinx_pic.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/ppc/syslib/xilinx_pic.c 2005-07-13 14:34:11.000000000 +0200
@@ -79,14 +79,11 @@
}
static struct hw_interrupt_type xilinx_intc = {
- "Xilinx Interrupt Controller",
- NULL,
- NULL,
- xilinx_intc_enable,
- xilinx_intc_disable,
- xilinx_intc_disable_and_ack,
- xilinx_intc_end,
- 0
+ .typename = "Xilinx Interrupt Controller",
+ .enable = xilinx_intc_enable,
+ .disable = xilinx_intc_disable,
+ .ack = xilinx_intc_disable_and_ack,
+ .end = xilinx_intc_end,
};
int
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/adx/irq_maskreg.c linux-2.6.12-armirq/arch/sh/boards/adx/irq_maskreg.c
--- linux-2.6.12/arch/sh/boards/adx/irq_maskreg.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/adx/irq_maskreg.c 2005-07-13 14:34:11.000000000 +0200
@@ -37,13 +37,13 @@
/* hw_interrupt_type */
static struct hw_interrupt_type maskreg_irq_type = {
- " Mask Register",
- startup_maskreg_irq,
- shutdown_maskreg_irq,
- enable_maskreg_irq,
- disable_maskreg_irq,
- mask_and_ack_maskreg,
- end_maskreg_irq
+ .typename = " Mask Register",
+ .startup = startup_maskreg_irq,
+ .shutdown = shutdown_maskreg_irq,
+ .enable = enable_maskreg_irq,
+ .disable = disable_maskreg_irq,
+ .ack = mask_and_ack_maskreg,
+ .end = end_maskreg_irq
};
/* actual implementatin */
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/bigsur/irq.c linux-2.6.12-armirq/arch/sh/boards/bigsur/irq.c
--- linux-2.6.12/arch/sh/boards/bigsur/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/bigsur/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -228,23 +228,23 @@
/* Define the IRQ structures for the L1 and L2 IRQ types */
static struct hw_interrupt_type bigsur_l1irq_type = {
- "BigSur-CPLD-Level1-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l1irq,
- disable_bigsur_l1irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
+ .typename = "BigSur-CPLD-Level1-IRQ",
+ .startup = startup_bigsur_irq,
+ .shutdown = shutdown_bigsur_irq,
+ .enable = enable_bigsur_l1irq,
+ .disable = disable_bigsur_l1irq,
+ .ack = mask_and_ack_bigsur,
+ .end = end_bigsur_irq
};
static struct hw_interrupt_type bigsur_l2irq_type = {
- "BigSur-CPLD-Level2-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l2irq,
- disable_bigsur_l2irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
+ .typename = "BigSur-CPLD-Level2-IRQ",
+ .startup = startup_bigsur_irq,
+ .shutdown =shutdown_bigsur_irq,
+ .enable = enable_bigsur_l2irq,
+ .disable = disable_bigsur_l2irq,
+ .ack = mask_and_ack_bigsur,
+ .end = end_bigsur_irq
};
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/cqreek/irq.c linux-2.6.12-armirq/arch/sh/boards/cqreek/irq.c
--- linux-2.6.12/arch/sh/boards/cqreek/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/cqreek/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -83,13 +83,13 @@
}
static struct hw_interrupt_type cqreek_irq_type = {
- "CqREEK-IRQ",
- startup_cqreek_irq,
- shutdown_cqreek_irq,
- enable_cqreek_irq,
- disable_cqreek_irq,
- mask_and_ack_cqreek,
- end_cqreek_irq
+ .typename = "CqREEK-IRQ",
+ .startup = startup_cqreek_irq,
+ .shutdown = shutdown_cqreek_irq,
+ .enable = enable_cqreek_irq,
+ .disable = disable_cqreek_irq,
+ .ack = mask_and_ack_cqreek,
+ .end = end_cqreek_irq
};
int cqreek_has_ide, cqreek_has_isa;
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/harp/irq.c linux-2.6.12-armirq/arch/sh/boards/harp/irq.c
--- linux-2.6.12/arch/sh/boards/harp/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/harp/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -39,13 +39,13 @@
}
static struct hw_interrupt_type harp_irq_type = {
- "Harp-IRQ",
- startup_harp_irq,
- shutdown_harp_irq,
- enable_harp_irq,
- disable_harp_irq,
- mask_and_ack_harp,
- end_harp_irq
+ .typename = "Harp-IRQ",
+ .startup = startup_harp_irq,
+ .shutdown = shutdown_harp_irq,
+ .enable = enable_harp_irq,
+ .disable = disable_harp_irq,
+ .ack = mask_and_ack_harp,
+ .end = end_harp_irq
};
static void disable_harp_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/overdrive/irq.c linux-2.6.12-armirq/arch/sh/boards/overdrive/irq.c
--- linux-2.6.12/arch/sh/boards/overdrive/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/overdrive/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -86,13 +86,13 @@
}
static struct hw_interrupt_type od_irq_type = {
- "Overdrive-IRQ",
- startup_od_irq,
- shutdown_od_irq,
- enable_od_irq,
- disable_od_irq,
- mask_and_ack_od,
- end_od_irq
+ .typename = "Overdrive-IRQ",
+ .startup = startup_od_irq,
+ .shutdown = shutdown_od_irq,
+ .enable = enable_od_irq,
+ .disable = disable_od_irq,
+ .ack = mask_and_ack_od,
+ .end = end_od_irq
};
static void disable_od_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/renesas/hs7751rvoip/irq.c linux-2.6.12-armirq/arch/sh/boards/renesas/hs7751rvoip/irq.c
--- linux-2.6.12/arch/sh/boards/renesas/hs7751rvoip/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/renesas/hs7751rvoip/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -74,13 +74,13 @@
}
static struct hw_interrupt_type hs7751rvoip_irq_type = {
- "HS7751RVoIP IRQ",
- startup_hs7751rvoip_irq,
- shutdown_hs7751rvoip_irq,
- enable_hs7751rvoip_irq,
- disable_hs7751rvoip_irq,
- ack_hs7751rvoip_irq,
- end_hs7751rvoip_irq,
+ .typename = "HS7751RVoIP IRQ",
+ .startup = startup_hs7751rvoip_irq,
+ .shutdown = shutdown_hs7751rvoip_irq,
+ .enable = enable_hs7751rvoip_irq,
+ .disable = disable_hs7751rvoip_irq,
+ .ack = ack_hs7751rvoip_irq,
+ .end = end_hs7751rvoip_irq,
};
static void make_hs7751rvoip_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/renesas/rts7751r2d/irq.c linux-2.6.12-armirq/arch/sh/boards/renesas/rts7751r2d/irq.c
--- linux-2.6.12/arch/sh/boards/renesas/rts7751r2d/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/renesas/rts7751r2d/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -88,13 +88,13 @@
}
static struct hw_interrupt_type rts7751r2d_irq_type = {
- "RTS7751R2D IRQ",
- startup_rts7751r2d_irq,
- shutdown_rts7751r2d_irq,
- enable_rts7751r2d_irq,
- disable_rts7751r2d_irq,
- ack_rts7751r2d_irq,
- end_rts7751r2d_irq,
+ .typename = "RTS7751R2D IRQ",
+ .startup = startup_rts7751r2d_irq,
+ .shutdown = shutdown_rts7751r2d_irq,
+ .enable = enable_rts7751r2d_irq,
+ .disable = disable_rts7751r2d_irq,
+ .ack = ack_rts7751r2d_irq,
+ .end = end_rts7751r2d_irq,
};
static void make_rts7751r2d_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/renesas/systemh/irq.c linux-2.6.12-armirq/arch/sh/boards/renesas/systemh/irq.c
--- linux-2.6.12/arch/sh/boards/renesas/systemh/irq.c 2005-07-18 15:41:28.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/renesas/systemh/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -35,13 +35,13 @@
/* hw_interrupt_type */
static struct hw_interrupt_type systemh_irq_type = {
- " SystemH Register",
- startup_systemh_irq,
- shutdown_systemh_irq,
- enable_systemh_irq,
- disable_systemh_irq,
- mask_and_ack_systemh,
- end_systemh_irq
+ .typename = " SystemH Register",
+ .startup = startup_systemh_irq,
+ .shutdown = shutdown_systemh_irq,
+ .enable = enable_systemh_irq,
+ .disable = disable_systemh_irq,
+ .ack = mask_and_ack_systemh,
+ .end = end_systemh_irq
};
static unsigned int startup_systemh_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/boards/superh/microdev/irq.c linux-2.6.12-armirq/arch/sh/boards/superh/microdev/irq.c
--- linux-2.6.12/arch/sh/boards/superh/microdev/irq.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/boards/superh/microdev/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -83,13 +83,13 @@
}
static struct hw_interrupt_type microdev_irq_type = {
- "MicroDev-IRQ",
- startup_microdev_irq,
- shutdown_microdev_irq,
- enable_microdev_irq,
- disable_microdev_irq,
- mask_and_ack_microdev,
- end_microdev_irq
+ .typename = "MicroDev-IRQ",
+ .startup = startup_microdev_irq,
+ .shutdown = shutdown_microdev_irq,
+ .enable = enable_microdev_irq,
+ .disable = disable_microdev_irq,
+ .ack = mask_and_ack_microdev,
+ .end = end_microdev_irq
};
static void disable_microdev_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/cchips/voyagergx/irq.c linux-2.6.12-armirq/arch/sh/cchips/voyagergx/irq.c
--- linux-2.6.12/arch/sh/cchips/voyagergx/irq.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/cchips/voyagergx/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -87,13 +87,13 @@
}
static struct hw_interrupt_type voyagergx_irq_type = {
- "VOYAGERGX-IRQ",
- startup_voyagergx_irq,
- shutdown_voyagergx_irq,
- enable_voyagergx_irq,
- disable_voyagergx_irq,
- mask_and_ack_voyagergx,
- end_voyagergx_irq,
+ .typename = "VOYAGERGX-IRQ",
+ .startup = startup_voyagergx_irq,
+ .shutdown = shutdown_voyagergx_irq,
+ .enable = enable_voyagergx_irq,
+ .disable = disable_voyagergx_irq,
+ .ack = mask_and_ack_voyagergx,
+ .end = end_voyagergx_irq,
};
static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/kernel/cpu/irq_imask.c linux-2.6.12-armirq/arch/sh/kernel/cpu/irq_imask.c
--- linux-2.6.12/arch/sh/kernel/cpu/irq_imask.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/kernel/cpu/irq_imask.c 2005-07-13 14:34:11.000000000 +0200
@@ -46,13 +46,13 @@
}
static struct hw_interrupt_type imask_irq_type = {
- "SR.IMASK",
- startup_imask_irq,
- shutdown_imask_irq,
- enable_imask_irq,
- disable_imask_irq,
- mask_and_ack_imask,
- end_imask_irq
+ .typename = "SR.IMASK",
+ .startup = startup_imask_irq,
+ .shutdown = shutdown_imask_irq,
+ .enable = enable_imask_irq,
+ .disable = disable_imask_irq,
+ .ack = mask_and_ack_imask,
+ .end = end_imask_irq
};
void static inline set_interrupt_registers(int ip)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/kernel/cpu/irq_ipr.c linux-2.6.12-armirq/arch/sh/kernel/cpu/irq_ipr.c
--- linux-2.6.12/arch/sh/kernel/cpu/irq_ipr.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/kernel/cpu/irq_ipr.c 2005-07-13 14:34:11.000000000 +0200
@@ -48,13 +48,13 @@
}
static struct hw_interrupt_type ipr_irq_type = {
- "IPR-IRQ",
- startup_ipr_irq,
- shutdown_ipr_irq,
- enable_ipr_irq,
- disable_ipr_irq,
- mask_and_ack_ipr,
- end_ipr_irq
+ .typename = "IPR-IRQ",
+ .startup = startup_ipr_irq,
+ .shutdown = shutdown_ipr_irq,
+ .enable = enable_ipr_irq,
+ .disable = disable_ipr_irq,
+ .ack = mask_and_ack_ipr,
+ .end = end_ipr_irq
};
static void disable_ipr_irq(unsigned int irq)
@@ -142,13 +142,13 @@
}
static struct hw_interrupt_type pint_irq_type = {
- "PINT-IRQ",
- startup_pint_irq,
- shutdown_pint_irq,
- enable_pint_irq,
- disable_pint_irq,
- mask_and_ack_pint,
- end_pint_irq
+ .typename = "PINT-IRQ",
+ .startup = startup_pint_irq,
+ .shutdown = shutdown_pint_irq,
+ .enable = enable_pint_irq,
+ .disable = disable_pint_irq,
+ .ack = mask_and_ack_pint,
+ .end = end_pint_irq
};
static void disable_pint_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh/kernel/cpu/sh4/irq_intc2.c linux-2.6.12-armirq/arch/sh/kernel/cpu/sh4/irq_intc2.c
--- linux-2.6.12/arch/sh/kernel/cpu/sh4/irq_intc2.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh/kernel/cpu/sh4/irq_intc2.c 2005-07-13 14:34:11.000000000 +0200
@@ -48,13 +48,13 @@
}
static struct hw_interrupt_type intc2_irq_type = {
- "INTC2-IRQ",
- startup_intc2_irq,
- shutdown_intc2_irq,
- enable_intc2_irq,
- disable_intc2_irq,
- mask_and_ack_intc2,
- end_intc2_irq
+ .typename = "INTC2-IRQ",
+ .startup = startup_intc2_irq,
+ .shutdown = shutdown_intc2_irq,
+ .enable = enable_intc2_irq,
+ .disable = disable_intc2_irq,
+ .ack = mask_and_ack_intc2,
+ .end = end_intc2_irq
};
static void disable_intc2_irq(unsigned int irq)
diff -urN --exclude=.hg linux-2.6.12/arch/sh64/kernel/irq_intc.c linux-2.6.12-armirq/arch/sh64/kernel/irq_intc.c
--- linux-2.6.12/arch/sh64/kernel/irq_intc.c 2005-07-18 15:41:29.000000000 +0200
+++ linux-2.6.12-armirq/arch/sh64/kernel/irq_intc.c 2005-07-13 14:34:11.000000000 +0200
@@ -107,13 +107,13 @@
static void end_intc_irq(unsigned int irq);
static struct hw_interrupt_type intc_irq_type = {
- "INTC",
- startup_intc_irq,
- shutdown_intc_irq,
- enable_intc_irq,
- disable_intc_irq,
- mask_and_ack_intc,
- end_intc_irq
+ .typename = "INTC",
+ .startup = startup_intc_irq,
+ .shutdown = shutdown_intc_irq,
+ .enable = enable_intc_irq,
+ .disable = disable_intc_irq,
+ .ack = mask_and_ack_intc,
+ .end = end_intc_irq
};
static int irlm; /* IRL mode */
diff -urN --exclude=.hg linux-2.6.12/arch/v850/kernel/irq.c linux-2.6.12-armirq/arch/v850/kernel/irq.c
--- linux-2.6.12/arch/v850/kernel/irq.c 2005-07-18 15:41:30.000000000 +0200
+++ linux-2.6.12-armirq/arch/v850/kernel/irq.c 2005-07-13 14:34:11.000000000 +0200
@@ -67,13 +67,13 @@
#define end_none enable_none
struct hw_interrupt_type no_irq_type = {
- "none",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "none",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
volatile unsigned long irq_err_count, spurious_count;
diff -urN --exclude=.hg linux-2.6.12/arch/v850/kernel/setup.c linux-2.6.12-armirq/arch/v850/kernel/setup.c
--- linux-2.6.12/arch/v850/kernel/setup.c 2005-07-18 15:41:30.000000000 +0200
+++ linux-2.6.12-armirq/arch/v850/kernel/setup.c 2005-07-13 14:34:11.000000000 +0200
@@ -128,13 +128,13 @@
}
static struct hw_interrupt_type nmi_irq_type = {
- "NMI",
- irq_zero, /* startup */
- irq_nop, /* shutdown */
- irq_nop, /* enable */
- irq_nop, /* disable */
- irq_nop, /* ack */
- nmi_end, /* end */
+ .typename = "NMI",
+ .startup = irq_zero, /* startup */
+ .shutdown = irq_nop, /* shutdown */
+ .enable = irq_nop, /* enable */
+ .disable = irq_nop, /* disable */
+ .ack = irq_nop, /* ack */
+ .end = nmi_end, /* end */
};
void __init init_IRQ (void)
diff -urN --exclude=.hg linux-2.6.12/arch/v850/kernel/sim.c linux-2.6.12-armirq/arch/v850/kernel/sim.c
--- linux-2.6.12/arch/v850/kernel/sim.c 2005-07-18 15:41:30.000000000 +0200
+++ linux-2.6.12-armirq/arch/v850/kernel/sim.c 2005-07-13 14:34:11.000000000 +0200
@@ -73,13 +73,13 @@
static unsigned irq_zero (unsigned irq) { return 0; }
static struct hw_interrupt_type sim_irq_type = {
- "IRQ",
- irq_zero, /* startup */
- irq_nop, /* shutdown */
- irq_nop, /* enable */
- irq_nop, /* disable */
- irq_nop, /* ack */
- irq_nop, /* end */
+ .typename = "IRQ",
+ .startup = irq_zero, /* startup */
+ .shutdown = irq_nop, /* shutdown */
+ .enable = irq_nop, /* enable */
+ .disable = irq_nop, /* disable */
+ .ack = irq_nop, /* ack */
+ .end = irq_nop, /* end */
};
void __init mach_init_irqs (void)
diff -urN --exclude=.hg linux-2.6.12/arch/x86_64/kernel/i8259.c linux-2.6.12-armirq/arch/x86_64/kernel/i8259.c
--- linux-2.6.12/arch/x86_64/kernel/i8259.c 2005-07-18 15:41:30.000000000 +0200
+++ linux-2.6.12-armirq/arch/x86_64/kernel/i8259.c 2005-07-13 14:34:11.000000000 +0200
@@ -157,14 +157,13 @@
}
static struct hw_interrupt_type i8259A_irq_type = {
- "XT-PIC",
- startup_8259A_irq,
- shutdown_8259A_irq,
- enable_8259A_irq,
- disable_8259A_irq,
- mask_and_ack_8259A,
- end_8259A_irq,
- NULL
+ .typename = "XT-PIC",
+ .startup = startup_8259A_irq,
+ .shutdown = shutdown_8259A_irq,
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
diff -urN --exclude=.hg linux-2.6.12/drivers/char/s3c2410-rtc.c linux-2.6.12-armirq/drivers/char/s3c2410-rtc.c
--- linux-2.6.12/drivers/char/s3c2410-rtc.c 2005-07-18 15:41:33.000000000 +0200
+++ linux-2.6.12-armirq/drivers/char/s3c2410-rtc.c 2005-07-13 14:34:11.000000000 +0200
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/drivers/input/serio/sa1111ps2.c linux-2.6.12-armirq/drivers/input/serio/sa1111ps2.c
--- linux-2.6.12/drivers/input/serio/sa1111ps2.c 2005-07-18 15:41:34.000000000 +0200
+++ linux-2.6.12-armirq/drivers/input/serio/sa1111ps2.c 2005-07-13 14:34:11.000000000 +0200
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/drivers/net/smc91x.c linux-2.6.12-armirq/drivers/net/smc91x.c
--- linux-2.6.12/drivers/net/smc91x.c 2005-07-18 15:41:42.000000000 +0200
+++ linux-2.6.12-armirq/drivers/net/smc91x.c 2005-07-11 16:13:31.000000000 +0200
@@ -74,6 +74,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1985,7 +1986,7 @@
if (retval)
goto err_out;
- set_irq_type(dev->irq, IRQT_RISING);
+ SMC_SET_IRQ_TYPE(dev->irq, IRQT_RISING);
#ifdef SMC_USE_PXA_DMA
{
diff -urN --exclude=.hg linux-2.6.12/drivers/net/smc91x.h linux-2.6.12-armirq/drivers/net/smc91x.h
--- linux-2.6.12/drivers/net/smc91x.h 2005-07-18 15:41:42.000000000 +0200
+++ linux-2.6.12-armirq/drivers/net/smc91x.h 2005-07-11 16:14:21.000000000 +0200
@@ -90,7 +90,7 @@
__l--; \
} \
} while (0)
-#define set_irq_type(irq, type)
+#define SMC_SET_IRQ_TYPE(irq, type)
#elif defined(CONFIG_SA1100_PLEB)
/* We can only do 16-bit reads and writes in the static memory space. */
@@ -109,7 +109,7 @@
#define SMC_outw(v, a, r) outw(v, (a) + (r))
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
-#define set_irq_type(irq, type) do {} while (0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while (0)
#elif defined(CONFIG_SA1100_ASSABET)
@@ -199,7 +199,7 @@
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
-#define set_irq_type(irq, type) do {} while(0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while(0)
#elif defined(CONFIG_ISA)
@@ -227,7 +227,7 @@
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
-#define set_irq_type(irq, type) do {} while(0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while(0)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
@@ -300,6 +300,9 @@
#endif
+#ifndef SMC_SET_IRQ_TYPE
+#define SMC_SET_IRQ_TYPE set_irq_type
+#endif
#ifdef SMC_USE_PXA_DMA
/*
diff -urN --exclude=.hg linux-2.6.12/drivers/pcmcia/soc_common.c linux-2.6.12-armirq/drivers/pcmcia/soc_common.c
--- linux-2.6.12/drivers/pcmcia/soc_common.c 2005-07-18 15:41:43.000000000 +0200
+++ linux-2.6.12-armirq/drivers/pcmcia/soc_common.c 2005-07-13 14:34:11.000000000 +0200
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
diff -urN --exclude=.hg linux-2.6.12/include/asm-arm/hw_irq.h linux-2.6.12-armirq/include/asm-arm/hw_irq.h
--- linux-2.6.12/include/asm-arm/hw_irq.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12-armirq/include/asm-arm/hw_irq.h 2005-07-13 14:34:11.000000000 +0200
@@ -0,0 +1,9 @@
+/*
+ * Nothing to see here yet
+ */
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+#include
+
+#endif
diff -urN --exclude=.hg linux-2.6.12/include/asm-arm/irq.h linux-2.6.12-armirq/include/asm-arm/irq.h
--- linux-2.6.12/include/asm-arm/irq.h 2005-07-18 15:41:56.000000000 +0200
+++ linux-2.6.12-armirq/include/asm-arm/irq.h 2005-07-13 14:34:11.000000000 +0200
@@ -19,16 +19,10 @@
#define NO_IRQ ((unsigned int)(-1))
#endif
-struct irqaction;
-
-extern void disable_irq_nosync(unsigned int);
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-#define __IRQT_FALEDGE (1 << 0)
-#define __IRQT_RISEDGE (1 << 1)
-#define __IRQT_LOWLVL (1 << 2)
-#define __IRQT_HIGHLVL (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)
@@ -36,16 +30,9 @@
#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 *);
+/* FIXME_TGLX */
+#define IRQT_PROBE (1 << 7)
#endif
diff -urN --exclude=.hg linux-2.6.12/include/asm-arm/mach/irq.h linux-2.6.12-armirq/include/asm-arm/mach/irq.h
--- linux-2.6.12/include/asm-arm/mach/irq.h 2005-07-18 15:41:56.000000000 +0200
+++ linux-2.6.12-armirq/include/asm-arm/mach/irq.h 2005-07-13 14:34:11.000000000 +0200
@@ -10,86 +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 (*type)(unsigned int, unsigned int);
- /*
- * Set wakeup-enable on the selected IRQ
- */
- int (*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 *chipdata;
- 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;
-
- struct proc_dir_entry *procdir;
-
-#ifdef CONFIG_SMP
- cpumask_t affinity;
- unsigned int cpu;
-#endif
+#include
- /*
- * IRQ lock detection
- */
- unsigned int lck_cnt;
- unsigned int lck_pc;
- unsigned int lck_jif;
-};
-
-extern struct irqdesc irq_desc[];
+struct seq_file;
/*
* This is internal. Do not use it.
@@ -97,31 +20,52 @@
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.
*/
#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].chipdata = d; } while (0)
-#define get_irq_chipdata(irq) (irq_desc[irq].chipdata)
-void set_irq_chip(unsigned int irq, struct irqchip *);
+
+#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_flags(unsigned int irq, unsigned int flags);
#define IRQF_VALID (1 << 0)
#define IRQF_PROBE (1 << 1)
#define IRQF_NOAUTOEN (1 << 2)
+/* ARM uses the retrigger functions in desc->chip or software retrigger */
+static inline void hw_resend_irq(struct irq_type *t, unsigned int i) {}
+
/*
- * Built-in IRQ handlers.
+ * Hack alert. This is for easy migration, but should be changed in the source
*/
-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 do_level_IRQ (&default_level_type)
+#define do_edge_IRQ (&default_edge_type)
+#define do_simple_IRQ (&default_simple_type)
+
+/* Hack to get around set_irq_chained_handler(nr,NULL) problem */
+#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)
+
+/* FIXME */
+#define ack_bad_irq(irq) do {} while (0)
#endif
diff -urN --exclude=.hg linux-2.6.12/include/linux/irq.h linux-2.6.12-armirq/include/linux/irq.h
--- linux-2.6.12/include/linux/irq.h 2005-07-18 15:42:03.000000000 +0200
+++ linux-2.6.12-armirq/include/linux/irq.h 2005-07-13 14:34:11.000000000 +0200
@@ -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
#if !defined(CONFIG_ARCH_S390)
@@ -33,65 +25,217 @@
#define IRQ_LEVEL 64 /* IRQ level triggered */
#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
#define IRQ_PER_CPU 256 /* IRQ is per CPU */
+#define IRQ_NOPROBE 512 /* IRQ is not valid for probing */
+#define IRQ_NOREQUEST 1024 /* IRQ cannot be requested */
/*
- * Interrupt controller descriptor. This is all we need
- * to describe about the low-level hardware.
+ * IRQ types
*/
-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);
+#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 */
+
+/*
+ * 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;
};
-typedef struct hw_interrupt_type hw_irq_controller;
+struct irq_desc;
+struct irq_type;
-/*
- * 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_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. (Note: This will 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.
+ */
+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
+};
+
+/**
+ * struct irq_desc - interrupt descriptor
+ *
+ * @lock: locking for SMP
+ * @status: status information
+ * @handler: interrupt type dependent handler functions,
+ * (this will be renamed to 'type')
+ * @chip: low level hardware access functions - comes from type
+ * @action: the irq action chain
+ * @depth: disable-depth, for nested irq_disable() calls
+ * @irq_count: stats field to detect stalled irqs
+ * @irqs_unhandled: stats field for spurious unhandled interrupts
+ * @data: data for the type handlers
*
* 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;
-} ____cacheline_aligned irq_desc_t;
+struct irq_desc {
+ spinlock_t lock;
+ unsigned int status;
+ /* (*type) Will be renamed !*/
+ struct irq_type *handler;
+ struct irq_chip *chip;
+ struct irqaction *action;
+ unsigned long depth;
+ unsigned long irq_count;
+ unsigned long irqs_unhandled;
+ void *data;
+} ____cacheline_aligned;
-extern irq_desc_t irq_desc [NR_IRQS];
+extern struct irq_desc irq_desc[NR_IRQS];
+
+/*
+ * 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_desc irq_desc_t;
+typedef struct irq_type hw_irq_controller;
#include /* the arch dependent stuff */
+/* Setup an interrupt. Used for static setups in early init */
extern int setup_irq(unsigned int irq, struct irqaction * new);
#ifdef CONFIG_GENERIC_HARDIRQS
-extern cpumask_t irq_affinity[NR_IRQS];
-extern int no_irq_affinity;
-extern int noirqdebug_setup(char *str);
+/* 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_lock_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);
-extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret);
-extern void report_bad_irq(unsigned int irq, irq_desc_t *desc, int action_ret);
-extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+/* Handling of unhandled and spurious interrupts */
+extern void note_interrupt(unsigned int irq, struct irq_desc *desc, int action_ret);
+
+/* Proc filesystem */
extern void init_irq_proc(void);
-#endif
-extern hw_irq_controller no_irq_type; /* needed in every arch ? */
+/* 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)
-#endif
+/* 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->chip_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;
+
+/* CPU-affinity (on SMP) related data and functions */
+extern cpumask_t irq_affinity[NR_IRQS];
+extern int no_irq_affinity;
+extern int set_irq_affinity(unsigned int irq, cpumask_t affinity);
+extern cpumask_t get_irq_affinity(unsigned int irq);
+
+extern void check_irq_resend(irq_desc_t *desc, unsigned int irq);
+
+#endif /* GENERIC_HARDIRQS */
+
+#endif /* !S390 */
#endif /* __irq_h */
diff -urN --exclude=.hg linux-2.6.12/kernel/irq/Makefile linux-2.6.12-armirq/kernel/irq/Makefile
--- linux-2.6.12/kernel/irq/Makefile 2005-07-18 15:42:04.000000000 +0200
+++ linux-2.6.12-armirq/kernel/irq/Makefile 2005-07-13 14:34:11.000000000 +0200
@@ -1,5 +1,5 @@
-obj-y := handle.o manage.o spurious.o
+obj-y := handle.o manage.o spurious.o resend.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_PROC_FS) += proc.o
diff -urN --exclude=.hg linux-2.6.12/kernel/irq/handle.c linux-2.6.12-armirq/kernel/irq/handle.c
--- linux-2.6.12/kernel/irq/handle.c 2005-07-18 15:42:04.000000000 +0200
+++ linux-2.6.12-armirq/kernel/irq/handle.c 2005-07-15 16:10:56.000000000 +0200
@@ -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
@@ -15,54 +19,50 @@
#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,
+ .depth = 1,
.lock = SPIN_LOCK_UNLOCKED
}
};
/*
- * 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 = {
+/*
+ * 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 = startup_none,
- .shutdown = shutdown_none,
- .enable = enable_none,
- .disable = disable_none,
- .ack = ack_none,
- .end = end_none,
- .set_affinity = NULL
+ .startup = noop_ret,
+ .shutdown = noop,
+ .enable = noop,
+ .disable = noop,
+ .ack = ack_bad,
+ .end = noop,
+ .handle_irq = handle_bad_irq,
};
/*
@@ -74,7 +74,147 @@
}
/*
- * 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 = noop,
+ .disable = noop,
+ .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)
@@ -99,10 +239,208 @@
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);
+ 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);
+ 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);
+ 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);
+ 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)
{
diff -urN --exclude=.hg linux-2.6.12/kernel/irq/manage.c linux-2.6.12-armirq/kernel/irq/manage.c
--- linux-2.6.12/kernel/irq/manage.c 2005-07-18 15:42:04.000000000 +0200
+++ linux-2.6.12-armirq/kernel/irq/manage.c 2005-07-13 14:34:11.000000000 +0200
@@ -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.
*/
@@ -19,6 +20,7 @@
/**
* synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ * @irq: Interrupt to synchronize
*
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
@@ -109,12 +111,10 @@
break;
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 */
}
@@ -126,6 +126,28 @@
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
@@ -135,7 +157,7 @@
{
struct irqaction *action;
- if (irq >= NR_IRQS)
+ if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
return 0;
action = irq_desc[irq].action;
@@ -179,12 +201,12 @@
/*
* 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 */
if (!(old->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
return -EBUSY;
}
@@ -207,7 +229,7 @@
else
desc->handler->enable(irq);
}
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
new->irq = irq;
register_irq_proc(irq);
@@ -241,7 +263,7 @@
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;
@@ -262,7 +284,7 @@
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 */
@@ -270,8 +292,8 @@
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;
}
}
@@ -324,6 +346,8 @@
return -EINVAL;
if (irq >= NR_IRQS)
return -EINVAL;
+ if (irq_desc[irq].status & IRQ_NOREQUEST)
+ return -EINVAL;
if (!handler)
return -EINVAL;
@@ -347,3 +371,145 @@
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->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->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 ? -ENXIO : 0;
+}
+
+EXPORT_SYMBOL(set_hwirq_type);
+
diff -urN --exclude=.hg linux-2.6.12/kernel/irq/resend.c linux-2.6.12-armirq/kernel/irq/resend.c
--- linux-2.6.12/kernel/irq/resend.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12-armirq/kernel/irq/resend.c 2005-07-13 14:34:11.000000000 +0200
@@ -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
+#include
+#include
+#include
+
+#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_lock_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);
+ }
+ }
+}
+