]> git.hungrycats.org Git - linux/commitdiff
[PATCH] H8/300: Interrupt handling cleanup
authorYoshinori Sato <ysato@users.sourceforge.jp>
Sun, 14 Mar 2004 23:57:04 +0000 (15:57 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 14 Mar 2004 23:57:04 +0000 (15:57 -0800)
 - merge common routine
 - runtime vector setup update

arch/h8300/kernel/Makefile
arch/h8300/kernel/ints.c [new file with mode: 0644]
arch/h8300/platform/h8300h/Makefile
arch/h8300/platform/h8300h/ints.c [deleted file]
arch/h8300/platform/h8300h/ints_h8300h.c [new file with mode: 0644]
arch/h8300/platform/h8s/Makefile
arch/h8300/platform/h8s/ints_h8s.c [new file with mode: 0644]
include/asm-h8300/irq.h
include/asm-h8300/traps.h

index 8f0dc676787f1a765cff51ab9102eb608d8f3d97..2aae3e9c62d4dd1134208dd12b87b254adbd8c2a 100644 (file)
@@ -4,7 +4,7 @@
 
 extra-y := vmlinux.lds.s
 
-obj-y := process.o traps.o ptrace.o \
+obj-y := process.o traps.o ptrace.o ints.o \
         sys_h8300.o time.o semaphore.o signal.o \
          setup.o h8300_ksyms.o gpio.o init_task.o \
          syscalls.o
diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c
new file mode 100644 (file)
index 0000000..4a70da2
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * linux/arch/h8300/platform/h8300h/ints.c
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/bootmem.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/hardirq.h>
+#include <asm/errno.h>
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+       irqreturn_t (*handler)(int, void *, struct pt_regs *);
+       int         flags;
+       int         count;
+       void        *dev_id;
+       const char  *devname;
+} irq_handler_t;
+
+static irq_handler_t *irq_list[NR_IRQS];
+static int use_kmalloc;
+
+extern unsigned long *interrupt_redirect_table;
+extern const int h8300_saved_vectors[];
+extern const unsigned long h8300_trap_table[];
+int h8300_enable_irq_pin(unsigned int irq);
+void h8300_disable_irq_pin(unsigned int irq);
+
+#define CPU_VECTOR ((unsigned long *)0x000000)
+#define ADDR_MASK (0xffffff)
+
+#if defined(CONFIG_RAMKERNEL)
+static unsigned long __init *get_vector_address(void)
+{
+       unsigned long *rom_vector = CPU_VECTOR;
+       unsigned long base,tmp;
+       int vec_no;
+
+       base = rom_vector[EXT_IRQ0] & ADDR_MASK;
+       
+       /* check romvector format */
+       for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
+               if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
+                       return NULL;
+       }
+
+       /* ramvector base address */
+       base -= EXT_IRQ0*4;
+
+       /* writerble check */
+       tmp = ~(*(volatile unsigned long *)base);
+       (*(volatile unsigned long *)base) = tmp;
+       if ((*(volatile unsigned long *)base) != tmp)
+               return NULL;
+       return (unsigned long *)base;
+}
+#endif
+
+void __init init_IRQ(void)
+{
+#if defined(CONFIG_RAMKERNEL)
+       int i;
+       unsigned long *ramvec,*ramvec_p;
+       const unsigned long *trap_entry;
+       const int *saved_vector;
+
+       ramvec = get_vector_address();
+       if (ramvec == NULL)
+               panic("interrupt vector serup failed.");
+       else
+               printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
+
+       /* create redirect table */
+       ramvec_p = ramvec;
+       trap_entry = h8300_trap_table;
+       saved_vector = h8300_saved_vectors;
+       for ( i = 0; i < NR_IRQS; i++) {
+               if (i == *saved_vector) {
+                       ramvec_p++;
+                       saved_vector++;
+               } else {
+                       if ( i < NR_TRAPS ) {
+                               if (*trap_entry)
+                                       *ramvec_p = VECTOR(*trap_entry);
+                               ramvec_p++;
+                               trap_entry++;
+                       } else
+                               *ramvec_p++ = REDIRECT(interrupt_entry);
+               }
+       }
+       interrupt_redirect_table = ramvec;
+#ifdef DUMP_VECTOR
+       ramvec_p = ramvec;
+       for (i = 0; i < NR_IRQS; i++) {
+               if ((i % 8) == 0)
+                       printk("\n%p: ",ramvec_p);
+               printk("%p ",*ramvec_p);
+               ramvec_p++;
+       }
+       printk("\n");
+#endif
+#endif
+}
+
+int request_irq(unsigned int irq, 
+               irqreturn_t (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+       irq_handler_t *irq_handle;
+       if (irq < 0 || irq >= NR_IRQS) {
+               printk("Incorrect IRQ %d from %s\n", irq, devname);
+               return -EINVAL;
+       }
+       if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY))
+               return -EBUSY;
+
+       if (use_kmalloc)
+               irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+       else {
+               /* use bootmem allocater */
+               irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
+               irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
+       }
+
+       if (irq_handle == NULL)
+               return -ENOMEM;
+
+       irq_handle->handler = handler;
+       irq_handle->flags   = flags;
+       irq_handle->count   = 0;
+       irq_handle->dev_id  = dev_id;
+       irq_handle->devname = devname;
+       irq_list[irq] = irq_handle;
+       return 0;
+}
+
+EXPORT_SYMBOL(request_irq);
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+       if (irq >= NR_IRQS) {
+               return;
+       }
+       if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
+               printk("Removing probably wrong IRQ %d from %s\n",
+                      irq, irq_list[irq]->devname);
+       h8300_disable_irq_pin(irq);
+       if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
+               kfree(irq_list[irq]);
+               irq_list[irq] = NULL;
+       }
+}
+
+EXPORT_SYMBOL(free_irq);
+
+/*
+ * Do we need these probe functions on the m68k?
+ */
+unsigned long probe_irq_on (void)
+{
+       return 0;
+}
+
+EXPORT_SYMBOL(probe_irq_on);
+
+int probe_irq_off (unsigned long irqs)
+{
+       return 0;
+}
+
+EXPORT_SYMBOL(probe_irq_off);
+
+void enable_irq(unsigned int irq)
+{
+       if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
+               IER_REGS |= 1 << (irq - EXT_IRQ0);
+}
+
+void disable_irq(unsigned int irq)
+{
+       if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
+               IER_REGS &= ~(1 << (irq - EXT_IRQ0));
+}
+
+asmlinkage void process_int(int irq, struct pt_regs *fp)
+{
+       irq_enter();
+       h8300_clear_isr(irq);
+       if (irq >= NR_TRAPS && irq < NR_IRQS) {
+               if (irq_list[irq]) {
+                       irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp);
+                       irq_list[irq]->count++;
+                       if (irq_list[irq]->flags & SA_SAMPLE_RANDOM)
+                               add_interrupt_randomness(irq);
+               }
+       } else {
+               BUG();
+       }
+       irq_exit();
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+       int i = *(loff_t *) v;
+
+       if ((i < NR_IRQS) && (irq_list[i]!=NULL)) {
+               seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
+               seq_printf(p, "%s\n", irq_list[i]->devname);
+       }
+
+       return 0;
+}
+
+void init_irq_proc(void)
+{
+}
+
+static int __init enable_kmalloc(void)
+{
+       use_kmalloc = 1;
+       return 0;
+}
+core_initcall(enable_kmalloc);
index dbedcf7801aaac5ee98fda5d8986bf5ce34d0739..9a920fe01921d76177d0246802db7ff8c110aa82 100644 (file)
@@ -4,15 +4,5 @@
 # Reuse any files we can from the H8/300H
 #
 
