aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/mac/psc.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m68k/mac/psc.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/m68k/mac/psc.c')
-rw-r--r--arch/m68k/mac/psc.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 6f026fc302f..a4c3eb60706 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -18,7 +18,6 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/irq.h>
22 21
23#include <asm/traps.h> 22#include <asm/traps.h>
24#include <asm/bootinfo.h> 23#include <asm/bootinfo.h>
@@ -31,6 +30,8 @@
31int psc_present; 30int psc_present;
32volatile __u8 *psc; 31volatile __u8 *psc;
33 32
33irqreturn_t psc_irq(int, void *);
34
34/* 35/*
35 * Debugging dump, used in various places to see what's going on. 36 * Debugging dump, used in various places to see what's going on.
36 */ 37 */
@@ -111,52 +112,52 @@ void __init psc_init(void)
111} 112}
112 113
113/* 114/*
115 * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
116 */
117
118void __init psc_register_interrupts(void)
119{
120 if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30))
121 pr_err("Couldn't register psc%d interrupt\n", 3);
122 if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40))
123 pr_err("Couldn't register psc%d interrupt\n", 4);
124 if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50))
125 pr_err("Couldn't register psc%d interrupt\n", 5);
126 if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60))
127 pr_err("Couldn't register psc%d interrupt\n", 6);
128}
129
130/*
114 * PSC interrupt handler. It's a lot like the VIA interrupt handler. 131 * PSC interrupt handler. It's a lot like the VIA interrupt handler.
115 */ 132 */
116 133
117static void psc_irq(unsigned int irq, struct irq_desc *desc) 134irqreturn_t psc_irq(int irq, void *dev_id)
118{ 135{
119 unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); 136 int pIFR = pIFRbase + ((int) dev_id);
120 int pIFR = pIFRbase + offset; 137 int pIER = pIERbase + ((int) dev_id);
121 int pIER = pIERbase + offset;
122 int irq_num; 138 int irq_num;
123 unsigned char irq_bit, events; 139 unsigned char irq_bit, events;
124 140
125#ifdef DEBUG_IRQS 141#ifdef DEBUG_IRQS
126 printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n", 142 printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n",
127 irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); 143 irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER));
128#endif 144#endif
129 145
130 events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; 146 events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF;
131 if (!events) 147 if (!events)
132 return; 148 return IRQ_NONE;
133 149
134 irq_num = irq << 3; 150 irq_num = irq << 3;
135 irq_bit = 1; 151 irq_bit = 1;
136 do { 152 do {
137 if (events & irq_bit) { 153 if (events & irq_bit) {
138 psc_write_byte(pIFR, irq_bit); 154 psc_write_byte(pIFR, irq_bit);
139 generic_handle_irq(irq_num); 155 m68k_handle_int(irq_num);
140 } 156 }
141 irq_num++; 157 irq_num++;
142 irq_bit <<= 1; 158 irq_bit <<= 1;
143 } while (events >= irq_bit); 159 } while (events >= irq_bit);
144} 160 return IRQ_HANDLED;
145
146/*
147 * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
148 */
149
150void __init psc_register_interrupts(void)
151{
152 irq_set_chained_handler(IRQ_AUTO_3, psc_irq);
153 irq_set_handler_data(IRQ_AUTO_3, (void *)0x30);
154 irq_set_chained_handler(IRQ_AUTO_4, psc_irq);
155 irq_set_handler_data(IRQ_AUTO_4, (void *)0x40);
156 irq_set_chained_handler(IRQ_AUTO_5, psc_irq);
157 irq_set_handler_data(IRQ_AUTO_5, (void *)0x50);
158 irq_set_chained_handler(IRQ_AUTO_6, psc_irq);
159 irq_set_handler_data(IRQ_AUTO_6, (void *)0x60);
160} 161}
161 162
162void psc_irq_enable(int irq) { 163void psc_irq_enable(int irq) {
@@ -180,3 +181,20 @@ void psc_irq_disable(int irq) {
180#endif 181#endif
181 psc_write_byte(pIER, 1 << irq_idx); 182 psc_write_byte(pIER, 1 << irq_idx);
182} 183}
184
185void psc_irq_clear(int irq) {
186 int irq_src = IRQ_SRC(irq);
187 int irq_idx = IRQ_IDX(irq);
188 int pIFR = pIERbase + (irq_src << 4);
189
190 psc_write_byte(pIFR, 1 << irq_idx);
191}
192
193int psc_irq_pending(int irq)
194{
195 int irq_src = IRQ_SRC(irq);
196 int irq_idx = IRQ_IDX(irq);
197 int pIFR = pIERbase + (irq_src << 4);
198
199 return psc_read_byte(pIFR) & (1 << irq_idx);
200}