diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2011-06-01 05:49:18 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2011-11-08 16:35:50 -0500 |
commit | fb1b646aa3bcae2f8211136a6b40228c7c9d236c (patch) | |
tree | 206b07fb3fc5e8a3114258929bebfa7118746536 /arch/m68k | |
parent | 978ef7e6d0e02083e4a62ab4411922bdeffa36a4 (diff) |
m68k/amiga: Optimize interrupts using chain handlers
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/amiga/amiints.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index c3da5342f495..a8da47126584 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c | |||
@@ -48,6 +48,99 @@ static struct irq_chip amiga_irq_chip = { | |||
48 | * The builtin Amiga hardware interrupt handlers. | 48 | * The builtin Amiga hardware interrupt handlers. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
52 | static void ami_int1(unsigned int irq, struct irq_desc *desc) | ||
53 | { | ||
54 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | ||
55 | |||
56 | /* if serial transmit buffer empty, interrupt */ | ||
57 | if (ints & IF_TBE) { | ||
58 | amiga_custom.intreq = IF_TBE; | ||
59 | generic_handle_irq(IRQ_AMIGA_TBE); | ||
60 | } | ||
61 | |||
62 | /* if floppy disk transfer complete, interrupt */ | ||
63 | if (ints & IF_DSKBLK) { | ||
64 | amiga_custom.intreq = IF_DSKBLK; | ||
65 | generic_handle_irq(IRQ_AMIGA_DSKBLK); | ||
66 | } | ||
67 | |||
68 | /* if software interrupt set, interrupt */ | ||
69 | if (ints & IF_SOFT) { | ||
70 | amiga_custom.intreq = IF_SOFT; | ||
71 | generic_handle_irq(IRQ_AMIGA_SOFT); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | static void ami_int3(unsigned int irq, struct irq_desc *desc) | ||
76 | { | ||
77 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | ||
78 | |||
79 | /* if a blitter interrupt */ | ||
80 | if (ints & IF_BLIT) { | ||
81 | amiga_custom.intreq = IF_BLIT; | ||
82 | generic_handle_irq(IRQ_AMIGA_BLIT); | ||
83 | } | ||
84 | |||
85 | /* if a copper interrupt */ | ||
86 | if (ints & IF_COPER) { | ||
87 | amiga_custom.intreq = IF_COPER; | ||
88 | generic_handle_irq(IRQ_AMIGA_COPPER); | ||
89 | } | ||
90 | |||
91 | /* if a vertical blank interrupt */ | ||
92 | if (ints & IF_VERTB) { | ||
93 | amiga_custom.intreq = IF_VERTB; | ||
94 | generic_handle_irq(IRQ_AMIGA_VERTB); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static void ami_int4(unsigned int irq, struct irq_desc *desc) | ||
99 | { | ||
100 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | ||
101 | |||
102 | /* if audio 0 interrupt */ | ||
103 | if (ints & IF_AUD0) { | ||
104 | amiga_custom.intreq = IF_AUD0; | ||
105 | generic_handle_irq(IRQ_AMIGA_AUD0); | ||
106 | } | ||
107 | |||
108 | /* if audio 1 interrupt */ | ||
109 | if (ints & IF_AUD1) { | ||
110 | amiga_custom.intreq = IF_AUD1; | ||
111 | generic_handle_irq(IRQ_AMIGA_AUD1); | ||
112 | } | ||
113 | |||
114 | /* if audio 2 interrupt */ | ||
115 | if (ints & IF_AUD2) { | ||
116 | amiga_custom.intreq = IF_AUD2; | ||
117 | generic_handle_irq(IRQ_AMIGA_AUD2); | ||
118 | } | ||
119 | |||
120 | /* if audio 3 interrupt */ | ||
121 | if (ints & IF_AUD3) { | ||
122 | amiga_custom.intreq = IF_AUD3; | ||
123 | generic_handle_irq(IRQ_AMIGA_AUD3); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | static void ami_int5(unsigned int irq, struct irq_desc *desc) | ||
128 | { | ||
129 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | ||
130 | |||
131 | /* if serial receive buffer full interrupt */ | ||
132 | if (ints & IF_RBF) { | ||
133 | /* acknowledge of IF_RBF must be done by the serial interrupt */ | ||
134 | generic_handle_irq(IRQ_AMIGA_RBF); | ||
135 | } | ||
136 | |||
137 | /* if a disk sync interrupt */ | ||
138 | if (ints & IF_DSKSYN) { | ||
139 | amiga_custom.intreq = IF_DSKSYN; | ||
140 | generic_handle_irq(IRQ_AMIGA_DSKSYN); | ||
141 | } | ||
142 | } | ||
143 | #else /* !CONFIG_GENERIC_HARDIRQS */ | ||
51 | static irqreturn_t ami_int1(int irq, void *dev_id) | 144 | static irqreturn_t ami_int1(int irq, void *dev_id) |
52 | { | 145 | { |
53 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | 146 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
@@ -143,6 +236,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id) | |||
143 | } | 236 | } |
144 | return IRQ_HANDLED; | 237 | return IRQ_HANDLED; |
145 | } | 238 | } |
239 | #endif /* !CONFIG_GENERIC_HARDIRQS */ | ||
146 | 240 | ||
147 | 241 | ||
148 | /* | 242 | /* |
@@ -158,6 +252,15 @@ static irqreturn_t ami_int5(int irq, void *dev_id) | |||
158 | 252 | ||
159 | void __init amiga_init_IRQ(void) | 253 | void __init amiga_init_IRQ(void) |
160 | { | 254 | { |
255 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
256 | m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, | ||
257 | AMI_STD_IRQS); | ||
258 | |||
259 | irq_set_chained_handler(IRQ_AUTO_1, ami_int1); | ||
260 | irq_set_chained_handler(IRQ_AUTO_3, ami_int3); | ||
261 | irq_set_chained_handler(IRQ_AUTO_4, ami_int4); | ||
262 | irq_set_chained_handler(IRQ_AUTO_5, ami_int5); | ||
263 | #else /* !CONFIG_GENERIC_HARDIRQS */ | ||
161 | if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) | 264 | if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) |
162 | pr_err("Couldn't register int%d\n", 1); | 265 | pr_err("Couldn't register int%d\n", 1); |
163 | if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) | 266 | if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) |
@@ -169,6 +272,7 @@ void __init amiga_init_IRQ(void) | |||
169 | 272 | ||
170 | m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, | 273 | m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, |
171 | AMI_STD_IRQS); | 274 | AMI_STD_IRQS); |
275 | #endif /* !CONFIG_GENERIC_HARDIRQS */ | ||
172 | 276 | ||
173 | /* turn off PCMCIA interrupts */ | 277 | /* turn off PCMCIA interrupts */ |
174 | if (AMIGAHW_PRESENT(PCMCIA)) | 278 | if (AMIGAHW_PRESENT(PCMCIA)) |