From c6387a48cf5958e43c201fc27a158c328927531a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Jun 2006 01:21:29 -0700 Subject: [SPARC]: Kill __irq_itoa(). This ugly hack was long overdue to die. It was a way to print out Sparc interrupts in a more freindly format, since IRQ numbers were arbitrary opaque 32-bit integers which vectored into PIL levels. These 32-bit integers were not necessarily in the 0-->NR_IRQS range, but the PILs they vectored to were. The idea now is that we will increase NR_IRQS a little bit and use a virtual<-->real IRQ number mapping scheme similar to PowerPC. That makes this IRQ printing hack irrelevant, and furthermore only a handful of drivers actually used __irq_itoa() making it even less useful. Signed-off-by: David S. Miller --- include/asm-sparc64/irq.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/asm-sparc64/irq.h') diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index de33d6e1afb..bbdf89e6faa 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -99,14 +99,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) -static __inline__ char *__irq_itoa(unsigned int irq) -{ - static char buff[16]; - - sprintf(buff, "%d,%x", __irq_pil(irq), (unsigned int)__irq_ino(irq)); - return buff; -} - #define NR_IRQS 16 #define irq_canonicalize(irq) (irq) -- cgit v1.2.3 From 37cdcd9e82108f9b899f1631f66ade2e45738a6e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Jun 2006 01:21:57 -0700 Subject: [SPARC64]: Kill ino_bucket->pil And reuse that struct member for virt_irq, which will be used in future changesets for the implementation of mapping between real and virtual IRQ numbers. This nicely kills off a ton of SBUS and PCI controller PIL assignment code which is no longer necessary. Signed-off-by: David S. Miller --- include/asm-sparc64/irq.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/asm-sparc64/irq.h') diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index bbdf89e6faa..d66c7cd820c 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -37,14 +37,14 @@ struct irq_desc { * line. Keep this in mind please. */ struct ino_bucket { - /* Next handler in per-CPU PIL worklist. We know that + /* Next handler in per-CPU IRQ worklist. We know that * bucket pointers have the high 32-bits clear, so to * save space we only store the bits we need. */ /*0x00*/unsigned int irq_chain; - /* PIL to schedule this IVEC at. */ -/*0x04*/unsigned char pil; + /* Virtual interrupt number assigned to this INO. */ +/*0x04*/unsigned char virt_irq; /* If an IVEC arrives while irq_info is NULL, we * set this to notify request_irq() about the event. @@ -95,7 +95,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; #define __irq_ino(irq) \ (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) -#define __irq_pil(irq) ((struct ino_bucket *)(unsigned long)(irq))->pil #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) @@ -105,8 +104,8 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; extern void disable_irq(unsigned int); #define disable_irq_nosync disable_irq extern void enable_irq(unsigned int); -extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); -extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags); +extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); +extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); static __inline__ void set_softint(unsigned long bits) -- cgit v1.2.3 From 8047e247c899f80c33a23ad7e9e250224f0d26a5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Jun 2006 01:22:35 -0700 Subject: [SPARC64]: Virtualize IRQ numbers. Inspired by PowerPC XICS interrupt support code. All IRQs are virtualized in order to keep NR_IRQS from needing to be too large. Interrupts on sparc64 are arbitrary 11-bit values, but we don't need to define NR_IRQS to 2048 if we virtualize the IRQs. As PCI and SBUS controller drivers build device IRQs, we divy out virtual IRQ numbers incrementally starting at 1. Zero is a special virtual IRQ used for the timer interrupt. So device drivers all see virtual IRQs, and all the normal interfaces such as request_irq(), enable_irq(), etc. translate that into a real IRQ number in order to configure the IRQ. At this point knowledge of the struct ino_bucket is almost entirely contained within arch/sparc64/kernel/irq.c There are a few small bits in the PCI controller drivers that need to be swept away before we can remove ino_bucket's definition out of asm-sparc64/irq.h and privately into kernel/irq.c Signed-off-by: David S. Miller --- include/asm-sparc64/irq.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'include/asm-sparc64/irq.h') diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index d66c7cd820c..9edcd90495f 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -98,13 +98,22 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) -#define NR_IRQS 16 +/* The largest number of unique interrupt sources we support. + * If this needs to ever be larger than 255, you need to change + * the type of ino_bucket->virt_irq as appropriate. + * + * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq(). + */ +#define NR_IRQS 255 +extern void irq_install_pre_handler(int virt_irq, + void (*func)(struct ino_bucket *, void *, void *), + void *arg1, void *arg2); #define irq_canonicalize(irq) (irq) extern void disable_irq(unsigned int); #define disable_irq_nosync disable_irq extern void enable_irq(unsigned int); -extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); +extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap, unsigned char flags); extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); -- cgit v1.2.3 From e18e2a00efc8352c131eb8d5a460149fb5776f1c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Jun 2006 01:23:32 -0700 Subject: [SPARC64]: Move over to GENERIC_HARDIRQS. This is the long overdue conversion of sparc64 over to the generic IRQ layer. The kernel image is slightly larger, but the BSS is ~60K smaller due to the reduced size of struct ino_bucket. A lot of IRQ implementation details, including ino_bucket, were moved out of asm-sparc64/irq.h and are now private to arch/sparc64/kernel/irq.c, and most of the code in irq.c totally disappeared. One thing that's different at the moment is IRQ distribution, we do it at enable_irq() time. If the cpu mask is ALL then we round-robin using a global rotating cpu counter, else we pick the first cpu in the mask to support single cpu targetting. This is similar to what powerpc's XICS IRQ support code does. This works fine on my UP SB1000, and the SMP build goes fine and runs on that machine, but lots of testing on different setups is needed. Signed-off-by: David S. Miller --- include/asm-sparc64/irq.h | 78 ++--------------------------------------------- 1 file changed, 3 insertions(+), 75 deletions(-) (limited to 'include/asm-sparc64/irq.h') diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 9edcd90495f..77a4f63cba7 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -16,58 +16,6 @@ #include #include -struct ino_bucket; - -#define MAX_IRQ_DESC_ACTION 4 - -struct irq_desc { - void (*pre_handler)(struct ino_bucket *, void *, void *); - void *pre_handler_arg1; - void *pre_handler_arg2; - u32 action_active_mask; - struct irqaction action[MAX_IRQ_DESC_ACTION]; -}; - -/* You should not mess with this directly. That's the job of irq.c. - * - * If you make changes here, please update hand coded assembler of - * the vectored interrupt trap handler in entry.S -DaveM - * - * This is currently one DCACHE line, two buckets per L2 cache - * line. Keep this in mind please. - */ -struct ino_bucket { - /* Next handler in per-CPU IRQ worklist. We know that - * bucket pointers have the high 32-bits clear, so to - * save space we only store the bits we need. - */ -/*0x00*/unsigned int irq_chain; - - /* Virtual interrupt number assigned to this INO. */ -/*0x04*/unsigned char virt_irq; - - /* If an IVEC arrives while irq_info is NULL, we - * set this to notify request_irq() about the event. - */ -/*0x05*/unsigned char pending; - - /* Miscellaneous flags. */ -/*0x06*/unsigned char flags; - - /* Currently unused. */ -/*0x07*/unsigned char __pad; - - /* Reference to IRQ descriptor for this bucket. */ -/*0x08*/struct irq_desc *irq_info; - - /* Sun5 Interrupt Clear Register. */ -/*0x10*/unsigned long iclr; - - /* Sun5 Interrupt Mapping Register. */ -/*0x18*/unsigned long imap; - -}; - /* IMAP/ICLR register defines */ #define IMAP_VALID 0x80000000 /* IRQ Enabled */ #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ @@ -85,19 +33,6 @@ struct ino_bucket { #define ICLR_TRANSMIT 0x00000001 /* Transmit state */ #define ICLR_PENDING 0x00000003 /* Pending state */ -/* Only 8-bits are available, be careful. -DaveM */ -#define IBF_PCI 0x02 /* PSYCHO/SABRE/SCHIZO PCI interrupt. */ -#define IBF_ACTIVE 0x04 /* Interrupt is active and has a handler.*/ -#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ - -#define NUM_IVECS (IMAP_INR + 1) -extern struct ino_bucket ivector_table[NUM_IVECS]; - -#define __irq_ino(irq) \ - (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) -#define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) -#define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) - /* The largest number of unique interrupt sources we support. * If this needs to ever be larger than 255, you need to change * the type of ino_bucket->virt_irq as appropriate. @@ -107,14 +42,11 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; #define NR_IRQS 255 extern void irq_install_pre_handler(int virt_irq, - void (*func)(struct ino_bucket *, void *, void *), + void (*func)(unsigned int, void *, void *), void *arg1, void *arg2); #define irq_canonicalize(irq) (irq) -extern void disable_irq(unsigned int); -#define disable_irq_nosync disable_irq -extern void enable_irq(unsigned int); -extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap, unsigned char flags); -extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags); +extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); +extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); static __inline__ void set_softint(unsigned long bits) @@ -140,8 +72,4 @@ static __inline__ unsigned long get_softint(void) return retval; } -struct irqaction; -struct pt_regs; -int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); - #endif -- cgit v1.2.3