X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Firq%2Fhandle.c;h=51df337b37db860b1141683d6fa0a01f6300ac0d;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=553a098888c8991ae9ed2751406712954ab9047e;hpb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;p=linux-2.6.git diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 553a09888..51df337b3 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -1,13 +1,9 @@ /* * linux/kernel/irq/handle.c * - * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar - * Copyright (C) 2005-2006, Thomas Gleixner, Russell King + * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar * * This file contains the core interrupt handling code. - * - * Detailed information is available in Documentation/DocBook/genericirq - * */ #include @@ -15,31 +11,14 @@ #include #include #include -#include #include "internals.h" -/** - * handle_bad_irq - handle spurious and unhandled irqs - * @irq: the interrupt number - * @desc: description of the interrupt - * @regs: pointer to a register structure - * - * Handles spurious and unhandled IRQ's. It also prints a debugmessage. - */ -void fastcall -handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) -{ - print_irq_desc(irq, desc); - kstat_this_cpu.irqs[irq]++; - ack_bad_irq(irq); -} - /* * Linux has a controller-independent interrupt architecture. * Every controller has a 'controller-template', that is used * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the appropriate + * interrupt source is transparently wired to the apropriate * controller. Thus drivers need not be aware of the * interrupt-controller. * @@ -49,68 +28,41 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) * * Controller mappings for all interrupt sources: */ -struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = { +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { .status = IRQ_DISABLED, - .chip = &no_irq_chip, - .handle_irq = handle_bad_irq, - .depth = 1, - .lock = SPIN_LOCK_UNLOCKED, -#ifdef CONFIG_SMP - .affinity = CPU_MASK_ALL -#endif + .handler = &no_irq_type, + .lock = SPIN_LOCK_UNLOCKED } }; /* - * What should we do if we get a hw irq event on an illegal vector? - * Each architecture has to answer this themself. - */ -static void ack_bad(unsigned int irq) -{ - print_irq_desc(irq, irq_desc + irq); - ack_bad_irq(irq); -} - -/* - * NOP functions + * Generic 'no controller' code */ -static void noop(unsigned int irq) -{ -} +static void end_none(unsigned int irq) { } +static void enable_none(unsigned int irq) { } +static void disable_none(unsigned int irq) { } +static void shutdown_none(unsigned int irq) { } +static unsigned int startup_none(unsigned int irq) { return 0; } -static unsigned int noop_ret(unsigned int irq) +static void ack_none(unsigned int irq) { - return 0; + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themself. + */ + ack_bad_irq(irq); } -/* - * Generic no controller implementation - */ -struct irq_chip no_irq_chip = { - .name = "none", - .startup = noop_ret, - .shutdown = noop, - .enable = noop, - .disable = noop, - .ack = ack_bad, - .end = noop, -}; - -/* - * Generic dummy implementation which can be used for - * real dumb interrupt sources - */ -struct irq_chip dummy_irq_chip = { - .name = "dummy", - .startup = noop_ret, - .shutdown = noop, - .enable = noop, - .disable = noop, - .ack = noop, - .mask = noop, - .unmask = noop, - .end = noop, +struct hw_interrupt_type no_irq_type = { + .typename = "none", + .startup = startup_none, + .shutdown = shutdown_none, + .enable = enable_none, + .disable = disable_none, + .ack = ack_none, + .end = end_none, + .set_affinity = NULL }; /* @@ -121,24 +73,16 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) return IRQ_NONE; } -/** - * handle_IRQ_event - irq action chain handler - * @irq: the interrupt number - * @regs: pointer to a register structure - * @action: the interrupt action chain for this irq - * - * Handles the action chain of an irq event +/* + * Have got an event to handle: */ -irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, - struct irqaction *action) +fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, + struct irqaction *action) { - irqreturn_t ret, retval = IRQ_NONE; - unsigned int status = 0; + int ret, retval = 0, status = 0; - handle_dynamic_tick(action); - - if (!(action->flags & IRQF_DISABLED)) - local_irq_enable_in_hardirq(); + if (!(action->flags & SA_INTERRUPT)) + local_irq_enable(); do { ret = action->handler(irq, action->dev_id, regs); @@ -148,30 +92,22 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, action = action->next; } while (action); - if (status & IRQF_SAMPLE_RANDOM) + if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); return retval; } -/** - * __do_IRQ - original all in one highlevel IRQ handler - * @irq: the interrupt number - * @regs: pointer to a register structure - * - * __do_IRQ handles all normal device IRQ's (the special +/* + * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific * handlers). - * - * This is the original x86 implementation which is used for every - * interrupt type. */ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) { - struct irq_desc *desc = irq_desc + irq; - struct irqaction *action; - struct vx_info_save vxis; + irq_desc_t *desc = irq_desc + irq; + struct irqaction * action; unsigned int status; kstat_this_cpu.irqs[irq]++; @@ -181,19 +117,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) /* * No locking required for CPU-local interrupts: */ - __enter_vx_admin(&vxis); - if (desc->chip->ack) - desc->chip->ack(irq); + if (desc->handler->ack) + desc->handler->ack(irq); action_ret = handle_IRQ_event(irq, regs, desc->action); - desc->chip->end(irq); - __leave_vx_admin(&vxis); + desc->handler->end(irq); return 1; } spin_lock(&desc->lock); - __enter_vx_admin(&vxis); - if (desc->chip->ack) - desc->chip->ack(irq); + if (desc->handler->ack) + desc->handler->ack(irq); /* * REPLAY is when Linux resends an IRQ that was dropped earlier * WAITING is used by probe to mark irqs that are being tested @@ -253,26 +186,9 @@ out: * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ - desc->chip->end(irq); - __leave_vx_admin(&vxis); + desc->handler->end(irq); spin_unlock(&desc->lock); return 1; } -#ifdef CONFIG_TRACE_IRQFLAGS - -/* - * lockdep: we want to handle all irq_desc locks as a single lock-class: - */ -static struct lock_class_key irq_desc_lock_class; - -void early_init_irq_lock_class(void) -{ - int i; - - for (i = 0; i < NR_IRQS; i++) - lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); -} - -#endif