patch-2.4.22 linux-2.4.22/arch/mips/au1000/common/irq.c
Next file: linux-2.4.22/arch/mips/au1000/common/pci_fixup.c
Previous file: linux-2.4.22/arch/mips/au1000/common/dbg_io.c
Back to the patch index
Back to the overall index
- Lines: 393
- Date:
2003-08-25 04:44:39.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips/au1000/common/irq.c
- Orig date:
2002-11-28 15:53:09.000000000 -0800
diff -urN linux-2.4.21/arch/mips/au1000/common/irq.c linux-2.4.22/arch/mips/au1000/common/irq.c
@@ -28,6 +28,7 @@
*/
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
@@ -46,15 +47,8 @@
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/au1000.h>
-
-#if defined(CONFIG_MIPS_PB1000)
+#ifdef CONFIG_MIPS_PB1000
#include <asm/pb1000.h>
-#elif defined(CONFIG_MIPS_PB1500)
-#include <asm/pb1500.h>
-#elif defined(CONFIG_MIPS_PB1100)
-#include <asm/pb1100.h>
-#else
-#error unsupported alchemy board
#endif
#undef DEBUG_IRQ
@@ -71,7 +65,7 @@
#define EXT_INTC1_REQ1 5 /* IP 5 */
#define MIPS_TIMER_IP 7 /* IP 7 */
-#ifdef CONFIG_REMOTE_DEBUG
+#ifdef CONFIG_KGDB
extern void breakpoint(void);
#endif
@@ -90,13 +84,13 @@
inline void local_enable_irq(unsigned int irq_nr);
inline void local_disable_irq(unsigned int irq_nr);
-extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
extern void __init init_generic_irq(void);
#ifdef CONFIG_PM
extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
#endif
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
{
@@ -280,10 +274,6 @@
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
local_enable_irq(irq_nr);
}
- else {
- printk("warning: end_irq %d did not enable (%x)\n",
- irq_nr, irq_desc[irq_nr].status);
- }
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO_15) {
au_writel(0x4000, PB1000_MDR); /* enable int */
@@ -296,8 +286,8 @@
{
int i;
unsigned long flags, mask;
- save_and_cli(flags);
+ spin_lock_irqsave(&irq_lock, flags);
if (controller) {
mask = au_readl(IC1_MASKSET);
for (i=32; i<64; i++) {
@@ -310,7 +300,8 @@
local_disable_irq(i);
}
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
+
return mask;
}
@@ -318,8 +309,8 @@
{
int i;
unsigned long flags, new_mask;
- save_and_cli(flags);
+ spin_lock_irqsave(&irq_lock, flags);
for (i=0; i<32; i++) {
if (mask & (1<<i)) {
if (controller)
@@ -333,7 +324,7 @@
else
new_mask = au_readl(IC0_MASKSET);
- restore_flags(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
}
@@ -348,7 +339,7 @@
NULL
};
-
+/*
static struct hw_interrupt_type fall_edge_irq_type = {
"Au1000 Fall Edge",
startup_irq,
@@ -359,7 +350,7 @@
end_irq,
NULL
};
-
+*/
static struct hw_interrupt_type level_irq_type = {
"Au1000 Level",
@@ -384,114 +375,52 @@
{
int i;
unsigned long cp0_status;
- extern char except_vec0_au1000;
+ au1xxx_irq_map_t *imp;
+ extern au1xxx_irq_map_t au1xxx_irq_map[];
+ extern int au1xxx_nr_irqs;
- cp0_status = read_32bit_cp0_register(CP0_STATUS);
+ cp0_status = read_c0_status();
memset(irq_desc, 0, sizeof(irq_desc));
set_except_vector(0, au1000_IRQ);
init_generic_irq();
for (i = 0; i <= AU1000_MAX_INTR; i++) {
- switch (i) {
- case AU1000_UART0_INT:
- case AU1000_UART3_INT:
-#ifdef CONFIG_MIPS_PB1000
- case AU1000_UART1_INT:
- case AU1000_UART2_INT:
-
- case AU1000_SSI0_INT:
- case AU1000_SSI1_INT:
-#endif
+ /* default is active high, level interrupt */
+ setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
+ irq_desc[i].handler = &level_irq_type;
+ }
-#ifdef CONFIG_MIPS_PB1100
- case AU1000_UART1_INT:
+ /* Now set up the irq mapping for the board.
+ */
+ imp = au1xxx_irq_map;
+ for (i=0; i<au1xxx_nr_irqs; i++) {
- case AU1000_SSI0_INT:
- case AU1000_SSI1_INT:
-#endif
- case AU1000_DMA_INT_BASE:
- case AU1000_DMA_INT_BASE+1:
- case AU1000_DMA_INT_BASE+2:
- case AU1000_DMA_INT_BASE+3:
- case AU1000_DMA_INT_BASE+4:
- case AU1000_DMA_INT_BASE+5:
- case AU1000_DMA_INT_BASE+6:
- case AU1000_DMA_INT_BASE+7:
+ setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
- case AU1000_IRDA_TX_INT:
- case AU1000_IRDA_RX_INT:
+ switch (imp->im_type) {
- case AU1000_MAC0_DMA_INT:
-#ifdef CONFIG_MIPS_PB1000
- case AU1000_MAC1_DMA_INT:
-#endif
-#ifdef CONFIG_MIPS_PB1500
- case AU1000_MAC1_DMA_INT:
-#endif
- case AU1500_GPIO_204:
+ case INTC_INT_HIGH_LEVEL:
+ irq_desc[imp->im_irq].handler = &level_irq_type;
+ break;
- setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
- irq_desc[i].handler = &level_irq_type;
- break;
+ case INTC_INT_LOW_LEVEL:
+ irq_desc[imp->im_irq].handler = &level_irq_type;
+ break;
-#ifdef CONFIG_MIPS_PB1000
- case AU1000_GPIO_15:
-#endif
- case AU1000_USB_HOST_INT:
-#ifdef CONFIG_MIPS_PB1500
- case AU1000_PCI_INTA:
- case AU1000_PCI_INTB:
- case AU1000_PCI_INTC:
- case AU1000_PCI_INTD:
- case AU1500_GPIO_201:
- case AU1500_GPIO_202:
- case AU1500_GPIO_203:
- case AU1500_GPIO_205:
- case AU1500_GPIO_207:
-#endif
+ case INTC_INT_RISE_EDGE:
+ irq_desc[imp->im_irq].handler = &rise_edge_irq_type;
+ break;
-#ifdef CONFIG_MIPS_PB1100
- case AU1000_GPIO_9: // PCMCIA Card Fully_Interted#
- case AU1000_GPIO_10: // PCMCIA_STSCHG#
- case AU1000_GPIO_11: // PCMCIA_IRQ#
- case AU1000_GPIO_13: // DC_IRQ#
- case AU1000_GPIO_23: // 2-wire SCL
-#endif
- setup_local_irq(i, INTC_INT_LOW_LEVEL, 0);
- irq_desc[i].handler = &level_irq_type;
- break;
- case AU1000_ACSYNC_INT:
- case AU1000_AC97C_INT:
- case AU1000_TOY_INT:
- case AU1000_TOY_MATCH0_INT:
- case AU1000_TOY_MATCH1_INT:
- case AU1000_USB_DEV_SUS_INT:
- case AU1000_USB_DEV_REQ_INT:
- case AU1000_RTC_INT:
- case AU1000_RTC_MATCH0_INT:
- case AU1000_RTC_MATCH1_INT:
- case AU1000_RTC_MATCH2_INT:
- setup_local_irq(i, INTC_INT_RISE_EDGE, 0);
- irq_desc[i].handler = &rise_edge_irq_type;
- break;
-
- // Careful if you change match 2 request!
- // The interrupt handler is called directly
- // from the low level dispatch code.
- case AU1000_TOY_MATCH2_INT:
- setup_local_irq(i, INTC_INT_RISE_EDGE, 1);
- irq_desc[i].handler = &rise_edge_irq_type;
- break;
- default: /* active high, level interrupt */
- setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
- irq_desc[i].handler = &level_irq_type;
- break;
+ default:
+ panic("Unknown au1xxx irq map");
+ break;
}
+ imp++;
}
- set_cp0_status(ALLINTS);
-#ifdef CONFIG_REMOTE_DEBUG
+ set_c0_status(ALLINTS);
+#ifdef CONFIG_KGDB
/* If local serial I/O used for debug port, enter kgdb at once */
puts("Waiting for kgdb to connect...");
set_debug_traps();
@@ -508,7 +437,7 @@
void intc0_req0_irqdispatch(struct pt_regs *regs)
{
- int irq = 0, i;
+ int irq = 0;
static unsigned long intc0_req0 = 0;
intc0_req0 |= au_readl(IC0_REQ0INT);
@@ -526,43 +455,33 @@
return;
}
- for (i=0; i<32; i++) {
- if ((intc0_req0 & (1<<i))) {
- intc0_req0 &= ~(1<<i);
- do_IRQ(irq, regs);
- break;
- }
- irq++;
- }
+ irq = au_ffs(intc0_req0) - 1;
+ intc0_req0 &= ~(1<<irq);
+ do_IRQ(irq, regs);
}
void intc0_req1_irqdispatch(struct pt_regs *regs)
{
- int irq = 0, i;
+ int irq = 0;
static unsigned long intc0_req1 = 0;
- intc0_req1 = au_readl(IC0_REQ1INT);
+ intc0_req1 |= au_readl(IC0_REQ1INT);
if (!intc0_req1) return;
- for (i=0; i<32; i++) {
- if ((intc0_req1 & (1<<i))) {
- intc0_req1 &= ~(1<<i);
+ irq = au_ffs(intc0_req1) - 1;
+ intc0_req1 &= ~(1<<irq);
#ifdef CONFIG_PM
- if (i == AU1000_TOY_MATCH2_INT) {
- mask_and_ack_rise_edge_irq(irq);
- counter0_irq(irq, NULL, regs);
- local_enable_irq(irq);
- }
- else
+ if (irq == AU1000_TOY_MATCH2_INT) {
+ mask_and_ack_rise_edge_irq(irq);
+ counter0_irq(irq, NULL, regs);
+ local_enable_irq(irq);
+ }
+ else
#endif
- {
- do_IRQ(irq, regs);
- }
- break;
- }
- irq++;
+ {
+ do_IRQ(irq, regs);
}
}
@@ -573,53 +492,31 @@
*/
void intc1_req0_irqdispatch(struct pt_regs *regs)
{
- int irq = 0, i;
+ int irq = 0;
static unsigned long intc1_req0 = 0;
- volatile unsigned short levels, mdr;
- unsigned char ide_status;
intc1_req0 |= au_readl(IC1_REQ0INT);
if (!intc1_req0) return;
-#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
- au_writel(1, CPLD_AUX0); /* debug led 0 */
-#endif
- for (i=0; i<32; i++) {
- if ((intc1_req0 & (1<<i))) {
- intc1_req0 &= ~(1<<i);
-#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
- au_writel(2, CPLD_AUX0); /* turn on debug led 1 */
- do_IRQ(irq+32, regs);
- au_writel(0, CPLD_AUX0); /* turn off debug led 1 */
-#else
- do_IRQ(irq+32, regs);
-#endif
- break;
- }
- irq++;
- }
-#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
- au_writel(0, CPLD_AUX0);
-#endif
+ irq = au_ffs(intc1_req0) - 1;
+ intc1_req0 &= ~(1<<irq);
+ irq += 32;
+ do_IRQ(irq, regs);
}
void intc1_req1_irqdispatch(struct pt_regs *regs)
{
- int irq = 0, i;
+ int irq = 0;
static unsigned long intc1_req1 = 0;
intc1_req1 |= au_readl(IC1_REQ1INT);
if (!intc1_req1) return;
- for (i=0; i<32; i++) {
- if ((intc1_req1 & (1<<i))) {
- intc1_req1 &= ~(1<<i);
- do_IRQ(irq+32, regs);
- break;
- }
- irq++;
- }
+ irq = au_ffs(intc1_req1) - 1;
+ intc1_req1 &= ~(1<<irq);
+ irq += 32;
+ do_IRQ(irq, regs);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)