• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/mips/brcm-boards/generic/
1/*
2 * Generic interrupt control functions for Broadcom MIPS boards
3 *
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: irq.c,v 1.1 2007/09/04 04:41:12 Exp $
19 */
20
21#include <linux/config.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27
28#include <asm/irq.h>
29#include <asm/mipsregs.h>
30#include <asm/gdb-stub.h>
31
32#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
33
34extern asmlinkage void brcmIRQ(void);
35extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
36
37void
38plat_irq_dispatch(struct pt_regs *regs)
39{
40	u32 cause;
41
42	cause = read_c0_cause() &
43		read_c0_status() &
44		CAUSEF_IP;
45
46#ifdef CONFIG_KERNPROF
47	change_c0_status(cause | 1, 1);
48#else
49	clear_c0_status(cause);
50#endif
51
52	if (cause & CAUSEF_IP7)
53		do_IRQ(7, regs);
54	if (cause & CAUSEF_IP2)
55		do_IRQ(2, regs);
56	if (cause & CAUSEF_IP3)
57		do_IRQ(3, regs);
58	if (cause & CAUSEF_IP4)
59		do_IRQ(4, regs);
60	if (cause & CAUSEF_IP5)
61		do_IRQ(5, regs);
62	if (cause & CAUSEF_IP6)
63		do_IRQ(6, regs);
64}
65
66static void
67enable_brcm_irq(unsigned int irq)
68{
69	if (irq < 8)
70		set_c0_status(1 << (irq + 8));
71	else
72		set_c0_status(IE_IRQ0);
73}
74
75static void
76disable_brcm_irq(unsigned int irq)
77{
78	if (irq < 8)
79		clear_c0_status(1 << (irq + 8));
80	else
81		clear_c0_status(IE_IRQ0);
82}
83
84static void
85ack_brcm_irq(unsigned int irq)
86{
87	/* Already done in plat_irq_dispatch */
88}
89
90static unsigned int
91startup_brcm_irq(unsigned int irq)
92{
93	enable_brcm_irq(irq);
94
95	return 0; /* never anything pending */
96}
97
98static void
99end_brcm_irq(unsigned int irq)
100{
101	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
102		enable_brcm_irq(irq);
103}
104
105static struct hw_interrupt_type brcm_irq_type = {
106	typename: "MIPS",
107	startup: startup_brcm_irq,
108	shutdown: disable_brcm_irq,
109	enable: enable_brcm_irq,
110	disable: disable_brcm_irq,
111	ack: ack_brcm_irq,
112	end: end_brcm_irq,
113	NULL
114};
115
116void __init
117init_IRQ(void)
118{
119	int i;
120
121	for (i = 0; i < NR_IRQS; i++) {
122		irq_desc[i].status = IRQ_DISABLED;
123		irq_desc[i].action = 0;
124		irq_desc[i].depth = 1;
125		irq_desc[i].handler = &brcm_irq_type;
126	}
127
128	change_c0_status(ST0_IM, ALLINTS);
129
130#ifdef CONFIG_KGDB
131	printk("Breaking into debugger...\n");
132	set_debug_traps();
133	breakpoint();
134#endif
135}
136