patch-2.4.19 linux-2.4.19/arch/mips/dec/irq.c

Next file: linux-2.4.19/arch/mips/dec/kn02-irq.c
Previous file: linux-2.4.19/arch/mips/dec/ioasic-irq.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/mips/dec/irq.c linux-2.4.19/arch/mips/dec/irq.c
@@ -19,7 +19,6 @@
 #include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
@@ -34,48 +33,52 @@
 
 extern asmlinkage void decstation_handle_int(void);
 
-unsigned long spurious_count = 0;
+atomic_t irq_err_count;
 
 static inline void mask_irq(unsigned int irq_nr)
 {
-    unsigned int dummy;
+	unsigned int dummy;
 
-    if (dec_interrupt[irq_nr].iemask) {		/* This is an ASIC interrupt    */
-	*imr &= ~dec_interrupt[irq_nr].iemask;
-	dummy = *imr;
-	dummy = *imr;
-    } else			/* This is a cpu interrupt        */
-	change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask);
+	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
+		*imr &= ~dec_interrupt[irq_nr].iemask;
+		dummy = *imr;
+		dummy = *imr;
+	} else			/* This is a cpu interrupt        */
+		change_cp0_status(ST0_IM,
+				  read_32bit_cp0_register(CP0_STATUS) &
+				  ~dec_interrupt[irq_nr].cpu_mask);
 }
 
 static inline void unmask_irq(unsigned int irq_nr)
 {
-    unsigned int dummy;
+	unsigned int dummy;
 
-    if (dec_interrupt[irq_nr].iemask) {		/* This is an ASIC interrupt    */
-	*imr |= dec_interrupt[irq_nr].iemask;
-	dummy = *imr;
-	dummy = *imr;
-    }
-    change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask);
+	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
+		*imr |= dec_interrupt[irq_nr].iemask;
+		dummy = *imr;
+		dummy = *imr;
+	}
+	change_cp0_status(ST0_IM,
+			  read_32bit_cp0_register(CP0_STATUS) |
+			  dec_interrupt[irq_nr].cpu_mask);
 }
 
 void disable_irq(unsigned int irq_nr)
 {
-    unsigned long flags;
+	unsigned long flags;
 
-    save_and_cli(flags);
-    mask_irq(irq_nr);
-    restore_flags(flags);
+	save_and_cli(flags);
+	mask_irq(irq_nr);
+	restore_flags(flags);
 }
 
 void enable_irq(unsigned int irq_nr)
 {
-    unsigned long flags;
+	unsigned long flags;
 
-    save_and_cli(flags);
-    unmask_irq(irq_nr);
-    restore_flags(flags);
+	save_and_cli(flags);
+	unmask_irq(irq_nr);
+	restore_flags(flags);
 }
 
 /*
@@ -84,35 +87,35 @@
  */
 extern void interrupt(void);
 
