]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/MAI/AmigaOneG3SE/interrupts.c
3 * John W. Linville <linville@tuxdriver.com>
5 * Copied and modified from original code by Josh Huber. Original
6 * copyright notice preserved below.
9 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
11 * See file CREDITS for list of people who contributed to this
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 * interrupts.c - just enough support for the decrementer/timer
35 #include <asm/processor.h>
41 #define PRINTF(fmt,args...) printf (fmt ,##args)
43 #define PRINTF(fmt,args...)
47 void irq_alloc_init(void);
48 long irq_alloc(long wanted
);
50 /****************************************************************************/
52 unsigned decrementer_count
; /* count value for 1e6/HZ microseconds */
55 interrupt_handler_t
*handler
;
60 static struct irq_action irq_handlers
[NR_IRQS
];
62 /****************************************************************************/
64 static __inline__
unsigned long
69 asm volatile("mfmsr %0" : "=r" (msr
) :);
73 static __inline__
void
74 set_msr(unsigned long msr
)
76 asm volatile("mtmsr %0" : : "r" (msr
));
79 static __inline__
unsigned long
84 asm volatile("mfdec %0" : "=r" (val
) :);
89 static __inline__
void
90 set_dec(unsigned long val
)
92 asm volatile("mtdec %0" : : "r" (val
));
97 enable_interrupts(void)
99 set_msr (get_msr() | MSR_EE
);
102 /* returns flag if MSR_EE was set before */
104 disable_interrupts(void)
109 set_msr (msr
& ~MSR_EE
);
110 return ((msr
& MSR_EE
) != 0);
113 /****************************************************************************/
115 int interrupt_init (void)
117 extern void new_reset(void);
118 extern void new_reset_end(void);
120 puts("interrupt_init: setting decrementer_count\n");
122 decrementer_count
= get_tbclk() / CONFIG_SYS_HZ
;
125 puts("interrupt_init: setting actual decremter\n");
127 set_dec (get_tbclk() / CONFIG_SYS_HZ
);
130 puts("interrupt_init: clearing external interrupt table\n");
132 /* clear external interrupt table here */
133 memset(irq_handlers
, 0, sizeof(irq_handlers
));
136 puts("interrupt_init: initializing interrupt controller\n");
141 puts("Copying reset trampoline\n");
143 /* WARNING: Assmues that the first megabyte is CACHEINHIBIT! */
144 memcpy((void *)0x100, new_reset
, new_reset_end
- new_reset
);
147 PRINTF("interrupt_init: enabling interrupts (msr = %08x)\n",
150 set_msr (get_msr() | MSR_EE
);
153 PRINTF("interrupt_init: done. (msr = %08x)\n", get_msr());
158 /****************************************************************************/
161 * Handle external interrupts
164 external_interrupt(struct pt_regs
*regs
)
166 extern int i8259_irq(void);
170 irq
= i8259_irq(); /*i8259_get_irq(regs); */
171 /* printf("irq = %d, handler at %p ack=%d\n", irq, irq_handlers[irq].handler, *(volatile unsigned char *)0xFEF00000); */
172 i8259_mask_and_ack(irq
);
174 if (irq_handlers
[irq
].handler
!= NULL
)
175 (*irq_handlers
[irq
].handler
)(irq_handlers
[irq
].arg
);
177 PRINTF ("\nBogus External Interrupt IRQ %d\n", irq
);
179 * turn off the bogus interrupt, otherwise it
180 * might repeat forever
185 if (unmask
) i8259_unmask_irq(irq
);
188 volatile ulong timestamp
= 0;
191 * timer_interrupt - gets called when the decrementer overflows,
192 * with interrupts disabled.
193 * Trivial implementation - no need to be really accurate.
196 timer_interrupt(struct pt_regs
*regs
)
198 set_dec(decrementer_count
);
202 /****************************************************************************/
211 get_timer(ulong base
)
213 return (timestamp
- base
);
222 /****************************************************************************/
225 * Install and free a interrupt handler.
229 irq_install_handler(int irq
, interrupt_handler_t
*handler
, void *arg
)
231 if (irq
< 0 || irq
>= NR_IRQS
) {
232 PRINTF("irq_install_handler: bad irq number %d\n", irq
);
236 if (irq_handlers
[irq
].handler
!= NULL
)
237 PRINTF("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
238 (ulong
)handler
, (ulong
)irq_handlers
[irq
].handler
);
240 irq_handlers
[irq
].handler
= handler
;
241 irq_handlers
[irq
].arg
= arg
;
243 i8259_unmask_irq(irq
);
247 irq_free_handler(int irq
)
249 if (irq
< 0 || irq
>= NR_IRQS
) {
250 PRINTF("irq_free_handler: bad irq number %d\n", irq
);
256 irq_handlers
[irq
].handler
= NULL
;
257 irq_handlers
[irq
].arg
= NULL
;
260 /****************************************************************************/
263 do_irqinfo(cmd_tbl_t
*cmdtp
, bd_t
*bd
, int flag
, int argc
, char *argv
[])
265 puts("IRQ related functions are unimplemented currently.\n");