3 * Copyright 2001 MontaVista Software Inc.
4 * Author: jsun@mvista.com or jsun@junsun.net
6 * arch/mips/gt64120/common/gt_irq.c
7 * Interrupt routines for gt64120. Currently it only handles timer irq.
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
17 #include <asm/ptrace.h>
18 #include <linux/config.h>
19 #include <linux/sched.h>
20 #include <linux/kernel_stat.h>
22 #include <asm/gt64120/gt64120.h>
25 * These are interrupt handlers for the GT on-chip interrupts. They
26 * all come in to the MIPS on a single interrupt line, and have to
27 * be handled and ack'ed differently than other MIPS interrupts.
32 struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
33 void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
36 * Hooks IRQ handler to the system. When the system is interrupted
37 * the interrupt service routine is called.
40 * int_cause - The interrupt cause number. In EVB64120 two parameters
41 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
42 * bit_num - Indicates which bit number in the cause register
43 * isr_ptr - Pointer to the interrupt service routine
45 void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
47 irq_handlers[int_cause][bit_num].routine = isr_ptr;
52 * Enables the IRQ on Galileo Chip
55 * int_cause - The interrupt cause number. In EVB64120 two parameters
56 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
57 * bit_num - Indicates which bit number in the cause register
60 * 1 if succesful, 0 if failure
62 int enable_galileo_irq(int int_cause, int bit_num)
64 if (int_cause == INT_CAUSE_MAIN)
65 SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
66 else if (int_cause == INT_CAUSE_HIGH)
67 SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
76 * Disables the IRQ on Galileo Chip
79 * int_cause - The interrupt cause number. In EVB64120 two parameters
80 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
81 * bit_num - Indicates which bit number in the cause register
84 * 1 if succesful, 0 if failure
86 int disable_galileo_irq(int int_cause, int bit_num)
88 if (int_cause == INT_CAUSE_MAIN)
89 RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
91 else if (int_cause == INT_CAUSE_HIGH)
92 RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
101 * Interrupt handler for interrupts coming from the Galileo chip.
102 * It could be timer interrupt, built in ethernet ports etc...
104 static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
106 unsigned int irq_src, int_high_src, irq_src_mask,
110 GT_READ(GT_INTRCAUSE_OFS, &irq_src);
111 GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
112 GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
113 GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
114 irq_src = irq_src & irq_src_mask;
115 int_high_src = int_high_src & int_high_src_mask;
119 /* Execute all interrupt handlers */
120 /* Check for timer interrupt */
121 if (irq_src & 0x00000800) {
123 irq_src &= ~0x00000800;
124 // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
130 "Other Galileo interrupt received irq_src %x\n",
133 for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
134 if (irq_src & (1 << count)) {
135 if (irq_handlers[INT_CAUSE_MAIN][count].
137 queue_task(&irq_handlers
138 [INT_CAUSE_MAIN][count],
140 mark_bh(IMMEDIATE_BH);
147 GT_WRITE(GT_INTRCAUSE_OFS, 0);
148 GT_WRITE(GT_HINTRCAUSE_OFS, 0);
153 * Future I2O support. We currently attach I2O interrupt handlers to
154 * the Galileo interrupt (int 4) and handle them in do_IRQ.
156 if (isInBoundDoorBellInterruptSet()) {
157 printk(KERN_INFO "I2O doorbell interrupt received.\n");
161 if (isInBoundPostQueueInterruptSet()) {
162 printk(KERN_INFO "I2O Queue interrupt received.\n");
167 * This normally would be outside of the ifdef, but since we're
168 * handling I2O outside of this handler, this printk shows up every
169 * time we get a valid I2O interrupt. So turn this off for now.
173 printk("Spurious Galileo interrupt...\n");
181 * Initializes timer using galileo's built in timer.
183 #ifdef CONFIG_SYSCLK_100
184 #define Sys_clock (100 * 1000000) // 100 MHz
186 #ifdef CONFIG_SYSCLK_83
187 #define Sys_clock (83.333 * 1000000) // 83.333 MHz
189 #ifdef CONFIG_SYSCLK_75
190 #define Sys_clock (75 * 1000000) // 75 MHz
194 * This will ignore the standard MIPS timer interrupt handler
195 * that is passed in as *irq (=irq0 in ../kernel/time.c).
196 * We will do our own timer interrupt handling.
198 void gt64120_time_init(void)
200 extern irq_desc_t irq_desc[NR_IRQS];
201 static struct irqaction timer;
203 /* Disable timer first */
204 GT_WRITE(GT_TC_CONTROL_OFS, 0);
205 /* Load timer value for 100 Hz */
206 GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
209 * Create the IRQ structure entry for the timer. Since we're too early
210 * in the boot process to use the "request_irq()" call, we'll hard-code
211 * the values to the correct interrupt line.
213 timer.handler = >64120_irq;
214 timer.flags = SA_SHIRQ | SA_INTERRUPT;
215 timer.name = "timer";
219 irq_desc[TIMER].action = &timer;
223 /* Enable timer ints */
224 GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
225 /* clear Cause register first */
226 GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
227 /* Unmask timer int */
228 GT_WRITE(GT_INTRMASK_OFS, 0x800);
229 /* Clear High int register */
230 GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
231 /* Mask All interrupts at High cause interrupt */
232 GT_WRITE(GT_HINTRMASK_OFS, 0x0);
235 void gt64120_irq_init(void)
240 /* Reset irq handlers pointers to NULL */
241 for (i = 0; i < MAX_CAUSE_REGS; i++) {
242 for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
243 irq_handlers[i][j].next = NULL;
244 irq_handlers[i][j].sync = 0;
245 irq_handlers[i][j].routine = NULL;
246 irq_handlers[i][j].data = NULL;