ia64/xen-unstable

changeset 3062:38c450a5a8a3

bitkeeper revision 1.1159.179.12 (419e133foVH755X0bQ79WRObEybang)

Add teardown_irq and update do_IRQ interface to match the Linux 2.6 one.
author cl349@arcadians.cl.cam.ac.uk
date Fri Nov 19 15:37:35 2004 +0000 (2004-11-19)
parents 911ddd7a09c1
children 8651c3cb88d9 88d784c1d7c4
files .rootkeys linux-2.4.27-xen-sparse/arch/xen/kernel/irq.c linux-2.4.27-xen-sparse/include/linux/irq.h linux-2.6.10-rc2-xen-sparse/arch/xen/kernel/evtchn.c
line diff
     1.1 --- a/.rootkeys	Fri Nov 19 14:02:29 2004 +0000
     1.2 +++ b/.rootkeys	Fri Nov 19 15:37:35 2004 +0000
     1.3 @@ -112,6 +112,7 @@ 3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4
     1.4  3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.27-xen-sparse/include/asm-xen/vga.h
     1.5  40659defgWA92arexpMGn8X3QMDj3w linux-2.4.27-xen-sparse/include/asm-xen/xor.h
     1.6  3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.27-xen-sparse/include/linux/blk.h
     1.7 +419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.27-xen-sparse/include/linux/irq.h
     1.8  4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.27-xen-sparse/include/linux/mm.h
     1.9  401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.27-xen-sparse/include/linux/sched.h
    1.10  40a248afgI0_JKthdYAe8beVfXSTpQ linux-2.4.27-xen-sparse/include/linux/skbuff.h
     2.1 --- a/linux-2.4.27-xen-sparse/arch/xen/kernel/irq.c	Fri Nov 19 14:02:29 2004 +0000
     2.2 +++ b/linux-2.4.27-xen-sparse/arch/xen/kernel/irq.c	Fri Nov 19 15:37:35 2004 +0000
     2.3 @@ -559,7 +559,7 @@ void enable_irq(unsigned int irq)
     2.4   * SMP cross-CPU interrupts have their own specific
     2.5   * handlers).
     2.6   */
     2.7 -asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
     2.8 +asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
     2.9  {	
    2.10  	/* 
    2.11  	 * We ack quickly, we don't want the irq controller
    2.12 @@ -571,6 +571,7 @@ asmlinkage unsigned int do_IRQ(int irq, 
    2.13  	 * 0 return value means that this irq is already being
    2.14  	 * handled by some other CPU. (or is disabled)
    2.15  	 */
    2.16 +	int irq = regs->orig_eax & 0xff; /* high bits used in ret_from_ code */
    2.17  	int cpu = smp_processor_id();
    2.18  	irq_desc_t *desc = irq_desc + irq;
    2.19  	struct irqaction * action;
    2.20 @@ -731,6 +732,53 @@ int request_irq(unsigned int irq,
    2.21  	return retval;
    2.22  }
    2.23  
    2.24 +/*
    2.25 + * Internal function to unregister an irqaction - typically used to
    2.26 + * deallocate special interrupts that are part of the architecture.
    2.27 + */
    2.28 +int teardown_irq(unsigned int irq, struct irqaction * old)
    2.29 +{
    2.30 +	irq_desc_t *desc;
    2.31 +	struct irqaction **p;
    2.32 +	unsigned long flags;
    2.33 +
    2.34 +	if (irq >= NR_IRQS)
    2.35 +		return -ENOENT;
    2.36 +
    2.37 +	desc = irq_desc + irq;
    2.38 +	spin_lock_irqsave(&desc->lock,flags);
    2.39 +	p = &desc->action;
    2.40 +	for (;;) {
    2.41 +		struct irqaction * action = *p;
    2.42 +		if (action) {
    2.43 +			struct irqaction **pp = p;
    2.44 +			p = &action->next;
    2.45 +			if (action != old)
    2.46 +				continue;
    2.47 +
    2.48 +			/* Found it - now remove it from the list of entries */
    2.49 +			*pp = action->next;
    2.50 +			if (!desc->action) {
    2.51 +				desc->status |= IRQ_DISABLED;
    2.52 +				desc->handler->shutdown(irq);
    2.53 +			}
    2.54 +			spin_unlock_irqrestore(&desc->lock,flags);
    2.55 +
    2.56 +#ifdef CONFIG_SMP
    2.57 +			/* Wait to make sure it's not being used on another CPU */
    2.58 +			while (desc->status & IRQ_INPROGRESS) {
    2.59 +				barrier();
    2.60 +				cpu_relax();
    2.61 +			}
    2.62 +#endif
    2.63 +			return 0;
    2.64 +		}
    2.65 +		printk("Trying to free free IRQ%d\n",irq);
    2.66 +		spin_unlock_irqrestore(&desc->lock,flags);
    2.67 +		return -ENOENT;
    2.68 +	}
    2.69 +}
    2.70 +
    2.71  /**
    2.72   *	free_irq - free an interrupt
    2.73   *	@irq: Interrupt line to free
    2.74 @@ -752,7 +800,7 @@ int request_irq(unsigned int irq,
    2.75  void free_irq(unsigned int irq, void *dev_id)
    2.76  {
    2.77  	irq_desc_t *desc;
    2.78 -	struct irqaction **p;
    2.79 +	struct irqaction *action;
    2.80  	unsigned long flags;
    2.81  
    2.82  	if (irq >= NR_IRQS)
    2.83 @@ -760,39 +808,19 @@ void free_irq(unsigned int irq, void *de
    2.84  
    2.85  	desc = irq_desc + irq;
    2.86  	spin_lock_irqsave(&desc->lock,flags);
    2.87 -	p = &desc->action;
    2.88 -	for (;;) {
    2.89 -		struct irqaction * action = *p;
    2.90 -		if (action) {
    2.91 -			struct irqaction **pp = p;
    2.92 -			p = &action->next;
    2.93 -			if (action->dev_id != dev_id)
    2.94 -				continue;
    2.95 +	for (action = desc->action; action != NULL; action = action->next) {
    2.96 +		if (action->dev_id != dev_id)
    2.97 +			continue;
    2.98  
    2.99 -			/* Found it - now remove it from the list of entries */
   2.100 -			*pp = action->next;
   2.101 -			if (!desc->action) {
   2.102 -				desc->status |= IRQ_DISABLED;
   2.103 -				desc->handler->shutdown(irq);
   2.104 -			}
   2.105 -			spin_unlock_irqrestore(&desc->lock,flags);
   2.106 +		spin_unlock_irqrestore(&desc->lock,flags);
   2.107  
   2.108 -#ifdef CONFIG_SMP
   2.109 -			/* Wait to make sure it's not being used on another CPU */
   2.110 -			while (desc->status & IRQ_INPROGRESS) {
   2.111 -				barrier();
   2.112 -				cpu_relax();
   2.113 -			}
   2.114 -#endif
   2.115 -#define SA_STATIC_ACTION 0x01000000 /* Is it our duty to free the action? */
   2.116 -			if (!(action->flags & SA_STATIC_ACTION))
   2.117 -				kfree(action);
   2.118 -			return;
   2.119 -		}
   2.120 -		printk("Trying to free free IRQ%d\n",irq);
   2.121 -		spin_unlock_irqrestore(&desc->lock,flags);
   2.122 +		if (teardown_irq(irq, action) == 0)
   2.123 +			kfree(action);
   2.124  		return;
   2.125  	}
   2.126 +	printk("Trying to free free IRQ%d\n",irq);
   2.127 +	spin_unlock_irqrestore(&desc->lock,flags);
   2.128 +	return;
   2.129  }
   2.130  
   2.131  /*
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/linux-2.4.27-xen-sparse/include/linux/irq.h	Fri Nov 19 15:37:35 2004 +0000
     3.3 @@ -0,0 +1,80 @@
     3.4 +#ifndef __irq_h
     3.5 +#define __irq_h
     3.6 +
     3.7 +/*
     3.8 + * Please do not include this file in generic code.  There is currently
     3.9 + * no requirement for any architecture to implement anything held
    3.10 + * within this file.
    3.11 + *
    3.12 + * Thanks. --rmk
    3.13 + */
    3.14 +
    3.15 +#include <linux/config.h>
    3.16 +
    3.17 +#if !defined(CONFIG_ARCH_S390)
    3.18 +
    3.19 +#include <linux/cache.h>
    3.20 +#include <linux/spinlock.h>
    3.21 +
    3.22 +#include <asm/irq.h>
    3.23 +#include <asm/ptrace.h>
    3.24 +
    3.25 +/*
    3.26 + * IRQ line status.
    3.27 + */
    3.28 +#define IRQ_INPROGRESS	1	/* IRQ handler active - do not enter! */
    3.29 +#define IRQ_DISABLED	2	/* IRQ disabled - do not enter! */
    3.30 +#define IRQ_PENDING	4	/* IRQ pending - replay on enable */
    3.31 +#define IRQ_REPLAY	8	/* IRQ has been replayed but not acked yet */
    3.32 +#define IRQ_AUTODETECT	16	/* IRQ is being autodetected */
    3.33 +#define IRQ_WAITING	32	/* IRQ not yet seen - for autodetection */
    3.34 +#define IRQ_LEVEL	64	/* IRQ level triggered */
    3.35 +#define IRQ_MASKED	128	/* IRQ masked - shouldn't be seen again */
    3.36 +#define IRQ_PER_CPU	256	/* IRQ is per CPU */
    3.37 +
    3.38 +/*
    3.39 + * Interrupt controller descriptor. This is all we need
    3.40 + * to describe about the low-level hardware. 
    3.41 + */
    3.42 +struct hw_interrupt_type {
    3.43 +	const char * typename;
    3.44 +	unsigned int (*startup)(unsigned int irq);
    3.45 +	void (*shutdown)(unsigned int irq);
    3.46 +	void (*enable)(unsigned int irq);
    3.47 +	void (*disable)(unsigned int irq);
    3.48 +	void (*ack)(unsigned int irq);
    3.49 +	void (*end)(unsigned int irq);
    3.50 +	void (*set_affinity)(unsigned int irq, unsigned long mask);
    3.51 +};
    3.52 +
    3.53 +typedef struct hw_interrupt_type  hw_irq_controller;
    3.54 +
    3.55 +/*
    3.56 + * This is the "IRQ descriptor", which contains various information
    3.57 + * about the irq, including what kind of hardware handling it has,
    3.58 + * whether it is disabled etc etc.
    3.59 + *
    3.60 + * Pad this out to 32 bytes for cache and indexing reasons.
    3.61 + */
    3.62 +typedef struct {
    3.63 +	unsigned int status;		/* IRQ status */
    3.64 +	hw_irq_controller *handler;
    3.65 +	struct irqaction *action;	/* IRQ action list */
    3.66 +	unsigned int depth;		/* nested irq disables */
    3.67 +	spinlock_t lock;
    3.68 +} ____cacheline_aligned irq_desc_t;
    3.69 +
    3.70 +extern irq_desc_t irq_desc [NR_IRQS];
    3.71 +
    3.72 +#include <asm/hw_irq.h> /* the arch dependent stuff */
    3.73 +
    3.74 +extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
    3.75 +extern int setup_irq(unsigned int , struct irqaction * );
    3.76 +extern int teardown_irq(unsigned int , struct irqaction * );
    3.77 +
    3.78 +extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
    3.79 +extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
    3.80 +
    3.81 +#endif
    3.82 +
    3.83 +#endif /* __irq_h */
     4.1 --- a/linux-2.6.10-rc2-xen-sparse/arch/xen/kernel/evtchn.c	Fri Nov 19 14:02:29 2004 +0000
     4.2 +++ b/linux-2.6.10-rc2-xen-sparse/arch/xen/kernel/evtchn.c	Fri Nov 19 15:37:35 2004 +0000
     4.3 @@ -69,7 +69,11 @@ static unsigned long pirq_needs_unmask_n
     4.4  
     4.5  /* Upcall to generic IRQ layer. */
     4.6  #ifdef CONFIG_X86
     4.7 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
     4.8  extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
     4.9 +#else
    4.10 +extern asmlinkage unsigned int do_IRQ(struct pt_regs *regs);
    4.11 +#endif
    4.12  #define do_IRQ(irq, regs) do {		\
    4.13      (regs)->orig_eax = (irq);		\
    4.14      do_IRQ((regs));			\