diff options
| author | Ingo Molnar <mingo@elte.hu> | 2004-10-18 08:55:37 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-18 08:55:37 -0700 |
| commit | 653853bcaf83a235f3109d00f4ae4af39f9a5872 (patch) | |
| tree | 74ac26de3840bc995401cb664788cb16f5e33cae /include/linux | |
| parent | 2dbc57298d84fe37d855c8bfa3b280dfd47ded4b (diff) | |
[PATCH] generic irq subsystem: core
The main goal of this patch is to consolidate all the different but still
fundamentally similar arch/*/kernel/irq.c code into the kernel/irq/ subsystem.
There are 4 new files in the kernel/irq/ directory:
- handle.c: core bits: __do_IRQ() and handle_IRQ_event(),
callable from arch-specific irq.c code.
- manage.c: the main driver apis
- spurious.c: the handling of buggy interrupt sources.
- autoprobe.c: probing of interrupts - older code but still in use.
- proc.c: /proc/irq/ code.
- internals.h for irq-core-internal interfaces not visible to drivers
nor arch PIC code.
An architecture enables the generic hardirq code by defining
CONFIG_GENERIC_HARDIRQS in its arch Kconfig. People doing this conversion
should check out the x86/x64/ppc/ppc64 patches for details - the conversion is
quite straightforward but every converted function (i.e. every function
removed from the arch irq.c) _must_ be matched to the generic version and if
there is any detail that the generic code should do it has to be added to the
generic code. All of the currently converted 4 architectures were converted
like that, and the generic code was extended/fixed along the way.
Other changes related to this patchset:
- clean up the irq include files (linux/irq.h, linux/interrupt.h,
linux/hardirq.h) and consolidate asm-*/[hard]irq.h. Note, to keep all
non-touched architectures in an untouched state this consolidation is
done carefully and strictly under CONFIG_GENERIC_HARDIRQS.
Once the consolidation is done we can do a couple of final cleanups
to reach the following logical splitup of 3 include files:
linux/interrupt.h: driver-visible APIs and details
linux/irq.h: core irq and arch-PIC code, internals
asm-*/irq.h: arch PIC and irq delivery details
the following include files will likely vanish:
linux/hardirq.h merges into linux/irq.h
asm-*/hardirq.h: merges into asm-*/irq.h
asm-*/hw_irq.h: merges into asm-*/irq.h
Christoph would like to do these once the current wave of
cleanups gets in.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/hardirq.h | 42 | ||||
| -rw-r--r-- | include/linux/interrupt.h | 9 | ||||
| -rw-r--r-- | include/linux/irq.h | 16 |
3 files changed, 66 insertions, 1 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 7e1aad3947e7..97343be12ad8 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -5,6 +5,40 @@ #include <linux/smp_lock.h> #include <asm/hardirq.h> +#ifdef CONFIG_GENERIC_HARDIRQS +/* + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x0fff0000 + */ + +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 12 + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif +#endif /* CONFIG_GENERIC_HARDIRQS */ + #define __IRQ_MASK(x) ((1UL << (x))-1) #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) @@ -43,4 +77,12 @@ extern void synchronize_irq(unsigned int irq); # define synchronize_irq(irq) barrier() #endif +#ifdef CONFIG_GENERIC_HARDIRQS +#define nmi_enter() (preempt_count() += HARDIRQ_OFFSET) +#define nmi_exit() (preempt_count() -= HARDIRQ_OFFSET) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) +extern void irq_exit(void); +#endif + #endif /* LINUX_HARDIRQ_H */ diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c7bf37959009..2b0f7331f9c3 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -40,6 +40,8 @@ struct irqaction { const char *name; void *dev_id; struct irqaction *next; + int irq; + struct proc_dir_entry *dir; }; extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs); @@ -48,6 +50,13 @@ extern int request_irq(unsigned int, unsigned long, const char *, void *); extern void free_irq(unsigned int, void *); + +#ifdef CONFIG_GENERIC_HARDIRQS +extern void disable_irq_nosync(unsigned int irq); +extern void disable_irq(unsigned int irq); +extern void enable_irq(unsigned int irq); +#endif + /* * Temporary defines for UP kernels, until all code gets fixed. */ diff --git a/include/linux/irq.h b/include/linux/irq.h index 5bc740d9bc47..012315f5665c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -13,6 +13,7 @@ #if !defined(CONFIG_ARCH_S390) +#include <linux/linkage.h> #include <linux/cache.h> #include <linux/spinlock.h> #include <linux/cpumask.h> @@ -71,7 +72,20 @@ extern irq_desc_t irq_desc [NR_IRQS]; #include <asm/hw_irq.h> /* the arch dependent stuff */ -extern int setup_irq(unsigned int , struct irqaction * ); +extern int setup_irq(unsigned int irq, struct irqaction * new); + +#ifdef CONFIG_GENERIC_HARDIRQS +extern cpumask_t irq_affinity[NR_IRQS]; + +extern asmlinkage int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, + struct irqaction *action); +extern asmlinkage unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); +extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); +extern void report_bad_irq(unsigned int irq, irq_desc_t *desc, int action_ret); +extern int can_request_irq(unsigned int irq, unsigned long irqflags); + +extern void init_irq_proc(void); +#endif extern hw_irq_controller no_irq_type; /* needed in every arch ? */ |
