From 1140a0c3f565ab0cd2749be484db807bd60bcd21 Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@osdl.org>
Date: Tue, 3 Feb 2004 18:53:48 -0800
Subject: [PATCH] [PATCH] Altix update: irq fixes

From: Pat Gefre <pfg@sgi.com>

arch/ia64/sn/kernel/irq.c
    Need to get the cpu from the passed in pcibr struct
    Made the interrupt list static and gave it a better name - credit jes
    Some lindent'isms
    Took out some code that isn't used ..... yet
---
 arch/ia64/sn/kernel/irq.c | 161 ++++++++++++++------------------------
 1 file changed, 58 insertions(+), 103 deletions(-)

diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index b42b82fdd8cf..aab72b0e1579 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/bootmem.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/sn/sgi.h>
@@ -40,8 +41,12 @@ static void force_interrupt(int irq);
 extern void pcibr_force_interrupt(pcibr_intr_t intr);
 extern int sn_force_interrupt_flag;
 
-static pcibr_intr_list_t *pcibr_intr_list;
+struct sn_intr_list_t {
+	struct sn_intr_list_t *next;
+	pcibr_intr_t intr;
+};
 
+static struct sn_intr_list_t *sn_intr_list[NR_IRQS];
 
 
 static unsigned int
@@ -114,25 +119,23 @@ sn_end_irq(unsigned int irq)
 }
 
 static void
-sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
+sn_set_affinity_irq(unsigned int irq, unsigned long cpu)
 {
-#if CONFIG_SMP  
-        int redir = 0;
-        pcibr_intr_list_t p = pcibr_intr_list[irq];
-        pcibr_intr_t intr; 
-	int	cpu;
-        extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
-        extern void sn_tio_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
-                
+#if CONFIG_SMP
+	int redir = 0;
+	struct sn_intr_list_t *p = sn_intr_list[irq];
+	pcibr_intr_t intr;
+	extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
+	extern void sn_tio_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
+
 	if (p == NULL)
 		return; 
         
-	intr = p->il_intr;
+	intr = p->intr;
 
 	if (intr == NULL)
 		return; 
 
-	cpu = first_cpu(mask);
 	sn_shub_redirect_intr(intr, cpu);
 	(void) set_irq_affinity_info(irq, cpu_physical_id(intr->bi_cpu), redir);
 #endif /* CONFIG_SMP */
@@ -152,7 +155,8 @@ struct hw_interrupt_type irq_type_sn = {
 
 
 struct irq_desc *
-sn_irq_desc(unsigned int irq) {
+sn_irq_desc(unsigned int irq)
+{
 
 	irq = SN_IVEC_FROM_IRQ(irq);
 
@@ -160,12 +164,14 @@ sn_irq_desc(unsigned int irq) {
 }
 
 u8
-sn_irq_to_vector(u8 irq) {
+sn_irq_to_vector(u8 irq)
+{
 	return(irq);
 }
 
 unsigned int
-sn_local_vector_to_irq(u8 vector) {
+sn_local_vector_to_irq(u8 vector)
+{
 	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
 }
 
@@ -175,7 +181,7 @@ sn_irq_init (void)
 	int i;
 	irq_desc_t *base_desc = _irq_desc;
 
-	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
+	for (i=0; i<NR_IRQS; i++) {
 		if (base_desc[i].handler == &no_irq_type) {
 			base_desc[i].handler = &irq_type_sn;
 		}
@@ -183,60 +189,56 @@ sn_irq_init (void)
 }
 
 void
-register_pcibr_intr(int irq, pcibr_intr_t intr) {
-	pcibr_intr_list_t p = kmalloc(sizeof(struct pcibr_intr_list_s), GFP_KERNEL);
-	pcibr_intr_list_t list;
-	int cpu = SN_CPU_FROM_IRQ(irq);
-
-	if (pcibr_intr_list == NULL) {
-		pcibr_intr_list = kmalloc(sizeof(pcibr_intr_list_t) * NR_IRQS, GFP_KERNEL);
-		if (pcibr_intr_list == NULL) 
-			pcibr_intr_list = vmalloc(sizeof(pcibr_intr_list_t) * NR_IRQS);
-		if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
-		memset( (void *)pcibr_intr_list, 0, sizeof(pcibr_intr_list_t) * NR_IRQS);
-	}
+register_pcibr_intr(int irq, pcibr_intr_t intr)
+{
+	struct sn_intr_list_t *p = kmalloc(sizeof(struct sn_intr_list_t), GFP_KERNEL);
+	struct sn_intr_list_t *list;
+	int cpu = intr->bi_cpu;
+
 	if (pdacpu(cpu)->sn_last_irq < irq) {
 		pdacpu(cpu)->sn_last_irq = irq;
 	}
-	if (pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
-	if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n");
-	if ((list = pcibr_intr_list[irq])) {
-		while (list->il_next) list = list->il_next;
-		list->il_next = p;
-		p->il_next = NULL;
-		p->il_intr = intr;
+	if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
+	if (!p) panic("Could not allocate memory for sn_intr_list_t\n");
+	if ((list = sn_intr_list[irq])) {
+		while (list->next) list = list->next;
+		list->next = p;
+		p->next = NULL;
+		p->intr = intr;
 	} else {
-		pcibr_intr_list[irq] = p;
-		p->il_next = NULL;
-		p->il_intr = intr;
+		sn_intr_list[irq] = p;
+		p->next = NULL;
+		p->intr = intr;
 	}
 }
 
 void
-force_polled_int(void) {
+force_polled_int(void)
+{
 	int i;
-	pcibr_intr_list_t p;
+	struct sn_intr_list_t *p;
 
 	for (i=0; i<NR_IRQS;i++) {
-		p = pcibr_intr_list[i];
+		p = sn_intr_list[i];
 		while (p) {
-			if (p->il_intr){
-				pcibr_force_interrupt(p->il_intr);
+			if (p->intr){
+				pcibr_force_interrupt(p->intr);
 			}
-			p = p->il_next;
+			p = p->next;
 		}
 	}
 }
 
 static void
-force_interrupt(int irq) {
-	pcibr_intr_list_t p = pcibr_intr_list[irq];
+force_interrupt(int irq)
+{
+	struct sn_intr_list_t *p = sn_intr_list[irq];
 
 	while (p) {
-		if (p->il_intr) {
-			pcibr_force_interrupt(p->il_intr);
+		if (p->intr) {
+			pcibr_force_interrupt(p->intr);
 		}
-		p = p->il_next;
+		p = p->next;
 	}
 }
 
@@ -251,7 +253,8 @@ but we should never miss a real lost interrupt.
 */
 
 static void
-sn_check_intr(int irq, pcibr_intr_t intr) {
+sn_check_intr(int irq, pcibr_intr_t intr)
+{
 	unsigned long regval;
 	int irr_reg_num;
 	int irr_bit;
@@ -290,68 +293,20 @@ sn_check_intr(int irq, pcibr_intr_t intr) {
 }
 
 void
-sn_lb_int_war_check(void) {
+sn_lb_int_war_check(void)
+{
 	int i;
 
 	if (pda->sn_first_irq == 0) return;
 	for (i=pda->sn_first_irq;
 		i <= pda->sn_last_irq; i++) {
-			pcibr_intr_list_t p = pcibr_intr_list[i];
+			struct sn_intr_list_t *p = sn_intr_list[i];
 			if (p == NULL) {
 				continue;
 			}
 			while (p) {
-				sn_check_intr(i, p->il_intr);
-				p = p->il_next;
+				sn_check_intr(i, p->intr);
+				p = p->next;
 			}
 	}
 }
-
-static inline int
-sn_get_next_bit(void) {
-	int i;
-	int bit;
-
-	for (i = 3; i >= 0; i--) {
-		if (pda->sn_soft_irr[i] != 0) {
-			bit = (i * 64) +  __ffs(pda->sn_soft_irr[i]);
-			__change_bit(bit, (volatile void *)pda->sn_soft_irr);
-			return(bit);
-		}
-	}
-	return IA64_SPURIOUS_INT_VECTOR;
-}
-
-void
-sn_set_tpr(int vector) {
-	if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) {
-		ia64_setreg(_IA64_REG_CR_TPR, vector);
-	} else {
-		ia64_setreg(_IA64_REG_CR_TPR, IA64_LAST_DEVICE_VECTOR);
-	}
-}
-
-static inline void
-sn_get_all_ivr(void) {
-	int vector;
-
-	vector = ia64_get_ivr();
-	while (vector != IA64_SPURIOUS_INT_VECTOR) {
-		__set_bit(vector, (volatile void *)pda->sn_soft_irr);
-		ia64_eoi();
-		if (vector > IA64_LAST_DEVICE_VECTOR) return;
-		vector = ia64_get_ivr();
-	}
-}
-	
-int
-sn_get_ivr(void) {
-	int vector;
-
-	vector = sn_get_next_bit();
-	if (vector == IA64_SPURIOUS_INT_VECTOR) {
-		sn_get_all_ivr();
-		vector = sn_get_next_bit();
-	}
-	return vector;
-}
-- 
2.30.9