diff options
Diffstat (limited to 'arch/tile/kernel/irq.c')
| -rw-r--r-- | arch/tile/kernel/irq.c | 135 |
1 files changed, 41 insertions, 94 deletions
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index 128805ef8f2..637f2ffaa5f 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c @@ -21,6 +21,7 @@ #include <hv/drv_pcie_rc_intf.h> #include <arch/spr_def.h> #include <asm/traps.h> +#include <linux/perf_event.h> /* Bit-flag stored in irq_desc->chip_data to indicate HW-cleared irqs. */ #define IS_HW_CLEARED 1 @@ -53,12 +54,6 @@ static DEFINE_PER_CPU(unsigned long, irq_disable_mask) */ static DEFINE_PER_CPU(int, irq_depth); -/* State for allocating IRQs on Gx. */ -#if CHIP_HAS_IPI() -static unsigned long available_irqs = ~(1UL << IRQ_RESCHEDULE); -static DEFINE_SPINLOCK(available_irqs_lock); -#endif - #if CHIP_HAS_IPI() /* Use SPRs to manipulate device interrupts. */ #define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_K, irq_mask) @@ -73,7 +68,8 @@ static DEFINE_SPINLOCK(available_irqs_lock); /* * The interrupt handling path, implemented in terms of HV interrupt - * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx. + * emulation on TILEPro, and IPI hardware on TILE-Gx. + * Entered with interrupts disabled. */ void tile_dev_intr(struct pt_regs *regs, int intnum) { @@ -152,14 +148,13 @@ void tile_dev_intr(struct pt_regs *regs, int intnum) * Remove an irq from the disabled mask. If we're in an interrupt * context, defer enabling the HW interrupt until we leave. */ -void enable_percpu_irq(unsigned int irq) +static void tile_irq_chip_enable(struct irq_data *d) { - get_cpu_var(irq_disable_mask) &= ~(1UL << irq); + get_cpu_var(irq_disable_mask) &= ~(1UL << d->irq); if (__get_cpu_var(irq_depth) == 0) - unmask_irqs(1UL << irq); + unmask_irqs(1UL << d->irq); put_cpu_var(irq_disable_mask); } -EXPORT_SYMBOL(enable_percpu_irq); /* * Add an irq to the disabled mask. We disable the HW interrupt @@ -167,52 +162,53 @@ EXPORT_SYMBOL(enable_percpu_irq); * in an interrupt context, the return path is careful to avoid * unmasking a newly disabled interrupt. */ -void disable_percpu_irq(unsigned int irq) +static void tile_irq_chip_disable(struct irq_data *d) { - get_cpu_var(irq_disable_mask) |= (1UL << irq); - mask_irqs(1UL << irq); + get_cpu_var(irq_disable_mask) |= (1UL << d->irq); + mask_irqs(1UL << d->irq); put_cpu_var(irq_disable_mask); } -EXPORT_SYMBOL(disable_percpu_irq); /* Mask an interrupt. */ -static void tile_irq_chip_mask(unsigned int irq) +static void tile_irq_chip_mask(struct irq_data *d) { - mask_irqs(1UL << irq); + mask_irqs(1UL << d->irq); } /* Unmask an interrupt. */ -static void tile_irq_chip_unmask(unsigned int irq) +static void tile_irq_chip_unmask(struct irq_data *d) { - unmask_irqs(1UL << irq); + unmask_irqs(1UL << d->irq); } /* * Clear an interrupt before processing it so that any new assertions * will trigger another irq. */ -static void tile_irq_chip_ack(unsigned int irq) +static void tile_irq_chip_ack(struct irq_data *d) { - if ((unsigned long)get_irq_chip_data(irq) != IS_HW_CLEARED) - clear_irqs(1UL << irq); + if ((unsigned long)irq_data_get_irq_chip_data(d) != IS_HW_CLEARED) + clear_irqs(1UL << d->irq); } /* * For per-cpu interrupts, we need to avoid unmasking any interrupts * that we disabled via disable_percpu_irq(). */ -static void tile_irq_chip_eoi(unsigned int irq) +static void tile_irq_chip_eoi(struct irq_data *d) { - if (!(__get_cpu_var(irq_disable_mask) & (1UL << irq))) - unmask_irqs(1UL << irq); + if (!(__get_cpu_var(irq_disable_mask) & (1UL << d->irq))) + unmask_irqs(1UL << d->irq); } static struct irq_chip tile_irq_chip = { .name = "tile_irq_chip", - .ack = tile_irq_chip_ack, - .eoi = tile_irq_chip_eoi, - .mask = tile_irq_chip_mask, - .unmask = tile_irq_chip_unmask, + .irq_enable = tile_irq_chip_enable, + .irq_disable = tile_irq_chip_disable, + .irq_ack = tile_irq_chip_ack, + .irq_eoi = tile_irq_chip_eoi, + .irq_mask = tile_irq_chip_mask, + .irq_unmask = tile_irq_chip_unmask, }; void __init init_IRQ(void) @@ -220,7 +216,7 @@ void __init init_IRQ(void) ipi_init(); } -void __cpuinit setup_irq_regs(void) +void setup_irq_regs(void) { /* Enable interrupt delivery. */ unmask_irqs(~0UL); @@ -233,7 +229,7 @@ void tile_irq_activate(unsigned int irq, int tile_irq_type) { /* * We use handle_level_irq() by default because the pending - * interrupt vector (whether modeled by the HV on TILE64 and + * interrupt vector (whether modeled by the HV on * TILEPro or implemented in hardware on TILE-Gx) has * level-style semantics for each bit. An interrupt fires * whenever a bit is high, not just at edges. @@ -241,14 +237,14 @@ void tile_irq_activate(unsigned int irq, int tile_irq_type) irq_flow_handler_t handle = handle_level_irq; if (tile_irq_type == TILE_IRQ_PERCPU) handle = handle_percpu_irq; - set_irq_chip_and_handler(irq, &tile_irq_chip, handle); + irq_set_chip_and_handler(irq, &tile_irq_chip, handle); /* * Flag interrupts that are hardware-cleared so that ack() * won't clear them. */ if (tile_irq_type == TILE_IRQ_HW_CLEAR) - set_irq_chip_data(irq, (void *)IS_HW_CLEARED); + irq_set_chip_data(irq, (void *)IS_HW_CLEARED); } EXPORT_SYMBOL(tile_irq_activate); @@ -259,76 +255,27 @@ void ack_bad_irq(unsigned int irq) } /* - * Generic, controller-independent functions: + * /proc/interrupts printing: */ - -int show_interrupts(struct seq_file *p, void *v) +int arch_show_interrupts(struct seq_file *p, int prec) { - int i = *(loff_t *) v, j; - struct irqaction *action; - unsigned long flags; - - if (i == 0) { - seq_printf(p, " "); - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - seq_printf(p, "CPU%-8d", j); - seq_putc(p, '\n'); - } - - if (i < NR_IRQS) { - raw_spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto skip; - seq_printf(p, "%3d: ", i); -#ifndef CONFIG_SMP - seq_printf(p, "%10u ", kstat_irqs(i)); -#else - for_each_online_cpu(j) - seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); -#endif - seq_printf(p, " %14s", irq_desc[i].chip->name); - seq_printf(p, " %s", action->name); +#ifdef CONFIG_PERF_EVENTS + int i; - for (action = action->next; action; action = action->next) - seq_printf(p, ", %s", action->name); + seq_printf(p, "%*s: ", prec, "PMI"); - seq_putc(p, '\n'); -skip: - raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } + for_each_online_cpu(i) + seq_printf(p, "%10llu ", per_cpu(perf_irqs, i)); + seq_puts(p, " perf_events\n"); +#endif return 0; } #if CHIP_HAS_IPI() -int create_irq(void) +int arch_setup_hwirq(unsigned int irq, int node) { - unsigned long flags; - int result; - - spin_lock_irqsave(&available_irqs_lock, flags); - if (available_irqs == 0) - result = -ENOMEM; - else { - result = __ffs(available_irqs); - available_irqs &= ~(1UL << result); - dynamic_irq_init(result); - } - spin_unlock_irqrestore(&available_irqs_lock, flags); - - return result; + return irq >= NR_IRQS ? -EINVAL : 0; } -EXPORT_SYMBOL(create_irq); -void destroy_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&available_irqs_lock, flags); - available_irqs |= (1UL << irq); - dynamic_irq_cleanup(irq); - spin_unlock_irqrestore(&available_irqs_lock, flags); -} -EXPORT_SYMBOL(destroy_irq); +void arch_teardown_hwirq(unsigned int irq) { } #endif |
