1/* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * (C) Copyright 2003 6 * Gleb Natapov <gnatapov@mrv.com> 7 * 8 * (C) Copyright 2007 9 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. 10 * 11 * See file CREDITS for list of people who contributed to this 12 * project. 13 * 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. 18 * 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. 23 * 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, 27 * MA 02111-1307 USA 28 */ 29 30#include <common.h> 31#include <asm/processor.h> 32#include <asm/irq.h> 33 34/* Implemented by SPARC CPUs */ 35extern int interrupt_init_cpu(void); 36extern void timer_interrupt_cpu(void *arg); 37extern int timer_interrupt_init_cpu(void); 38 39int intLock(void) 40{ 41 unsigned int pil; 42 43 pil = get_pil(); 44 45 /* set PIL to 15 ==> no pending interrupts will interrupt CPU */ 46 set_pil(15); 47 48 return pil; 49} 50 51void intUnlock(int oldLevel) 52{ 53 set_pil(oldLevel); 54} 55 56void enable_interrupts(void) 57{ 58 set_pil(0); /* enable all interrupts */ 59} 60 61int disable_interrupts(void) 62{ 63 return intLock(); 64} 65 66int interrupt_init(void) 67{ 68 int ret; 69 70 /* call cpu specific function from $(CPU)/interrupts.c */ 71 ret = interrupt_init_cpu(); 72 73 /* enable global interrupts */ 74 enable_interrupts(); 75 76 return ret; 77} 78 79/* timer interrupt/overflow counter */ 80static volatile ulong timestamp = 0; 81 82/* regs can not be used here! regs is actually the pointer given in 83 * irq_install_handler 84 */ 85void timer_interrupt(struct pt_regs *regs) 86{ 87 /* call cpu specific function from $(CPU)/interrupts.c */ 88 timer_interrupt_cpu((void *)regs); 89 90 timestamp++; 91} 92 93void reset_timer(void) 94{ 95 timestamp = 0; 96} 97 98ulong get_timer(ulong base) 99{ 100 return (timestamp - base); 101} 102 103void set_timer(ulong t) 104{ 105 timestamp = t; 106} 107 108void timer_interrupt_init(void) 109{ 110 int irq; 111 112 reset_timer(); 113 114 irq = timer_interrupt_init_cpu(); 115 116 if (irq < 0) { 117 /* cpu specific code handled the interrupt registration it self */ 118 return; 119 } 120 /* register interrupt handler for timer */ 121 irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL); 122} 123