PageRenderTime 17ms CodeModel.GetById 1ms app.highlight 5ms RepoModel.GetById 10ms app.codeStats 0ms

/arch/mips/mips-boards/atlas/atlas_int.c

https://bitbucket.org/evzijst/gittest
C | 142 lines | 85 code | 26 blank | 31 comment | 14 complexity | 2fece52d31bab12022f5b77e98ac95d7 MD5 | raw file
  1/*
  2 * Carsten Langgaard, carstenl@mips.com
  3 * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
  4 *
  5 * ########################################################################
  6 *
  7 *  This program is free software; you can distribute it and/or modify it
  8 *  under the terms of the GNU General Public License (Version 2) as
  9 *  published by the Free Software Foundation.
 10 *
 11 *  This program is distributed in the hope it will be useful, but WITHOUT
 12 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14 *  for more details.
 15 *
 16 *  You should have received a copy of the GNU General Public License along
 17 *  with this program; if not, write to the Free Software Foundation, Inc.,
 18 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 19 *
 20 * ########################################################################
 21 *
 22 * Routines for generic manipulation of the interrupts found on the MIPS
 23 * Atlas board.
 24 *
 25 */
 26#include <linux/compiler.h>
 27#include <linux/init.h>
 28#include <linux/sched.h>
 29#include <linux/slab.h>
 30#include <linux/interrupt.h>
 31#include <linux/kernel_stat.h>
 32
 33#include <asm/irq.h>
 34#include <asm/io.h>
 35#include <asm/mips-boards/atlas.h>
 36#include <asm/mips-boards/atlasint.h>
 37#include <asm/gdb-stub.h>
 38
 39
 40static struct atlas_ictrl_regs *atlas_hw0_icregs;
 41
 42extern asmlinkage void mipsIRQ(void);
 43
 44#if 0
 45#define DEBUG_INT(x...) printk(x)
 46#else
 47#define DEBUG_INT(x...)
 48#endif
 49
 50void disable_atlas_irq(unsigned int irq_nr)
 51{
 52	atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE));
 53	iob();
 54}
 55
 56void enable_atlas_irq(unsigned int irq_nr)
 57{
 58	atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE));
 59	iob();
 60}
 61
 62static unsigned int startup_atlas_irq(unsigned int irq)
 63{
 64	enable_atlas_irq(irq);
 65	return 0; /* never anything pending */
 66}
 67
 68#define shutdown_atlas_irq	disable_atlas_irq
 69
 70#define mask_and_ack_atlas_irq disable_atlas_irq
 71
 72static void end_atlas_irq(unsigned int irq)
 73{
 74	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 75		enable_atlas_irq(irq);
 76}
 77
 78static struct hw_interrupt_type atlas_irq_type = {
 79	"Atlas",
 80	startup_atlas_irq,
 81	shutdown_atlas_irq,
 82	enable_atlas_irq,
 83	disable_atlas_irq,
 84	mask_and_ack_atlas_irq,
 85	end_atlas_irq,
 86	NULL
 87};
 88
 89static inline int ls1bit32(unsigned int x)
 90{
 91	int b = 31, s;
 92
 93	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
 94	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
 95	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
 96	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
 97	s =  1; if (x <<  1 == 0) s = 0; b -= s;
 98
 99	return b;
100}
101
102void atlas_hw0_irqdispatch(struct pt_regs *regs)
103{
104	unsigned long int_status;
105	int irq;
106
107	int_status = atlas_hw0_icregs->intstatus;
108
109	/* if int_status == 0, then the interrupt has already been cleared */
110	if (unlikely(int_status == 0))
111		return;
112
113	irq = ATLASINT_BASE + ls1bit32(int_status);
114
115	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
116
117	do_IRQ(irq, regs);
118}
119
120void __init arch_init_irq(void)
121{
122	int i;
123
124	atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *));
125	
126	/*
127	 * Mask out all interrupt by writing "1" to all bit position in
128	 * the interrupt reset reg.
129	 */
130	atlas_hw0_icregs->intrsten = 0xffffffff;
131
132	/* Now safe to set the exception vector. */
133	set_except_vector(0, mipsIRQ);
134
135	for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
136		irq_desc[i].status	= IRQ_DISABLED;
137		irq_desc[i].action	= 0;
138		irq_desc[i].depth	= 1;
139		irq_desc[i].handler	= &atlas_irq_type;
140		spin_lock_init(&irq_desc[i].lock);
141	}
142}