[kernel] r5328 - in people/waldi/linux-2.6: . debian debian/patches debian/patches/series

Bastian Blank waldi at costa.debian.org
Fri Jan 6 22:33:14 UTC 2006


Author: waldi
Date: Fri Jan  6 22:33:09 2006
New Revision: 5328

Added:
   people/waldi/linux-2.6/debian/patches/alpha-generic-irq-1.patch
   people/waldi/linux-2.6/debian/patches/alpha-generic-irq-2.patch
Modified:
   people/waldi/linux-2.6/   (props changed)
   people/waldi/linux-2.6/debian/changelog
   people/waldi/linux-2.6/debian/patches/series/2
Log:
Merge /dists/trunk/linux-2.6.


Modified: people/waldi/linux-2.6/debian/changelog
==============================================================================
--- people/waldi/linux-2.6/debian/changelog	(original)
+++ people/waldi/linux-2.6/debian/changelog	Fri Jan  6 22:33:09 2006
@@ -16,7 +16,10 @@
   [ Sven Luther ]
   * Removed spurious file from powerpc-apus patch. (Closes: #346159)
 
- -- maximilian attems <maks at sternwelten.at>  Fri,  6 Jan 2006 21:06:39 +0100
+  [ Norbert Tretkowski ]
+  * Backport the generic irq framework for alpha. (closes: #339080)
+
+ -- Norbert Tretkowski <nobse at debian.org>  Fri,  6 Jan 2006 23:25:46 +0100
 
 linux-2.6 (2.6.15-1) unstable; urgency=low
 

Added: people/waldi/linux-2.6/debian/patches/alpha-generic-irq-1.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/alpha-generic-irq-1.patch	Fri Jan  6 22:33:09 2006
@@ -0,0 +1,75 @@
+tree a8ed14ee532ea8dabc1010d540542eea1d620540
+parent 1fa744e6e91a895750b9980d13fcfc5791a0cd91
+author Ivan Kokshaysky <ink at jurassic.park.msu.ru> Fri, 06 Jan 2006 16:12:21 -0800
+committer Linus Torvalds <torvalds at g5.osdl.org> Sat, 07 Jan 2006 00:33:40 -0800
+
+[PATCH] Alpha: convert to generic irq framework (generic part)
+
+Thanks to Christoph for doing most of the work.
+
+This allows automatic SMP IRQ affinity assignment other than default "all
+interrupts on all CPUs" which is rather expensive.  This might be useful if
+the hardware can be programmed to distribute interrupts among different
+CPUs, like Alpha does.
+
+Signed-off-by: Ivan Kokshaysky <ink at jurassic.park.msu.ru>
+Cc: Christoph Hellwig <hch at lst.de>
+Cc: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ include/linux/irq.h |   11 +++++++++++
+ kernel/irq/manage.c |    2 ++
+ kernel/irq/proc.c   |    4 +++-
+ 3 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index f04ba20..60f8bc7 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -221,6 +221,17 @@ extern void note_interrupt(unsigned int 
+ extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+ 
+ extern void init_irq_proc(void);
++
++#ifdef CONFIG_AUTO_IRQ_AFFINITY
++extern int select_smp_affinity(unsigned int irq);
++#else
++static inline int
++select_smp_affinity(unsigned int irq)
++{
++	return 1;
++}
++#endif
++
+ #endif
+ 
+ extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 81c49a4..97d5559 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -366,6 +366,8 @@ int request_irq(unsigned int irq,
+ 	action->next = NULL;
+ 	action->dev_id = dev_id;
+ 
++	select_smp_affinity(irq);
++
+ 	retval = setup_irq(irq, action);
+ 	if (retval)
+ 		kfree(action);
+diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
+index f26e534..8a64a48 100644
+--- a/kernel/irq/proc.c
++++ b/kernel/irq/proc.c
+@@ -68,7 +68,9 @@ static int irq_affinity_write_proc(struc
+ 	 */
+ 	cpus_and(tmp, new_value, cpu_online_map);
+ 	if (cpus_empty(tmp))
+-		return -EINVAL;
++		/* Special case for empty set - allow the architecture
++		   code to set default SMP affinity. */
++		return select_smp_affinity(irq) ? -EINVAL : full_count;
+ 
+ 	proc_set_irq_affinity(irq, new_value);
+ 

Added: people/waldi/linux-2.6/debian/patches/alpha-generic-irq-2.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/alpha-generic-irq-2.patch	Fri Jan  6 22:33:09 2006
@@ -0,0 +1,748 @@
+tree f7b4c361b102e483ee87337a6e471ee17ec8ffdc
+parent eee45269b0f5979c70bc151c6c2f4e5f4f5ababe
+author Ivan Kokshaysky <ink at jurassic.park.msu.ru> Fri, 06 Jan 2006 16:12:22 -0800
+committer Linus Torvalds <torvalds at g5.osdl.org> Sat, 07 Jan 2006 00:33:40 -0800
+
+[PATCH] Alpha: convert to generic irq framework (alpha part)
+
+Kconfig tweaks and tons of deletions.
+
+Signed-off-by: Ivan Kokshaysky <ink at jurassic.park.msu.ru>
+Cc: Christoph Hellwig <hch at lst.de>
+Cc: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+
+ arch/alpha/Kconfig              |   13 
+ arch/alpha/kernel/alpha_ksyms.c |    1 
+ arch/alpha/kernel/irq.c         |  630 ----------------------------------------
+ include/asm-alpha/hardirq.h     |    2 
+ 4 files changed, 24 insertions(+), 622 deletions(-)
+
+diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
+index 786491f..153337f 100644
+--- a/arch/alpha/Kconfig
++++ b/arch/alpha/Kconfig
+@@ -40,6 +40,19 @@ config GENERIC_IOMAP
+ 	bool
+ 	default n
+ 
++config GENERIC_HARDIRQS
++	bool
++	default y
++
++config GENERIC_IRQ_PROBE
++	bool
++	default y
++
++config AUTO_IRQ_AFFINITY
++	bool
++	depends on SMP
++	default y
++
+ source "init/Kconfig"
+ 
+ 
+diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
+index 24ae9a3..f3e98f8 100644
+--- a/arch/alpha/kernel/alpha_ksyms.c
++++ b/arch/alpha/kernel/alpha_ksyms.c
+@@ -175,7 +175,6 @@ EXPORT_SYMBOL(up);
+  */
+ 
+ #ifdef CONFIG_SMP
+-EXPORT_SYMBOL(synchronize_irq);
+ EXPORT_SYMBOL(flush_tlb_mm);
+ EXPORT_SYMBOL(flush_tlb_range);
+ EXPORT_SYMBOL(flush_tlb_page);
+diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
+index b6114f5..76be5cf 100644
+--- a/arch/alpha/kernel/irq.c
++++ b/arch/alpha/kernel/irq.c
+@@ -32,214 +32,25 @@
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ 
+-/*
+- * Controller mappings for all interrupt sources:
+- */
+-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
+-	[0 ... NR_IRQS-1] = {
+-		.handler = &no_irq_type,
+-		.lock = SPIN_LOCK_UNLOCKED
+-	}
+-};
+-
+-static void register_irq_proc(unsigned int irq);
+-
+ volatile unsigned long irq_err_count;
+ 
+-/*
+- * Special irq handlers.
+- */
+-
+-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
+-{
+-	return IRQ_NONE;
+-}
+-
+-/*
+- * Generic no controller code
+- */
+-
+-static void no_irq_enable_disable(unsigned int irq) { }
+-static unsigned int no_irq_startup(unsigned int irq) { return 0; }
+-
+-static void
+-no_irq_ack(unsigned int irq)
++void ack_bad_irq(unsigned int irq)
+ {
+ 	irq_err_count++;
+ 	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
+ }
+ 
+-struct hw_interrupt_type no_irq_type = {
+-	.typename	= "none",
+-	.startup	= no_irq_startup,
+-	.shutdown	= no_irq_enable_disable,
+-	.enable		= no_irq_enable_disable,
+-	.disable	= no_irq_enable_disable,
+-	.ack		= no_irq_ack,
+-	.end		= no_irq_enable_disable,
+-};
+-
+-int
+-handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
+-		 struct irqaction *action)
+-{
+-	int status = 1;	/* Force the "do bottom halves" bit */
+-	int ret;
+-
+-	do {
+-		if (!(action->flags & SA_INTERRUPT))
+-			local_irq_enable();
+-		else
+-			local_irq_disable();
+-
+-		ret = action->handler(irq, action->dev_id, regs);
+-		if (ret == IRQ_HANDLED)
+-			status |= action->flags;
+-		action = action->next;
+-	} while (action);
+-	if (status & SA_SAMPLE_RANDOM)
+-		add_interrupt_randomness(irq);
+-	local_irq_disable();
+-
+-	return status;
+-}
+-
+-/*
+- * Generic enable/disable code: this just calls
+- * down into the PIC-specific version for the actual
+- * hardware disable after having gotten the irq
+- * controller lock. 
+- */
+-void inline
+-disable_irq_nosync(unsigned int irq)
+-{
+-	irq_desc_t *desc = irq_desc + irq;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&desc->lock, flags);
+-	if (!desc->depth++) {
+-		desc->status |= IRQ_DISABLED;
+-		desc->handler->disable(irq);
+-	}
+-	spin_unlock_irqrestore(&desc->lock, flags);
+-}
+-
+-/*
+- * Synchronous version of the above, making sure the IRQ is
+- * no longer running on any other IRQ..
+- */
+-void
+-disable_irq(unsigned int irq)
+-{
+-	disable_irq_nosync(irq);
+-	synchronize_irq(irq);
+-}
+-
+-void
+-enable_irq(unsigned int irq)
+-{
+-	irq_desc_t *desc = irq_desc + irq;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&desc->lock, flags);
+-	switch (desc->depth) {
+-	case 1: {
+-		unsigned int status = desc->status & ~IRQ_DISABLED;
+-		desc->status = status;
+-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+-			desc->status = status | IRQ_REPLAY;
+-			hw_resend_irq(desc->handler,irq);
+-		}
+-		desc->handler->enable(irq);
+-		/* fall-through */
+-	}
+-	default:
+-		desc->depth--;
+-		break;
+-	case 0:
+-		printk(KERN_ERR "enable_irq() unbalanced from %p\n",
+-		       __builtin_return_address(0));
+-	}
+-	spin_unlock_irqrestore(&desc->lock, flags);
+-}
+-
+-int
+-setup_irq(unsigned int irq, struct irqaction * new)
+-{
+-	int shared = 0;
+-	struct irqaction *old, **p;
+-	unsigned long flags;
+-	irq_desc_t *desc = irq_desc + irq;
+-
+-        if (desc->handler == &no_irq_type)
+-		return -ENOSYS;
+-
+-	/*
+-	 * Some drivers like serial.c use request_irq() heavily,
+-	 * so we have to be careful not to interfere with a
+-	 * running system.
+-	 */
+-	if (new->flags & SA_SAMPLE_RANDOM) {
+-		/*
+-		 * This function might sleep, we want to call it first,
+-		 * outside of the atomic block.
+-		 * Yes, this might clear the entropy pool if the wrong
+-		 * driver is attempted to be loaded, without actually
+-		 * installing a new handler, but is this really a problem,
+-		 * only the sysadmin is able to do this.
+-		 */
+-		rand_initialize_irq(irq);
+-	}
+-
+-	/*
+-	 * The following block of code has to be executed atomically
+-	 */
+-	spin_lock_irqsave(&desc->lock,flags);
+-	p = &desc->action;
+-	if ((old = *p) != NULL) {
+-		/* Can't share interrupts unless both agree to */
+-		if (!(old->flags & new->flags & SA_SHIRQ)) {
+-			spin_unlock_irqrestore(&desc->lock,flags);
+-			return -EBUSY;
+-		}
+-
+-		/* add new interrupt at end of irq queue */
+-		do {
+-			p = &old->next;
+-			old = *p;
+-		} while (old);
+-		shared = 1;
+-	}
+-
+-	*p = new;
+-
+-	if (!shared) {
+-		desc->depth = 0;
+-		desc->status &=
+-		    ~(IRQ_DISABLED|IRQ_AUTODETECT|IRQ_WAITING|IRQ_INPROGRESS);
+-		desc->handler->startup(irq);
+-	}
+-	spin_unlock_irqrestore(&desc->lock,flags);
+-
+-	return 0;
+-}
+-
+-static struct proc_dir_entry * root_irq_dir;
+-static struct proc_dir_entry * irq_dir[NR_IRQS];
+-
+ #ifdef CONFIG_SMP 
+-static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
+ static char irq_user_affinity[NR_IRQS];
+-static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
+ 
+-static void
+-select_smp_affinity(int irq)
++int
++select_smp_affinity(unsigned int irq)
+ {
+ 	static int last_cpu;
+ 	int cpu = last_cpu + 1;
+ 
+-	if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
+-		return;
++	if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
++		return 1;
+ 
+ 	while (!cpu_possible(cpu))
+ 		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
+@@ -247,208 +58,10 @@ select_smp_affinity(int irq)
+ 
+ 	irq_affinity[irq] = cpumask_of_cpu(cpu);
+ 	irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu));
++	return 0;
+ }
+-
+-static int
+-irq_affinity_read_proc (char *page, char **start, off_t off,
+-			int count, int *eof, void *data)
+-{
+-	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
+-	if (count - len < 2)
+-		return -EINVAL;
+-	len += sprintf(page + len, "\n");
+-	return len;
+-}
+-
+-static int
+-irq_affinity_write_proc(struct file *file, const char __user *buffer,
+-			unsigned long count, void *data)
+-{
+-	int irq = (long) data, full_count = count, err;
+-	cpumask_t new_value;
+-
+-	if (!irq_desc[irq].handler->set_affinity)
+-		return -EIO;
+-
+-	err = cpumask_parse(buffer, count, new_value);
+-
+-	/* The special value 0 means release control of the
+-	   affinity to kernel.  */
+-	cpus_and(new_value, new_value, cpu_online_map);
+-	if (cpus_empty(new_value)) {
+-		irq_user_affinity[irq] = 0;
+-		select_smp_affinity(irq);
+-	}
+-	/* Do not allow disabling IRQs completely - it's a too easy
+-	   way to make the system unusable accidentally :-) At least
+-	   one online CPU still has to be targeted.  */
+-	else {
+-		irq_affinity[irq] = new_value;
+-		irq_user_affinity[irq] = 1;
+-		irq_desc[irq].handler->set_affinity(irq, new_value);
+-	}
+-
+-	return full_count;
+-}
+-
+ #endif /* CONFIG_SMP */
+ 
+-#define MAX_NAMELEN 10
+-
+-static void
+-register_irq_proc (unsigned int irq)
+-{
+-	char name [MAX_NAMELEN];
+-
+-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
+-	    irq_dir[irq])
+-		return;
+-
+-	memset(name, 0, MAX_NAMELEN);
+-	sprintf(name, "%d", irq);
+-
+-	/* create /proc/irq/1234 */
+-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+-
+-#ifdef CONFIG_SMP 
+-	if (irq_desc[irq].handler->set_affinity) {
+-		struct proc_dir_entry *entry;
+-		/* create /proc/irq/1234/smp_affinity */
+-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+-
+-		if (entry) {
+-			entry->nlink = 1;
+-			entry->data = (void *)(long)irq;
+-			entry->read_proc = irq_affinity_read_proc;
+-			entry->write_proc = irq_affinity_write_proc;
+-		}
+-
+-		smp_affinity_entry[irq] = entry;
+-	}
+-#endif
+-}
+-
+-void
+-init_irq_proc (void)
+-{
+-	int i;
+-
+-	/* create /proc/irq */
+-	root_irq_dir = proc_mkdir("irq", NULL);
+-
+-#ifdef CONFIG_SMP 
+-	/* create /proc/irq/prof_cpu_mask */
+-	create_prof_cpu_mask(root_irq_dir);
+-#endif
+-
+-	/*
+-	 * Create entries for all existing IRQs.
+-	 */
+-	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
+-		if (irq_desc[i].handler == &no_irq_type)
+-			continue;
+-		register_irq_proc(i);
+-	}
+-}
+-
+-int
+-request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
+-	    unsigned long irqflags, const char * devname, void *dev_id)
+-{
+-	int retval;
+-	struct irqaction * action;
+-
+-	if (irq >= ACTUAL_NR_IRQS)
+-		return -EINVAL;
+-	if (!handler)
+-		return -EINVAL;
+-
+-#if 1
+-	/*
+-	 * Sanity-check: shared interrupts should REALLY pass in
+-	 * a real dev-ID, otherwise we'll have trouble later trying
+-	 * to figure out which interrupt is which (messes up the
+-	 * interrupt freeing logic etc).
+-	 */
+-	if ((irqflags & SA_SHIRQ) && !dev_id) {
+-		printk(KERN_ERR
+-		       "Bad boy: %s (at %p) called us without a dev_id!\n",
+-		       devname, __builtin_return_address(0));
+-	}
+-#endif
+-
+-	action = (struct irqaction *)
+-			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+-	if (!action)
+-		return -ENOMEM;
+-
+-	action->handler = handler;
+-	action->flags = irqflags;
+-	cpus_clear(action->mask);
+-	action->name = devname;
+-	action->next = NULL;
+-	action->dev_id = dev_id;
+-
+-#ifdef CONFIG_SMP
+-	select_smp_affinity(irq);
+-#endif
+-
+-	retval = setup_irq(irq, action);
+-	if (retval)
+-		kfree(action);
+-	return retval;
+-}
+-
+-EXPORT_SYMBOL(request_irq);
+-
+-void
+-free_irq(unsigned int irq, void *dev_id)
+-{
+-	irq_desc_t *desc;
+-	struct irqaction **p;
+-	unsigned long flags;
+-
+-	if (irq >= ACTUAL_NR_IRQS) {
+-		printk(KERN_CRIT "Trying to free IRQ%d\n", irq);
+-		return;
+-	}
+-
+-	desc = irq_desc + irq;
+-	spin_lock_irqsave(&desc->lock,flags);
+-	p = &desc->action;
+-	for (;;) {
+-		struct irqaction * action = *p;
+-		if (action) {
+-			struct irqaction **pp = p;
+-			p = &action->next;
+-			if (action->dev_id != dev_id)
+-				continue;
+-
+-			/* Found - now remove it from the list of entries.  */
+-			*pp = action->next;
+-			if (!desc->action) {
+-				desc->status |= IRQ_DISABLED;
+-				desc->handler->shutdown(irq);
+-			}
+-			spin_unlock_irqrestore(&desc->lock,flags);
+-
+-#ifdef CONFIG_SMP
+-			/* Wait to make sure it's not being used on
+-			   another CPU.  */
+-			while (desc->status & IRQ_INPROGRESS)
+-				barrier();
+-#endif
+-			kfree(action);
+-			return;
+-		}
+-		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
+-		spin_unlock_irqrestore(&desc->lock,flags);
+-		return;
+-	}
+-}
+-
+-EXPORT_SYMBOL(free_irq);
+-
+ int
+ show_interrupts(struct seq_file *p, void *v)
+ {
+@@ -531,10 +144,6 @@ handle_irq(int irq, struct pt_regs * reg
+ 	 * 0 return value means that this irq is already being
+ 	 * handled by some other CPU. (or is disabled)
+ 	 */
+-	int cpu = smp_processor_id();
+-	irq_desc_t *desc = irq_desc + irq;
+-	struct irqaction * action;
+-	unsigned int status;
+ 	static unsigned int illegal_count=0;
+ 	
+ 	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
+@@ -546,229 +155,8 @@ handle_irq(int irq, struct pt_regs * reg
+ 	}
+ 
+ 	irq_enter();
+-	kstat_cpu(cpu).irqs[irq]++;
+-	spin_lock_irq(&desc->lock); /* mask also the higher prio events */
+-	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.
+-	 */
+-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+-	status |= IRQ_PENDING; /* we _want_ to handle it */
+-
+-	/*
+-	 * If the IRQ is disabled for whatever reason, we cannot
+-	 * use the action we have.
+-	 */
+-	action = NULL;
+-	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+-		action = desc->action;
+-		status &= ~IRQ_PENDING; /* we commit to handling */
+-		status |= IRQ_INPROGRESS; /* we are handling it */
+-	}
+-	desc->status = status;
+-
+-	/*
+-	 * If there is no IRQ handler or it was disabled, exit early.
+-	 * Since we set PENDING, if another processor is handling
+-	 * a different instance of this same irq, the other processor
+-	 * will take care of it.
+-	 */
+-	if (!action)
+-		goto out;
+-
+-	/*
+-	 * Edge triggered interrupts need to remember pending events.
+-	 * This applies to any hw interrupts that allow a second
+-	 * instance of the same irq to arrive while we are in handle_irq
+-	 * or in the handler. But the code here only handles the _second_
+-	 * instance of the irq, not the third or fourth. So it is mostly
+-	 * useful for irq hardware that does not mask cleanly in an
+-	 * SMP environment.
+-	 */
+-	for (;;) {
+-		spin_unlock(&desc->lock);
+-		handle_IRQ_event(irq, regs, action);
+-		spin_lock(&desc->lock);
+-		
+-		if (!(desc->status & IRQ_PENDING)
+-		    || (desc->status & IRQ_LEVEL))
+-			break;
+-		desc->status &= ~IRQ_PENDING;
+-	}
+-	desc->status &= ~IRQ_INPROGRESS;
+-out:
+-	/*
+-	 * The ->end() handler has to deal with interrupts which got
+-	 * disabled while the handler was running.
+-	 */
+-	desc->handler->end(irq);
+-	spin_unlock(&desc->lock);
+-
++	local_irq_disable();
++	__do_IRQ(irq, regs);
++	local_irq_enable();
+ 	irq_exit();
+ }
+-
+-/*
+- * IRQ autodetection code..
+- *
+- * This depends on the fact that any interrupt that
+- * comes in on to an unassigned handler will get stuck
+- * with "IRQ_WAITING" cleared and the interrupt
+- * disabled.
+- */
+-unsigned long
+-probe_irq_on(void)
+-{
+-	int i;
+-	irq_desc_t *desc;
+-	unsigned long delay;
+-	unsigned long val;
+-
+-	/* Something may have generated an irq long ago and we want to
+-	   flush such a longstanding irq before considering it as spurious. */
+-	for (i = NR_IRQS-1; i >= 0; i--) {
+-		desc = irq_desc + i;
+-
+-		spin_lock_irq(&desc->lock);
+-		if (!irq_desc[i].action) 
+-			irq_desc[i].handler->startup(i);
+-		spin_unlock_irq(&desc->lock);
+-	}
+-
+-	/* Wait for longstanding interrupts to trigger. */
+-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+-		/* about 20ms delay */ barrier();
+-
+-	/* enable any unassigned irqs (we must startup again here because
+-	   if a longstanding irq happened in the previous stage, it may have
+-	   masked itself) first, enable any unassigned irqs. */
+-	for (i = NR_IRQS-1; i >= 0; i--) {
+-		desc = irq_desc + i;
+-
+-		spin_lock_irq(&desc->lock);
+-		if (!desc->action) {
+-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+-			if (desc->handler->startup(i))
+-				desc->status |= IRQ_PENDING;
+-		}
+-		spin_unlock_irq(&desc->lock);
+-	}
+-
+-	/*
+-	 * Wait for spurious interrupts to trigger
+-	 */
+-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+-		/* about 100ms delay */ barrier();
+-
+-	/*
+-	 * Now filter out any obviously spurious interrupts
+-	 */
+-	val = 0;
+-	for (i=0; i<NR_IRQS; i++) {
+-		irq_desc_t *desc = irq_desc + i;
+-		unsigned int status;
+-
+-		spin_lock_irq(&desc->lock);
+-		status = desc->status;
+-
+-		if (status & IRQ_AUTODETECT) {
+-			/* It triggered already - consider it spurious. */
+-			if (!(status & IRQ_WAITING)) {
+-				desc->status = status & ~IRQ_AUTODETECT;
+-				desc->handler->shutdown(i);
+-			} else
+-				if (i < 32)
+-					val |= 1 << i;
+-		}
+-		spin_unlock_irq(&desc->lock);
+-	}
+-
+-	return val;
+-}
+-
+-EXPORT_SYMBOL(probe_irq_on);
+-
+-/*
+- * Return a mask of triggered interrupts (this
+- * can handle only legacy ISA interrupts).
+- */
+-unsigned int
+-probe_irq_mask(unsigned long val)
+-{
+-	int i;
+-	unsigned int mask;
+-
+-	mask = 0;
+-	for (i = 0; i < NR_IRQS; i++) {
+-		irq_desc_t *desc = irq_desc + i;
+-		unsigned int status;
+-
+-		spin_lock_irq(&desc->lock);
+-		status = desc->status;
+-
+-		if (status & IRQ_AUTODETECT) {
+-			/* We only react to ISA interrupts */
+-			if (!(status & IRQ_WAITING)) {
+-				if (i < 16)
+-					mask |= 1 << i;
+-			}
+-
+-			desc->status = status & ~IRQ_AUTODETECT;
+-			desc->handler->shutdown(i);
+-		}
+-		spin_unlock_irq(&desc->lock);
+-	}
+-
+-	return mask & val;
+-}
+-
+-/*
+- * Get the result of the IRQ probe.. A negative result means that
+- * we have several candidates (but we return the lowest-numbered
+- * one).
+- */
+-
+-int
+-probe_irq_off(unsigned long val)
+-{
+-	int i, irq_found, nr_irqs;
+-
+-	nr_irqs = 0;
+-	irq_found = 0;
+-	for (i=0; i<NR_IRQS; i++) {
+-		irq_desc_t *desc = irq_desc + i;
+-		unsigned int status;
+-
+-		spin_lock_irq(&desc->lock);
+-		status = desc->status;
+-
+-		if (status & IRQ_AUTODETECT) {
+-			if (!(status & IRQ_WAITING)) {
+-				if (!nr_irqs)
+-					irq_found = i;
+-				nr_irqs++;
+-			}
+-			desc->status = status & ~IRQ_AUTODETECT;
+-			desc->handler->shutdown(i);
+-		}
+-		spin_unlock_irq(&desc->lock);
+-	}
+-
+-	if (nr_irqs > 1)
+-		irq_found = -irq_found;
+-	return irq_found;
+-}
+-
+-EXPORT_SYMBOL(probe_irq_off);
+-
+-#ifdef CONFIG_SMP
+-void synchronize_irq(unsigned int irq)
+-{
+-        /* is there anything to synchronize with? */
+-	if (!irq_desc[irq].action)
+-		return;
+-
+-	while (irq_desc[irq].status & IRQ_INPROGRESS)
+-		barrier();
+-}
+-#endif
+diff --git a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
+index c0593f9..7bb6a36 100644
+--- a/include/asm-alpha/hardirq.h
++++ b/include/asm-alpha/hardirq.h
+@@ -13,6 +13,8 @@ typedef struct {
+ 
+ #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+ 
++void ack_bad_irq(unsigned int irq);
++
+ #define HARDIRQ_BITS	12
+ 
+ /*

Modified: people/waldi/linux-2.6/debian/patches/series/2
==============================================================================
--- people/waldi/linux-2.6/debian/patches/series/2	(original)
+++ people/waldi/linux-2.6/debian/patches/series/2	Fri Jan  6 22:33:09 2006
@@ -1,3 +1,4 @@
 - powerpc-arch-default-powerpc.patch
 + alsa-opl3-oops.patch
-
++ alpha-generic-irq-1.patch
++ alpha-generic-irq-2.patch



More information about the Kernel-svn-changes mailing list