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