aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/harp/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/harp/irq.c')
-rw-r--r--arch/sh/boards/harp/irq.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c
new file mode 100644
index 000000000000..acd58489970f
--- /dev/null
+++ b/arch/sh/boards/harp/irq.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Looks after interrupts on the HARP board.
8 *
9 * Bases on the IPR irq system
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/system.h>
17#include <asm/io.h>
18#include <asm/harp/harp.h>
19
20
21#define NUM_EXTERNAL_IRQS 16
22
23// Early versions of the STB1 Overdrive required this nasty frig
24//#define INVERT_INTMASK_WRITES
25
26static void enable_harp_irq(unsigned int irq);
27static void disable_harp_irq(unsigned int irq);
28
29/* shutdown is same as "disable" */
30#define shutdown_harp_irq disable_harp_irq
31
32static void mask_and_ack_harp(unsigned int);
33static void end_harp_irq(unsigned int irq);
34
35static unsigned int startup_harp_irq(unsigned int irq)
36{
37 enable_harp_irq(irq);
38 return 0; /* never anything pending */
39}
40
41static struct hw_interrupt_type harp_irq_type = {
42 "Harp-IRQ",
43 startup_harp_irq,
44 shutdown_harp_irq,
45 enable_harp_irq,
46 disable_harp_irq,
47 mask_and_ack_harp,
48 end_harp_irq
49};
50
51static void disable_harp_irq(unsigned int irq)
52{
53 unsigned val, flags;
54 unsigned maskReg;
55 unsigned mask;
56 int pri;
57
58 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
59 return;
60
61 pri = 15 - irq;
62
63 if (pri < 8) {
64 maskReg = EPLD_INTMASK0;
65 } else {
66 maskReg = EPLD_INTMASK1;
67 pri -= 8;
68 }
69
70 local_irq_save(flags);
71 mask = ctrl_inl(maskReg);
72 mask &= (~(1 << pri));
73#if defined(INVERT_INTMASK_WRITES)
74 mask ^= 0xff;
75#endif
76 ctrl_outl(mask, maskReg);
77 local_irq_restore(flags);
78}
79
80static void enable_harp_irq(unsigned int irq)
81{
82 unsigned flags;
83 unsigned maskReg;
84 unsigned mask;
85 int pri;
86
87 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
88 return;
89
90 pri = 15 - irq;
91
92 if (pri < 8) {
93 maskReg = EPLD_INTMASK0;
94 } else {
95 maskReg = EPLD_INTMASK1;
96 pri -= 8;
97 }
98
99 local_irq_save(flags);
100 mask = ctrl_inl(maskReg);
101
102
103 mask |= (1 << pri);
104
105#if defined(INVERT_INTMASK_WRITES)
106 mask ^= 0xff;
107#endif
108 ctrl_outl(mask, maskReg);
109
110 local_irq_restore(flags);
111}
112
113/* This functions sets the desired irq handler to be an overdrive type */
114static void __init make_harp_irq(unsigned int irq)
115{
116 disable_irq_nosync(irq);
117 irq_desc[irq].handler = &harp_irq_type;
118 disable_harp_irq(irq);
119}
120
121static void mask_and_ack_harp(unsigned int irq)
122{
123 disable_harp_irq(irq);
124}
125
126static void end_harp_irq(unsigned int irq)
127{
128 enable_harp_irq(irq);
129}
130
131void __init init_harp_irq(void)
132{
133 int i;
134
135#if !defined(INVERT_INTMASK_WRITES)
136 // On the harp these are set to enable an interrupt
137 ctrl_outl(0x00, EPLD_INTMASK0);
138 ctrl_outl(0x00, EPLD_INTMASK1);
139#else
140 // On the Overdrive the data is inverted before being stored in the reg
141 ctrl_outl(0xff, EPLD_INTMASK0);
142 ctrl_outl(0xff, EPLD_INTMASK1);
143#endif
144
145 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
146 make_harp_irq(i);
147 }
148}