1/* 2 * This program is free software; you can redistribute it and/or modify it 3 * under the terms of the GNU General Public License as published by the 4 * Free Software Foundation; either version 2 of the License, or (at your 5 * option) any later version. 6 * 7 * Galileo Technology chip interrupt handler 8 */ 9#include <linux/interrupt.h> 10#include <linux/kernel.h> 11#include <linux/sched.h> 12#include <linux/kernel_stat.h> 13#include <asm/irq_regs.h> 14#include <asm/gt64120.h> 15 16/* 17 * These are interrupt handlers for the GT on-chip interrupts. They all come 18 * in to the MIPS on a single interrupt line, and have to be handled and ack'ed 19 * differently than other MIPS interrupts. 20 */ 21 22static irqreturn_t gt64120_irq(int irq, void *dev_id) 23{ 24 unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask; 25 int handled = 0; 26 27 irq_src = GT_READ(GT_INTRCAUSE_OFS); 28 irq_src_mask = GT_READ(GT_INTRMASK_OFS); 29 int_high_src = GT_READ(GT_HINTRCAUSE_OFS); 30 int_high_src_mask = GT_READ(GT_HINTRMASK_OFS); 31 irq_src = irq_src & irq_src_mask; 32 int_high_src = int_high_src & int_high_src_mask; 33 34 if (irq_src & 0x00000800) { /* Check for timer interrupt */ 35 handled = 1; 36 irq_src &= ~0x00000800; 37 do_timer(1); 38#ifndef CONFIG_SMP 39 update_process_times(user_mode(get_irq_regs())); 40#endif 41 } 42 43 GT_WRITE(GT_INTRCAUSE_OFS, 0); 44 GT_WRITE(GT_HINTRCAUSE_OFS, 0); 45 46 return IRQ_HANDLED; 47} 48 49/* 50 * Initializes timer using galileo's built in timer. 51 */ 52#ifdef CONFIG_SYSCLK_100 53#define Sys_clock (100 * 1000000) // 100 MHz 54#endif 55#ifdef CONFIG_SYSCLK_83 56#define Sys_clock (83.333 * 1000000) // 83.333 MHz 57#endif 58#ifdef CONFIG_SYSCLK_75 59#define Sys_clock (75 * 1000000) // 75 MHz 60#endif 61 62/* 63 * This will ignore the standard MIPS timer interrupt handler that is passed in 64 * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt 65 * handling. 66 */ 67void __init plat_timer_setup(struct irqaction *irq) 68{ 69 static struct irqaction timer; 70 71 /* Disable timer first */ 72 GT_WRITE(GT_TC_CONTROL_OFS, 0); 73 /* Load timer value for 100 Hz */ 74 GT_WRITE(GT_TC3_OFS, Sys_clock / HZ); 75 76 /* 77 * Create the IRQ structure entry for the timer. Since we're too early 78 * in the boot process to use the "request_irq()" call, we'll hard-code 79 * the values to the correct interrupt line. 80 */ 81 timer.handler = gt64120_irq; 82 timer.flags = IRQF_SHARED | IRQF_DISABLED; 83 timer.name = "timer"; 84 timer.dev_id = NULL; 85 timer.next = NULL; 86 timer.mask = CPU_MASK_NONE; 87 irq_desc[GT_TIMER].action = &timer; 88 89 enable_irq(GT_TIMER); 90 91 /* Enable timer ints */ 92 GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); 93 /* clear Cause register first */ 94 GT_WRITE(GT_INTRCAUSE_OFS, 0x0); 95 /* Unmask timer int */ 96 GT_WRITE(GT_INTRMASK_OFS, 0x800); 97 /* Clear High int register */ 98 GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); 99 /* Mask All interrupts at High cause interrupt */ 100 GT_WRITE(GT_HINTRMASK_OFS, 0x0); 101} 102