diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m68k/mac/psc.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/m68k/mac/psc.c')
-rw-r--r-- | arch/m68k/mac/psc.c | 66 |
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 @@ | |||
31 | int psc_present; | 30 | int psc_present; |
32 | volatile __u8 *psc; | 31 | volatile __u8 *psc; |
33 | 32 | ||
33 | irqreturn_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 | |||
118 | void __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 | ||
117 | static void psc_irq(unsigned int irq, struct irq_desc *desc) | 134 | irqreturn_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 | |||
150 | void __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 | ||
162 | void psc_irq_enable(int irq) { | 163 | void 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 | |||
185 | void 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 | |||
193 | int 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 | } | ||