diff options
Diffstat (limited to 'arch/alpha/kernel/irq.c')
| -rw-r--r-- | arch/alpha/kernel/irq.c | 95 |
1 files changed, 28 insertions, 67 deletions
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 76be5cf0de1..7b2be251c30 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -10,7 +10,6 @@ * should be easier. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> @@ -19,7 +18,6 @@ #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include <linux/random.h> #include <linux/init.h> #include <linux/irq.h> @@ -28,11 +26,11 @@ #include <linux/profile.h> #include <linux/bitops.h> -#include <asm/system.h> #include <asm/io.h> #include <asm/uaccess.h> volatile unsigned long irq_err_count; +DEFINE_PER_CPU(unsigned long, irq_pmi_count); void ack_bad_irq(unsigned int irq) { @@ -43,86 +41,49 @@ void ack_bad_irq(unsigned int irq) #ifdef CONFIG_SMP static char irq_user_affinity[NR_IRQS]; -int -select_smp_affinity(unsigned int irq) +int irq_select_affinity(unsigned int irq) { + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip; static int last_cpu; int cpu = last_cpu + 1; - if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) + if (!data) return 1; + chip = irq_data_get_irq_chip(data); - while (!cpu_possible(cpu)) + if (!chip->irq_set_affinity || irq_user_affinity[irq]) + return 1; + + while (!cpu_possible(cpu) || + !cpumask_test_cpu(cpu, irq_default_affinity)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = cpumask_of_cpu(cpu); - irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); + cpumask_copy(data->affinity, cpumask_of(cpu)); + chip->irq_set_affinity(data, cpumask_of(cpu), false); return 0; } #endif /* CONFIG_SMP */ -int -show_interrupts(struct seq_file *p, void *v) +int arch_show_interrupts(struct seq_file *p, int prec) { -#ifdef CONFIG_SMP int j; -#endif - int i = *(loff_t *) v; - struct irqaction * action; - unsigned long flags; #ifdef CONFIG_SMP - if (i == 0) { - seq_puts(p, " "); - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - seq_printf(p, "CPU%d ", i); - seq_putc(p, '\n'); - } + seq_puts(p, "IPI: "); + for_each_online_cpu(j) + seq_printf(p, "%10lu ", cpu_data[j].ipi_count); + seq_putc(p, '\n'); #endif - - if (i < ACTUAL_NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto unlock; - seq_printf(p, "%3d: ",i); -#ifndef CONFIG_SMP - seq_printf(p, "%10u ", kstat_irqs(i)); -#else - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); -#endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); - seq_printf(p, " %c%s", - (action->flags & SA_INTERRUPT)?'+':' ', - action->name); - - for (action=action->next; action; action = action->next) { - seq_printf(p, ", %c%s", - (action->flags & SA_INTERRUPT)?'+':' ', - action->name); - } - - seq_putc(p, '\n'); -unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == ACTUAL_NR_IRQS) { -#ifdef CONFIG_SMP - seq_puts(p, "IPI: "); - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - seq_printf(p, "%10lu ", cpu_data[i].ipi_count); - seq_putc(p, '\n'); -#endif - seq_printf(p, "ERR: %10lu\n", irq_err_count); - } + seq_puts(p, "PMI: "); + for_each_online_cpu(j) + seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j)); + seq_puts(p, " Performance Monitoring\n"); + seq_printf(p, "ERR: %10lu\n", irq_err_count); return 0; } - /* * handle_irq handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -132,7 +93,7 @@ unlock: #define MAX_ILLEGAL_IRQS 16 void -handle_irq(int irq, struct pt_regs * regs) +handle_irq(int irq) { /* * We ack quickly, we don't want the irq controller @@ -145,8 +106,10 @@ handle_irq(int irq, struct pt_regs * regs) * handled by some other CPU. (or is disabled) */ static unsigned int illegal_count=0; + struct irq_desc *desc = irq_to_desc(irq); - if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) { + if (!desc || ((unsigned) irq > ACTUAL_NR_IRQS && + illegal_count < MAX_ILLEGAL_IRQS)) { irq_err_count++; illegal_count++; printk(KERN_CRIT "device_interrupt: invalid interrupt %d\n", @@ -155,8 +118,6 @@ handle_irq(int irq, struct pt_regs * regs) } irq_enter(); - local_irq_disable(); - __do_IRQ(irq, regs); - local_irq_enable(); + generic_handle_irq_desc(irq, desc); irq_exit(); } |
