1/* 2 * linux/arch/h8300/platform/h8s/ints_h8s.c 3 * Interrupt handling CPU variants 4 * 5 * Yoshinori Sato <ysato@users.sourceforge.jp> 6 * 7 */ 8 9#include <linux/init.h> 10#include <linux/errno.h> 11#include <linux/kernel.h> 12 13#include <asm/ptrace.h> 14#include <asm/traps.h> 15#include <asm/irq.h> 16#include <asm/io.h> 17#include <asm/gpio.h> 18#include <asm/regs267x.h> 19 20/* saved vector list */ 21const int __initdata h8300_saved_vectors[]={ 22#if defined(CONFIG_GDB_DEBUG) 23 TRACE_VEC, 24 TRAP3_VEC, 25#endif 26 -1 27}; 28 29/* trap entry table */ 30const H8300_VECTOR __initdata h8300_trap_table[] = { 31 0,0,0,0,0, 32 trace_break, /* TRACE */ 33 0,0, 34 system_call, /* TRAPA #0 */ 35 0,0,0,0,0,0,0 36}; 37 38/* IRQ pin assignment */ 39struct irq_pins { 40 unsigned char port_no; 41 unsigned char bit_no; 42} __attribute__((aligned(1),packed)); 43/* ISTR = 0 */ 44static const struct irq_pins irq_assign_table0[16]={ 45 {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1}, 46 {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3}, 47 {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5}, 48 {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7}, 49 {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1}, 50 {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3}, 51 {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5}, 52 {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2}, 53}; 54/* ISTR = 1 */ 55static const struct irq_pins irq_assign_table1[16]={ 56 {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1}, 57 {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3}, 58 {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5}, 59 {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3}, 60 {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1}, 61 {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3}, 62 {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5}, 63 {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7}, 64}; 65 66/* IRQ to GPIO pin translation */ 67#define IRQ_GPIO_MAP(irqbit,irq,port,bit) \ 68do { \ 69 if (*(volatile unsigned short *)ITSR & irqbit) { \ 70 port = irq_assign_table1[irq - EXT_IRQ0].port_no; \ 71 bit = irq_assign_table1[irq - EXT_IRQ0].bit_no; \ 72 } else { \ 73 port = irq_assign_table0[irq - EXT_IRQ0].port_no; \ 74 bit = irq_assign_table0[irq - EXT_IRQ0].bit_no; \ 75 } \ 76} while(0) 77 78int h8300_enable_irq_pin(unsigned int irq) 79{ 80 if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { 81 unsigned short ptn = 1 << (irq - EXT_IRQ0); 82 unsigned int port_no,bit_no; 83 IRQ_GPIO_MAP(ptn, irq, port_no, bit_no); 84 if (H8300_GPIO_RESERVE(port_no, bit_no) == 0) 85 return -EBUSY; /* pin already use */ 86 H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT); 87 *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */ 88 } 89 90 return 0; 91} 92 93void h8300_disable_irq_pin(unsigned int irq) 94{ 95 if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { 96 /* disable interrupt & release IRQ pin */ 97 unsigned short ptn = 1 << (irq - EXT_IRQ0); 98 unsigned short port_no,bit_no; 99 *(volatile unsigned short *)ISR &= ~ptn; 100 *(volatile unsigned short *)IER &= ~ptn; 101 IRQ_GPIO_MAP(ptn, irq, port_no, bit_no); 102 H8300_GPIO_FREE(port_no, bit_no); 103 } 104} 105