-static struct irqaction *irq_action[32] =
-{
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+static struct irqaction *irq_action[32] = {
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
 int get_irq_list(char *buf)
 {
-    int i, len = 0;
-    struct irqaction *action;
+	int i, len = 0;
+	struct irqaction *action;
 
-    for (i = 0; i < 32; i++) {
-	action = irq_action[i];
-	if (!action)
-	    continue;
-	len += sprintf(buf + len, "%2d: %8d %c %s",
-		       i, kstat.irqs[0][i],
-		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
-		       action->name);
-	for (action = action->next; action; action = action->next) {
-	    len += sprintf(buf + len, ",%s %s",
-			   (action->flags & SA_INTERRUPT) ? " +" : "",
-			   action->name);
+	for (i = 0; i < 32; i++) {
+		action = irq_action[i];
+		if (!action)
+			continue;
+		len += sprintf(buf + len, "%2d: %8d %c %s",
+			       i, kstat.irqs[0][i],
+			       (action->flags & SA_INTERRUPT) ? '+' : ' ',
+			       action->name);
+		for (action = action->next; action; action = action->next) {
+			len += sprintf(buf + len, ",%s %s",
+				       (action->
+					flags & SA_INTERRUPT) ? " +" : "",
+				       action->name);
+		}
+		len += sprintf(buf + len, "\n");
 	}
-	len += sprintf(buf + len, "\n");
-    }
-    return len;
+	return len;
 }
 
 /*
@@ -124,33 +127,34 @@
  */
 asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
 {
-    struct irqaction *action;
-    int do_random, cpu;
+	struct irqaction *action;
+	int do_random, cpu;
 
-    cpu = smp_processor_id();
-    irq_enter(cpu, irq);
-    kstat.irqs[cpu][irq]++;
-
-    mask_irq(irq);
-    action = *(irq + irq_action);
-    if (action) {
-	if (!(action->flags & SA_INTERRUPT))
-	    __sti();
+	cpu = smp_processor_id();
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	mask_irq(irq);
 	action = *(irq + irq_action);
-	do_random = 0;
-	do {
-	    do_random |= action->flags;
-	    action->handler(irq, action->dev_id, regs);
-	    action = action->next;
-	} while (action);
-	if (do_random & SA_SAMPLE_RANDOM)
-	    add_interrupt_randomness(irq);
-	__cli();
-	unmask_irq(irq);
-    }
-    irq_exit(cpu, irq);
+	if (action) {
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+		action = *(irq + irq_action);
+		do_random = 0;
+		do {
+			do_random |= action->flags;
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+		if (do_random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+		__cli();
+		unmask_irq(irq);
+	}
+	irq_exit(cpu, irq);
 
-    /* unmasking and bottom half handling is done magically for us. */
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 /*
@@ -159,139 +163,145 @@
  */
 int setup_dec_irq(int irq, struct irqaction *new)
 {
-    int shared = 0;
-    struct irqaction *old, **p;
-    unsigned long flags;
-
-    p = irq_action + irq;
-    if ((old = *p) != NULL) {
-	/* Can't share interrupts unless both agree to */
-	if (!(old->flags & new->flags & SA_SHIRQ))
-	    return -EBUSY;
-
-	/* Can't share interrupts unless both are same type */
-	if ((old->flags ^ new->flags) & SA_INTERRUPT)
-	    return -EBUSY;
-
-	/* add new interrupt at end of irq queue */
-	do {
-	    p = &old->next;
-	    old = *p;
-	} while (old);
-	shared = 1;
-    }
-    if (new->flags & SA_SAMPLE_RANDOM)
-	rand_initialize_irq(irq);
-
-    save_and_cli(flags);
-    *p = new;
-
-    if (!shared) {
-	unmask_irq(irq);
-    }
-    restore_flags(flags);
-    return 0;
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+
+	p = irq_action + irq;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ))
+			return -EBUSY;
+
+		/* Can't share interrupts unless both are same type */
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
+			return -EBUSY;
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	save_and_cli(flags);
+	*p = new;
+
+	if (!shared) {
+		unmask_irq(irq);
+	}
+	restore_flags(flags);
+	return 0;
 }
 
 int request_irq(unsigned int irq,
 		void (*handler) (int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char *devname,
-		void *dev_id)
-{
-    int retval;
-    struct irqaction *action;
-
-    if (irq >= 32)
-	return -EINVAL;
-    if (!handler)
-	return -EINVAL;
-
-    action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-    if (!action)
-	return -ENOMEM;
-
-    action->handler = handler;
-    action->flags = irqflags;
-    action->mask = 0;
-    action->name = devname;
-    action->next = NULL;
-    action->dev_id = dev_id;
-
-    retval = setup_dec_irq(irq, action);
-
-    if (retval)
-	kfree(action);
-    return retval;
+		unsigned long irqflags, const char *devname, void *dev_id)
+{
+	int retval;
+	struct irqaction *action;
+
+	if (irq >= 32)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action =
+	    (struct irqaction *) kmalloc(sizeof(struct irqaction),
+					 GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_dec_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
 }
 
 void free_irq(unsigned int irq, void *dev_id)
 {
-    struct irqaction *action, **p;
-    unsigned long flags;
-
-    if (irq > 39) {
-	printk("Trying to free IRQ%d\n", irq);
-	return;
-    }
-    for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
-	if (action->dev_id != dev_id)
-	    continue;
+	struct irqaction *action, **p;
+	unsigned long flags;
 
-	/* Found it - now free it */
-	save_and_cli(flags);
-	*p = action->next;
-	if (!irq[irq_action])
-	    mask_irq(irq);
-	restore_flags(flags);
-	kfree(action);
-	return;
-    }
-    printk("Trying to free free IRQ%d\n", irq);
+	if (irq > 39) {
+		printk("Trying to free IRQ%d\n", irq);
+		return;
+	}
+	for (p = irq + irq_action; (action = *p) != NULL;
+	     p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		save_and_cli(flags);
+		*p = action->next;
+		if (!irq[irq_action])
+			mask_irq(irq);
+		restore_flags(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n", irq);
 }
 
 unsigned long probe_irq_on(void)
 {
-    /* TODO */
-    return 0;
+	/* TODO */
+	return 0;
 }
 
 int probe_irq_off(unsigned long irqs)
 {
-    /* TODO */
-    return 0;
+	/* TODO */
+	return 0;
+}
+
+void init_irq_proc(void)
+{
+	/* Nothing, for now.  */
 }
 
 void __init init_IRQ(void)
 {
-    switch (mips_machtype) {
-    case MACH_DS23100:
-	dec_init_kn01();
-	break;
-    case MACH_DS5100:		/*  DS5100 MIPSMATE */
-	dec_init_kn230();
-	break;
-    case MACH_DS5000_200:	/* DS5000 3max */
-	dec_init_kn02();
-	break;
-    case MACH_DS5000_1XX:	/* DS5000/100 3min */
-	dec_init_kn02ba();
-	break;
-    case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-	dec_init_kn03();
-	break;
-    case MACH_DS5000_XX:	/* Personal DS5000/2x */
-	dec_init_kn02ca();
-	break;
-    case MACH_DS5800:		/* DS5800 Isis */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5400:		/* DS5400 MIPSfair */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5500:		/* DS5500 MIPSfair-2 */
-	panic("Don't know how to set this up!");
-	break;
-    }
-    set_except_vector(0, decstation_handle_int);
+	switch (mips_machtype) {
+	case MACH_DS23100:
+		dec_init_kn01();
+		break;
+	case MACH_DS5100:	/*  DS5100 MIPSMATE */
+		dec_init_kn230();
+		break;
+	case MACH_DS5000_200:	/* DS5000 3max */
+		dec_init_kn02();
+		break;
+	case MACH_DS5000_1XX:	/* DS5000/100 3min */
+		dec_init_kn02ba();
+		break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+		dec_init_kn03();
+		break;
+	case MACH_DS5000_XX:	/* Personal DS5000/2x */
+		dec_init_kn02ca();
+		break;
+	case MACH_DS5800:	/* DS5800 Isis */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5400:	/* DS5400 MIPSfair */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5500:	/* DS5500 MIPSfair-2 */
+		panic("Don't know how to set this up!");
+		break;
+	}
+	set_except_vector(0, decstation_handle_int);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)