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