patch-2.4.4 linux/arch/arm/kernel/irq.c
Next file: linux/arch/arm/kernel/leds-ebsa110.c
Previous file: linux/arch/arm/kernel/irq-arch.c
Back to the patch index
Back to the overall index
- Lines: 208
- Date:
Thu Apr 12 12:20:31 2001
- Orig file:
v2.4.3/linux/arch/arm/kernel/irq.c
- Orig date:
Fri Feb 9 11:29:44 2001
diff -u --recursive --new-file v2.4.3/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c
@@ -2,7 +2,7 @@
* linux/arch/arm/kernel/irq.c
*
* Copyright (C) 1992 Linus Torvalds
- * Modifications for ARM processor Copyright (C) 1995-1998 Russell King.
+ * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -29,9 +29,11 @@
#include <linux/smp.h>
#include <linux/init.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/system.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/irq.h> /* pick up fixup_irq definition */
/*
* Maximum IRQ count. Currently, this is arbitary. However, it should
@@ -42,41 +44,11 @@
*/
#define MAX_IRQ_CNT 100000
-spinlock_t irq_controller_lock;
-
-int setup_arm_irq(int, struct irqaction *);
-extern int get_fiq_list(char *);
-extern void init_FIQ(void);
-
-struct irqdesc {
- unsigned int nomask : 1; /* IRQ does not mask in IRQ */
- unsigned int enabled : 1; /* IRQ is currently enabled */
- unsigned int triggered: 1; /* IRQ has occurred */
- 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;
- void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */
- void (*mask)(unsigned int irq); /* Mask IRQ */
- void (*unmask)(unsigned int irq); /* Unmask IRQ */
- struct irqaction *action;
- /*
- * IRQ lock detection
- */
- unsigned int lck_cnt;
- unsigned int lck_pc;
- unsigned int lck_jif;
-};
-
-static struct irqdesc irq_desc[NR_IRQS];
static volatile unsigned long irq_err_count;
+static spinlock_t irq_controller_lock;
-/*
- * Get architecture specific interrupt handlers
- * and interrupt initialisation.
- */
-#include <asm/arch/irq.h>
+struct irqdesc irq_desc[NR_IRQS];
+void (*init_arch_irq)(void) __initdata = NULL;
/*
* Dummy mask/unmask handler
@@ -85,6 +57,14 @@
{
}
+/**
+ * disable_irq - disable an irq and wait for completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line.
+ *
+ * This function may be called - with care - from IRQ context.
+ */
void disable_irq(unsigned int irq)
{
unsigned long flags;
@@ -95,6 +75,14 @@
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
+/**
+ * enable_irq - enable interrupt handling on an irq
+ * @irq: Interrupt to enable
+ *
+ * Re-enables the processing of interrupts on this IRQ line
+ *
+ * This function may be called from IRQ context.
+ */
void enable_irq(unsigned int irq)
{
unsigned long flags;
@@ -271,6 +259,7 @@
int shared = 0;
struct irqaction *old, **p;
unsigned long flags;
+ struct irqdesc *desc;
/*
* Some drivers like serial.c use request_irq() heavily,
@@ -292,8 +281,9 @@
/*
* The following block of code has to be executed atomically
*/
+ desc = irq_desc + irq;
spin_lock_irqsave(&irq_controller_lock, flags);
- p = &irq_desc[irq].action;
+ p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
if (!(old->flags & new->flags & SA_SHIRQ)) {
@@ -312,11 +302,11 @@
*p = new;
if (!shared) {
- irq_desc[irq].nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0;
- irq_desc[irq].probing = 0;
- if (!irq_desc[irq].noautoenable) {
- irq_desc[irq].enabled = 1;
- irq_desc[irq].unmask(irq);
+ desc->nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0;
+ desc->probing = 0;
+ if (!desc->noautoenable) {
+ desc->enabled = 1;
+ desc->unmask(irq);
}
}
@@ -324,13 +314,45 @@
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, void (*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)
+ 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);
@@ -351,6 +373,18 @@
return retval;
}
+/**
+ * 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 may be called from interrupt context.
+ */
void free_irq(unsigned int irq, void *dev_id)
{
struct irqaction * action, **p;
@@ -486,6 +520,6 @@
irq_desc[irq].unmask = dummy_mask_unmask_irq;
}
- irq_init_irq();
+ init_arch_irq();
init_dma();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)