-#VPATH := $(VPATH):$(BOARD)
+obj-y := entry.o ints_h8300h.o
 
-.S.o:
-       $(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
-
-obj-y := entry.o ints.o
-
-$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
-
-entry.o: entry.S
-
-ints.o: ints.c
diff --git a/arch/h8300/platform/h8300h/ints.c b/arch/h8300/platform/h8300h/ints.c
deleted file mode 100644 (file)
index 7340c06..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/ints.c
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- *
- * Copyright 1996 Roman Zippel
- * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/random.h>
-#include <linux/bootmem.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/traps.h>
-#include <asm/io.h>
-#include <asm/setup.h>
-#include <asm/gpio.h>
-#include <asm/hardirq.h>
-#include <asm/regs306x.h>
-#include <asm/errno.h>
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-typedef struct irq_handler {
-       irqreturn_t (*handler)(int, void *, struct pt_regs *);
-       int         flags;
-       int         count;
-       void        *dev_id;
-       const char  *devname;
-} irq_handler_t;
-
-static irq_handler_t *irq_list[NR_IRQS];
-static int use_kmalloc;
-
-extern unsigned long *interrupt_redirect_table;
-
-#define CPU_VECTOR ((unsigned long *)0x000000)
-#define ADDR_MASK (0xffffff)
-
-static inline unsigned long *get_vector_address(void)
-{
-       unsigned long *rom_vector = CPU_VECTOR;
-       unsigned long base,tmp;
-       int vec_no;
-
-       base = rom_vector[EXT_IRQ0] & ADDR_MASK;
-       
-       /* check romvector format */
-       for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ5; vec_no++) {
-               if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
-                       return NULL;
-       }
-
-       /* ramvector base address */
-       base -= EXT_IRQ0*4;
-
-       /* writerble check */
-       tmp = ~(*(volatile unsigned long *)base);
-       (*(volatile unsigned long *)base) = tmp;
-       if ((*(volatile unsigned long *)base) != tmp)
-               return NULL;
-       return (unsigned long *)base;
-}
-
-void __init init_IRQ(void)
-{
-#if defined(CONFIG_RAMKERNEL)
-       int i;
-       unsigned long *ramvec,*ramvec_p;
-       unsigned long break_vec;
-
-#if defined(CONFIG_GDB_DEBUG)
-       break_vec = ramvec[TRAP3_VEC];
-#else
-       break_vec = VECTOR(trace_break);
-#endif
-
-       ramvec = get_vector_address();
-       if (ramvec == NULL)
-               panic("interrupt vector serup failed.");
-       else
-               printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
-
-       for (ramvec_p = ramvec, i = 0; i < NR_IRQS; i++)
-               *ramvec_p++ = REDIRECT(interrupt_entry);
-
-       ramvec[TRAP0_VEC] = VECTOR(system_call);
-       ramvec[TRAP3_VEC] = break_vec;
-       interrupt_redirect_table = ramvec;
-#ifdef DUMP_VECTOR
-       ramvec_p = interrupt_redirect_table;
-       for (i = 0; i < NR_IRQS; i++) {
-               if ((i % 8) == 0)
-                       printk("\n%p: ",ramvec_p);
-               printk("%p ",*ramvec_p);
-               ramvec_p++;
-       }
-       printk("\n");
-#endif
-#endif
-}
-
-int request_irq(unsigned int irq, 
-               irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                unsigned long flags, const char *devname, void *dev_id)
-{
-       irq_handler_t *irq_handle;
-       if (irq < 0 || irq >= NR_IRQS) {
-               printk("Incorrect IRQ %d from %s\n", irq, devname);
-               return -EINVAL;
-       }
-       if (irq_list[irq])
-               return -EBUSY;
-       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ3) {
-               if (H8300_GPIO_RESERVE(H8300_GPIO_P8, 1 << (irq - EXT_IRQ0)) == 0)
-                       return -EBUSY;
-               H8300_GPIO_DDR(H8300_GPIO_P8, (irq - EXT_IRQ0), 0);
-       }
-       if (irq >= EXT_IRQ4 && irq <= EXT_IRQ5) {
-               if (H8300_GPIO_RESERVE(H8300_GPIO_P9, 1 << (irq - EXT_IRQ0)) == 0)
-                       return -EBUSY;
-               H8300_GPIO_DDR(H8300_GPIO_P9, (irq - EXT_IRQ0), 0);
-       }
-
-       if (use_kmalloc)
-               irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
-       else {
-               /* use bootmem allocater */
-               irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
-               irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
-       }
-
-       if (irq_handle == NULL)
-               return -ENOMEM;
-
-       irq_handle->handler = handler;
-       irq_handle->flags   = flags;
-       irq_handle->count   = 0;
-       irq_handle->dev_id  = dev_id;
-       irq_handle->devname = devname;
-       irq_list[irq] = irq_handle;
-       return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-       if (irq >= NR_IRQS) {
-               return;
-       }
-       if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
-               printk("Removing probably wrong IRQ %d from %s\n",
-                      irq, irq_list[irq]->devname);
-       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)
-               *(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0));
-       if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
-               kfree(irq_list[irq]);
-               irq_list[irq] = NULL;
-       }
-}
-
-EXPORT_SYMBOL(free_irq);
-
-/*
- * Do we need these probe functions on the m68k?
- */
-unsigned long probe_irq_on (void)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-int probe_irq_off (unsigned long irqs)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-void enable_irq(unsigned int irq)
-{
-       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) {
-               *(volatile unsigned char *)IER |= (1 << (irq - EXT_IRQ0));
-               *(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0));
-       }
-}
-
-void disable_irq(unsigned int irq)
-{
-       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) {
-               *(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0));
-       }
-}
-
-asmlinkage void process_int(int vec, struct pt_regs *fp)
-{
-       irq_enter();
-       if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5)
-               *(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0));
-       if (vec < NR_IRQS) {
-               if (irq_list[vec]) {
-                       irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp);
-                       irq_list[vec]->count++;
-                       if (irq_list[vec]->flags & SA_SAMPLE_RANDOM)
-                               add_interrupt_randomness(vec);
-               }
-       } else {
-               BUG();
-       }
-       irq_exit();
-}
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v;
-
-       if ((i < NR_IRQS) && (irq_list[i]!=NULL)) {
-               seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
-               seq_printf(p, "%s\n", irq_list[i]->devname);
-       }
-
-       return 0;
-}
-
-void init_irq_proc(void)
-{
-}
-
-static int __init enable_kmalloc(void)
-{
-       use_kmalloc = 1;
-       return 0;
-}
-core_initcall(enable_kmalloc);
diff --git a/arch/h8300/platform/h8300h/ints_h8300h.c b/arch/h8300/platform/h8300h/ints_h8300h.c
new file mode 100644 (file)
index 0000000..86a1554
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/h8300/platform/h8300h/ints_h8300h.c
+ * Interrupt handling CPU variants
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/traps.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/regs306x.h>
+
+/* saved vector list */
+const int __initdata h8300_saved_vectors[]={
+#if defined(CONFIG_GDB_DEBUG)
+       TRAP3_VEC,
+#endif
+       -1
+};
+
+/* trap entry table */
+const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
+       0,0,0,0,0,0,0,0,
+       (unsigned long)system_call,  /* TRAPA #0 */
+       0,0,
+       (unsigned long)trace_break,  /* TRAPA #3 */
+};
+
+int h8300_enable_irq_pin(unsigned int irq)
+{
+       int bitmask;
+       if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+               return 0;
+
+       /* initialize IRQ pin */
+       bitmask = 1 << (irq - EXT_IRQ0);
+       switch(irq) {
+       case EXT_IRQ0:
+       case EXT_IRQ1:
+       case EXT_IRQ2:
+       case EXT_IRQ3:
+               if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
+                       return -EBUSY;
+               H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
+               break;
+       case EXT_IRQ4:
+       case EXT_IRQ5:
+               if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
+                       return -EBUSY;
+               H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
+               break;
+       }
+
+       return 0;
+}
+
+void h8300_disable_irq_pin(unsigned int irq)
+{
+       int bitmask;
+       if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+               return;
+
+       /* disable interrupt & release IRQ pin */
+       bitmask = 1 << (irq - EXT_IRQ0);
+       switch(irq) {
+       case EXT_IRQ0:
+       case EXT_IRQ1:
+       case EXT_IRQ2:
+       case EXT_IRQ3:
+               *(volatile unsigned char *)IER &= ~bitmask;
+               H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
+               break ;
+       case EXT_IRQ4:
+       case EXT_IRQ5:
+               *(volatile unsigned char *)IER &= ~bitmask;
+               H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
+               break;
+       }
+}
index 448549788a61c102bea30183a7128d918ea1d4c9..7cf522c11de593811f52311a4f4c2254a7b0d190 100644 (file)
@@ -4,15 +4,4 @@
 # Reuse any files we can from the H8S
 #
 
