aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-microdev/irq.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-07-29 08:01:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-29 08:01:19 -0400
commitda2014a2b080e7f3024a4eb6917d47069ad9620b (patch)
treecfde12c6d4b5baa222966b14a676f107992cf786 /arch/sh/boards/mach-microdev/irq.c
parent71b8064e7df5698520d73b4c1566a3dbc98eb9ef (diff)
sh: Shuffle the board directories in to mach groups.
This flattens out the board directories in to individual mach groups, we will use this for getting rid of unneeded directories, simplifying the build system, and becoming more coherent with the refactored arch/sh/include topology. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/boards/mach-microdev/irq.c')
-rw-r--r--arch/sh/boards/mach-microdev/irq.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
new file mode 100644
index 000000000000..4d335077a3ff
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -0,0 +1,183 @@
1/*
2 * arch/sh/boards/superh/microdev/irq.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 *
6 * SuperH SH4-202 MicroDev board support.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15#include <asm/system.h>
16#include <asm/io.h>
17#include <asm/microdev.h>
18
19#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
20
21static const struct {
22 unsigned char fpgaIrq;
23 unsigned char mapped;
24 const char *name;
25} fpgaIrqTable[NUM_EXTERNAL_IRQS] = {
26 { 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */
27 { MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */
28 { MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */
29 { MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */
30 { MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */
31 { 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */
32 { 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */
33 { MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */
34 { MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */
35 { MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */
36 { MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */
37 { MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */
38 { MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */
39 { MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */
40 { MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */
41 { 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */
42};
43
44#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)
45# error Inconsistancy in defining the IRQ# for Keyboard!
46#endif
47
48#if (MICRODEV_LINUX_IRQ_ETHERNET != 3)
49# error Inconsistancy in defining the IRQ# for Ethernet!
50#endif
51
52#if (MICRODEV_LINUX_IRQ_USB_HC != 7)
53# error Inconsistancy in defining the IRQ# for USB!
54#endif
55
56#if (MICRODEV_LINUX_IRQ_MOUSE != 12)
57# error Inconsistancy in defining the IRQ# for PS/2 Mouse!
58#endif
59
60#if (MICRODEV_LINUX_IRQ_IDE2 != 13)
61# error Inconsistancy in defining the IRQ# for secondary IDE!
62#endif
63
64#if (MICRODEV_LINUX_IRQ_IDE1 != 14)
65# error Inconsistancy in defining the IRQ# for primary IDE!
66#endif
67
68static void enable_microdev_irq(unsigned int irq);
69static void disable_microdev_irq(unsigned int irq);
70
71 /* shutdown is same as "disable" */
72#define shutdown_microdev_irq disable_microdev_irq
73
74static void mask_and_ack_microdev(unsigned int);
75static void end_microdev_irq(unsigned int irq);
76
77static unsigned int startup_microdev_irq(unsigned int irq)
78{
79 enable_microdev_irq(irq);
80 return 0; /* never anything pending */
81}
82
83static struct hw_interrupt_type microdev_irq_type = {
84 .typename = "MicroDev-IRQ",
85 .startup = startup_microdev_irq,
86 .shutdown = shutdown_microdev_irq,
87 .enable = enable_microdev_irq,
88 .disable = disable_microdev_irq,
89 .ack = mask_and_ack_microdev,
90 .end = end_microdev_irq
91};
92
93static void disable_microdev_irq(unsigned int irq)
94{
95 unsigned int fpgaIrq;
96
97 if (irq >= NUM_EXTERNAL_IRQS)
98 return;
99 if (!fpgaIrqTable[irq].mapped)
100 return;
101
102 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
103
104 /* disable interrupts on the FPGA INTC register */
105 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
106}
107
108static void enable_microdev_irq(unsigned int irq)
109{
110 unsigned long priorityReg, priorities, pri;
111 unsigned int fpgaIrq;
112
113 if (unlikely(irq >= NUM_EXTERNAL_IRQS))
114 return;
115 if (unlikely(!fpgaIrqTable[irq].mapped))
116 return;
117
118 pri = 15 - irq;
119
120 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
121 priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
122
123 /* set priority for the interrupt */
124 priorities = ctrl_inl(priorityReg);
125 priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
126 priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
127 ctrl_outl(priorities, priorityReg);
128
129 /* enable interrupts on the FPGA INTC register */
130 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
131}
132
133 /* This functions sets the desired irq handler to be a MicroDev type */
134static void __init make_microdev_irq(unsigned int irq)
135{
136 disable_irq_nosync(irq);
137 irq_desc[irq].chip = &microdev_irq_type;
138 disable_microdev_irq(irq);
139}
140
141static void mask_and_ack_microdev(unsigned int irq)
142{
143 disable_microdev_irq(irq);
144}
145
146static void end_microdev_irq(unsigned int irq)
147{
148 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
149 enable_microdev_irq(irq);
150}
151
152extern void __init init_microdev_irq(void)
153{
154 int i;
155
156 /* disable interrupts on the FPGA INTC register */
157 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
158
159 for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
160 make_microdev_irq(i);
161}
162
163extern void microdev_print_fpga_intc_status(void)
164{
165 volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;
166 volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;
167 volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);
168 volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);
169 volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);
170 volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);
171 volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;
172 volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;
173
174 printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");
175 printk("FPGA_INTENB = 0x%08x\n", *intenb);
176 printk("FPGA_INTDSB = 0x%08x\n", *intdsb);
177 printk("FPGA_INTSRC = 0x%08x\n", *intsrc);
178 printk("FPGA_INTREQ = 0x%08x\n", *intreq);
179 printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
180 printk("-------------------------------------------------------------------------------\n");
181}
182
183