linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] H8/300 support update (1/4) - Interrupt handling cleanup
@ 2004-03-14 16:28 Yoshinori Sato
  2004-03-15 15:00 ` Yoshinori Sato
  0 siblings, 1 reply; 2+ messages in thread
From: Yoshinori Sato @ 2004-03-14 16:28 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux kernel Mailing List

- merge common routine
- runtime vector setup update

-- 
Yoshinori Sato
<ysato@users.sourceforge.jp>

diff -Nru -X .exclude-diff linux-2.6.4/arch/h8300/kernel/Makefile linux-2.6.4-h8300/arch/h8300/kernel/Makefile
--- linux-2.6.4/arch/h8300/kernel/Makefile	2004-01-09 15:59:44.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/kernel/Makefile	2004-03-03 21:11:04.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/kernel/ints.c linux-2.6.4-h8300/arch/h8300/kernel/ints.c
--- linux-2.6.4/arch/h8300/kernel/ints.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/kernel/ints.c	2004-03-15 01:20:29.000000000 +0900
@@ -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);
--- linux-2.6.4/arch/h8300/platform/h8300h/Makefile	2004-03-14 18:17:37.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/Makefile	2004-03-15 00:26:38.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8300h/ints.c linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints.c
--- linux-2.6.4/arch/h8300/platform/h8300h/ints.c	2004-02-20 01:08:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints.c	1970-01-01 09:00:00.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8300h/ints_h8300h.c linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints_h8300h.c
--- linux-2.6.4/arch/h8300/platform/h8300h/ints_h8300h.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints_h8300h.c	2004-03-03 21:11:04.000000000 +0900
@@ -0,1 +1,87 @@
+/*
+ * 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;
+	}
+}
diff -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8s/Makefile linux-2.6.4-h8300/arch/h8300/platform/h8s/Makefile
--- linux-2.6.4/arch/h8300/platform/h8s/Makefile	2004-03-14 18:17:37.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8s/Makefile	2004-03-15 00:26:46.000000000 +0900
@@ -4,16 +4,5 @@
 # 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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8s/ints_h8s.c linux-2.6.4-h8300/arch/h8300/platform/h8s/ints_h8s.c
--- linux-2.6.4/arch/h8300/platform/h8s/ints_h8s.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8s/ints_h8s.c	2004-03-15 00:47:59.000000000 +0900
@@ -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);
+	}
+}
diff -Nru -X .exclude-diff linux-2.6.4/include/asm-h8300/irq.h linux-2.6.4-h8300/include/asm-h8300/irq.h
--- linux-2.6.4/include/asm-h8300/irq.h	2004-01-09 15:59:10.000000000 +0900
+++ linux-2.6.4-h8300/include/asm-h8300/irq.h	2004-03-03 21:13:21.000000000 +0900
@@ -13,6 +13,16 @@
 #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
@@ -32,6 +42,16 @@
 #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)
diff -Nru -X .exclude-diff linux-2.6.4/include/asm-h8300/traps.h linux-2.6.4-h8300/include/asm-h8300/traps.h
--- linux-2.6.4/include/asm-h8300/traps.h	2004-01-09 16:00:05.000000000 +0900
+++ linux-2.6.4-h8300/include/asm-h8300/traps.h	2004-03-03 21:13:21.000000000 +0900
@@ -20,9 +20,18 @@
 #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 */

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] H8/300 support update (1/4) - Interrupt handling cleanup
  2004-03-14 16:28 [PATCH] H8/300 support update (1/4) - Interrupt handling cleanup Yoshinori Sato
@ 2004-03-15 15:00 ` Yoshinori Sato
  0 siblings, 0 replies; 2+ messages in thread
From: Yoshinori Sato @ 2004-03-15 15:00 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux kernel Mailing List

At Mon, 15 Mar 2004 01:28:00 +0900,
Yoshinori Sato wrote:
> 
> - merge common routine
> - runtime vector setup update
> 

I'm sorry.
Because a patch was broken, resend.

-- 
Yoshinori Sato
<ysato@user.sourceforge.jp>

diff -Nru -X .exclude-diff linux-2.6.4/arch/h8300/kernel/Makefile linux-2.6.4-h8300/arch/h8300/kernel/Makefile
--- linux-2.6.4/arch/h8300/kernel/Makefile	2004-01-09 15:59:44.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/kernel/Makefile	2004-03-03 21:11:04.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/kernel/ints.c linux-2.6.4-h8300/arch/h8300/kernel/ints.c
--- linux-2.6.4/arch/h8300/kernel/ints.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/kernel/ints.c	2004-03-15 01:20:29.000000000 +0900
@@ -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);
diff -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8300h/Makefile linux-2.6.4-h8300/arch/h8300/platform/h8300h/Makefile
--- linux-2.6.4/arch/h8300/platform/h8300h/Makefile	2004-03-15 23:46:37.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/Makefile	2004-03-15 00:17:44.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8300h/ints.c linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints.c
--- linux-2.6.4/arch/h8300/platform/h8300h/ints.c	2004-03-15 23:45:06.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints.c	1970-01-01 09:00:00.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8300h/ints_h8300h.c linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints_h8300h.c
--- linux-2.6.4/arch/h8300/platform/h8300h/ints_h8300h.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8300h/ints_h8300h.c	2004-03-03 21:11:04.000000000 +0900
@@ -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;
+	}
+}
diff -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8s/Makefile linux-2.6.4-h8300/arch/h8300/platform/h8s/Makefile
--- linux-2.6.4/arch/h8300/platform/h8s/Makefile	2004-03-15 23:46:37.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8s/Makefile	2004-03-15 00:17:44.000000000 +0900
@@ -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 -Nru -X .exclude-diff linux-2.6.4/arch/h8300/platform/h8s/ints_h8s.c linux-2.6.4-h8300/arch/h8300/platform/h8s/ints_h8s.c
--- linux-2.6.4/arch/h8300/platform/h8s/ints_h8s.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4-h8300/arch/h8300/platform/h8s/ints_h8s.c	2004-03-15 00:47:59.000000000 +0900
@@ -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);
+	}
+}
diff -Nru -X .exclude-diff linux-2.6.4/include/asm-h8300/irq.h linux-2.6.4-h8300/include/asm-h8300/irq.h
--- linux-2.6.4/include/asm-h8300/irq.h	2004-01-09 15:59:10.000000000 +0900
+++ linux-2.6.4-h8300/include/asm-h8300/irq.h	2004-03-03 21:13:21.000000000 +0900
@@ -13,6 +13,16 @@
 #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
@@ -32,6 +42,16 @@
 #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)
diff -Nru -X .exclude-diff linux-2.6.4/include/asm-h8300/traps.h linux-2.6.4-h8300/include/asm-h8300/traps.h
--- linux-2.6.4/include/asm-h8300/traps.h	2004-01-09 16:00:05.000000000 +0900
+++ linux-2.6.4-h8300/include/asm-h8300/traps.h	2004-03-03 21:13:21.000000000 +0900
@@ -20,9 +20,18 @@
 #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 */

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-15 15:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-14 16:28 [PATCH] H8/300 support update (1/4) - Interrupt handling cleanup Yoshinori Sato
2004-03-15 15:00 ` Yoshinori Sato

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).