-#VPATH := $(VPATH):$(BOARD)
-
-.S.o:
-       $(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
-
-obj-y := entry.o ints.o
-
-$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
-
-entry.o: entry.S
-
-ints.o: ints.c
+obj-y := entry.o ints_h8s.o
diff --git a/arch/h8300/platform/h8s/ints_h8s.c b/arch/h8300/platform/h8s/ints_h8s.c
new file mode 100644 (file)
index 0000000..dd4398e
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/h8300/platform/h8s/ints_h8s.c
+ * Interrupt handling CPU variants
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/traps.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/regs267x.h>
+
+/* saved vector list */
+const int __initdata h8300_saved_vectors[]={
+#if defined(CONFIG_GDB_DEBUG)
+       TRACE_VEC,
+       TRAP3_VEC,
+#endif
+       -1
+};
+
+/* trap entry table */
+const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
+       0,0,0,0,0,
+       (unsigned long)trace_break,  /* TRACE */
+       0,0,
+       (unsigned long)system_call,  /* TRAPA #0 */
+       0,0,0,0,0,0,0
+};
+
+/* IRQ pin assignment */
+struct irq_pins {
+       unsigned char port_no;
+       unsigned char bit_no;
+} __attribute__((aligned(1),packed));
+/* ISTR = 0 */
+const static struct irq_pins irq_assign_table0[16]={
+        {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
+       {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
+       {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
+       {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
+       {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
+       {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
+       {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
+       {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
+}; 
+/* ISTR = 1 */
+const static struct irq_pins irq_assign_table1[16]={
+       {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
+       {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
+       {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
+       {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
+       {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
+       {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
+       {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
+       {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
+};
+
+#define IRQ_GPIO_MAP(irqbit,port,bit)                            \
+do {                                                             \
+       if (*(volatile unsigned short *)ITSR & irqbit) {          \
+               port = irq_assign_table1[irq - EXT_IRQ0].port_no; \
+               bit  = irq_assign_table1[irq - EXT_IRQ0].bit_no;  \
+       } else {                                                  \
+               port = irq_assign_table0[irq - EXT_IRQ0].port_no; \
+               bit  = irq_assign_table0[irq - EXT_IRQ0].bit_no;  \
+       }                                                         \
+} while(0)
+
+int h8300_enable_irq_pin(unsigned int irq)
+{
+       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
+               unsigned short ptn = 1 << (irq - EXT_IRQ0);
+               unsigned int port_no,bit_no;
+               IRQ_GPIO_MAP(ptn,port_no,bit_no);
+               if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
+                       return -EBUSY;                   /* pin already use */
+               H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
+               *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
+       }               
+       return 0;
+}
+
+void h8300_disable_irq_pin(unsigned int irq)
+{
+       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
+               /* disable interrupt & release IRQ pin */
+               unsigned short ptn = 1 << (irq - EXT_IRQ0);
+               unsigned short port_no,bit_no;
+               *(volatile unsigned short *)ISR &= ~ptn;
+               *(volatile unsigned short *)IER &= ~ptn;
+               IRQ_GPIO_MAP(ptn,port_no,bit_no);
+               H8300_GPIO_FREE(port_no, bit_no);
+       }
+}
index b50d0a8a14a1caba45ded174fdbffac05bc10491..fabde1dd34a1f7dfc0b0261e3d722a3fb7493925 100644 (file)
 #define EXT_IRQ5 17
 #define EXT_IRQ6 18
 #define EXT_IRQ7 19
+#define EXT_IRQS 5
+
+#include <asm/regs306x.h>
+#define h8300_clear_isr(irq)                                                \
+do {                                                                        \
+       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)                             \
+               *(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
+} while(0)
+
+#define IER_REGS *(volatile unsigned char *)IER
 #endif
 #if defined(CONFIG_CPU_H8S)
 #define NR_IRQS 128
 #define EXT_IRQ13 29
 #define EXT_IRQ14 30
 #define EXT_IRQ15 31
+#define EXT_IRQS 15
+
+#include <asm/regs267x.h>
+#define h8300_clear_isr(irq)                                                 \
+do {                                                                         \
+       if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)                             \
+               *(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
+} while(0)
+
+#define IER_REGS *(volatile unsigned short *)IER
 #endif
 
 static __inline__ int irq_canonicalize(int irq)
index a721c6eacf2ec6d87022efc4546c792622e65406..41cf6be02f681f7b264901ea0bc2f53e770e9b07 100644 (file)
@@ -20,9 +20,18 @@ extern void trace_break(void);
 #define VECTOR(address) ((JMP_OP)|((unsigned long)address))
 #define REDIRECT(address) ((JSR_OP)|((unsigned long)address))
 
+#define TRACE_VEC 5
+
 #define TRAP0_VEC 8
 #define TRAP1_VEC 9
 #define TRAP2_VEC 10
 #define TRAP3_VEC 11
 
+#if defined(__H8300H__)
+#define NR_TRAPS 12
+#endif
+#if defined(__H8300S__)
+#define NR_TRAPS 16
+#endif
+
 #endif /* _H8300_TRAPS_H */