X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fkernel%2Firq.c;h=410b9a72aba97439c042eac98208e6da0ffd3203;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=aac8af5aae51ddcea1a954ee7876b104c2d40576;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index aac8af5aa..410b9a72a 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -154,11 +154,9 @@ void (*sparc_init_timers)(irqreturn_t (*)(int, void *,struct pt_regs *)) = struct irqaction static_irqaction[MAX_STATIC_ALLOC]; int static_irq_count; -struct { - struct irqaction *action; - int flags; -} sparc_irq[NR_IRQS]; -#define SPARC_IRQ_INPROGRESS 1 +struct irqaction *irq_action[NR_IRQS] = { + [0 ... (NR_IRQS-1)] = NULL +}; /* Used to protect the IRQ action lists */ DEFINE_SPINLOCK(irq_action_lock); @@ -179,16 +177,17 @@ int show_interrupts(struct seq_file *p, void *v) } spin_lock_irqsave(&irq_action_lock, flags); if (i < NR_IRQS) { - action = sparc_irq[i].action; + action = *(i + irq_action); if (!action) goto out_unlock; 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_cpu(j).irqs[i]); + for (j = 0; j < NR_CPUS; j++) { + if (cpu_online(j)) + seq_printf(p, "%10u ", + kstat_cpu(cpu_logical_map(j)).irqs[i]); } #endif seq_printf(p, " %c %s", @@ -209,7 +208,7 @@ out_unlock: void free_irq(unsigned int irq, void *dev_id) { struct irqaction * action; - struct irqaction **actionp; + struct irqaction * tmp = NULL; unsigned long flags; unsigned int cpu_irq; @@ -227,8 +226,7 @@ void free_irq(unsigned int irq, void *dev_id) spin_lock_irqsave(&irq_action_lock, flags); - actionp = &sparc_irq[cpu_irq].action; - action = *actionp; + action = *(cpu_irq + irq_action); if (!action->handler) { printk("Trying to free free IRQ%d\n",irq); @@ -238,7 +236,7 @@ void free_irq(unsigned int irq, void *dev_id) for (; action; action = action->next) { if (action->dev_id == dev_id) break; - actionp = &action->next; + tmp = action; } if (!action) { printk("Trying to free free shared IRQ%d\n",irq); @@ -257,8 +255,11 @@ void free_irq(unsigned int irq, void *dev_id) irq, action->name); goto out_unlock; } - - *actionp = action->next; + + if (action && tmp) + tmp->next = action->next; + else + *(cpu_irq + irq_action) = action->next; spin_unlock_irqrestore(&irq_action_lock, flags); @@ -268,7 +269,7 @@ void free_irq(unsigned int irq, void *dev_id) kfree(action); - if (!sparc_irq[cpu_irq].action) + if (!(*(cpu_irq + irq_action))) disable_irq(irq); out_unlock: @@ -287,11 +288,8 @@ EXPORT_SYMBOL(free_irq); #ifdef CONFIG_SMP void synchronize_irq(unsigned int irq) { - unsigned int cpu_irq; - - cpu_irq = irq & (NR_IRQS - 1); - while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS) - cpu_relax(); + printk("synchronize_irq says: implement me!\n"); + BUG(); } #endif /* SMP */ @@ -302,7 +300,7 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) unsigned int cpu_irq; cpu_irq = irq & (NR_IRQS - 1); - action = sparc_irq[cpu_irq].action; + action = *(cpu_irq + irq_action); printk("IO device interrupt, irq = %d\n", irq); printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, @@ -333,8 +331,7 @@ void handler_irq(int irq, struct pt_regs * regs) if(irq < 10) smp4m_irq_rotate(cpu); #endif - action = sparc_irq[irq].action; - sparc_irq[irq].flags |= SPARC_IRQ_INPROGRESS; + action = *(irq + irq_action); kstat_cpu(cpu).irqs[irq]++; do { if (!action || !action->handler) @@ -342,7 +339,6 @@ void handler_irq(int irq, struct pt_regs * regs) action->handler(irq, action->dev_id, regs); action = action->next; } while (action); - sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS; enable_pil_irq(irq); irq_exit(); } @@ -394,7 +390,7 @@ int request_fast_irq(unsigned int irq, spin_lock_irqsave(&irq_action_lock, flags); - action = sparc_irq[cpu_irq].action; + action = *(cpu_irq + irq_action); if(action) { if(action->flags & SA_SHIRQ) panic("Trying to register fast irq when already shared.\n"); @@ -457,7 +453,7 @@ int request_fast_irq(unsigned int irq, action->dev_id = NULL; action->next = NULL; - sparc_irq[cpu_irq].action = action; + *(cpu_irq + irq_action) = action; enable_irq(irq); @@ -472,7 +468,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { - struct irqaction * action, **actionp; + struct irqaction * action, *tmp = NULL; unsigned long flags; unsigned int cpu_irq; int ret; @@ -495,20 +491,20 @@ int request_irq(unsigned int irq, spin_lock_irqsave(&irq_action_lock, flags); - actionp = &sparc_irq[cpu_irq].action; - action = *actionp; + action = *(cpu_irq + irq_action); if (action) { - if (!(action->flags & SA_SHIRQ) || !(irqflags & SA_SHIRQ)) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { ret = -EBUSY; goto out_unlock; } - if ((action->flags & SA_INTERRUPT) != (irqflags & SA_INTERRUPT)) { + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); ret = -EBUSY; goto out_unlock; - } - for ( ; action; action = *actionp) - actionp = &action->next; + } + action = NULL; /* Or else! */ } /* If this is flagged as statically allocated then we use our @@ -537,7 +533,10 @@ int request_irq(unsigned int irq, action->next = NULL; action->dev_id = dev_id; - *actionp = action; + if (tmp) + tmp->next = action; + else + *(cpu_irq + irq_action) = action; enable_irq(irq);