Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
irq.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 PMC-Sierra Inc.
3  * Author: Manish Lachwani ([email protected])
4  *
5  * Copyright (C) 2006 Ralf Baechle ([email protected])
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.
11  *
12  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with this program; if not, write to the Free Software Foundation, Inc.,
25  * 675 Mass Ave, Cambridge, MA 02139, USA.
26  *
27  * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
28  */
29 #include <linux/errno.h>
30 #include <linux/init.h>
31 #include <linux/kernel_stat.h>
32 #include <linux/module.h>
33 #include <linux/signal.h>
34 #include <linux/sched.h>
35 #include <linux/types.h>
36 #include <linux/interrupt.h>
37 #include <linux/ioport.h>
38 #include <linux/irq.h>
39 #include <linux/timex.h>
40 #include <linux/random.h>
41 #include <linux/bitops.h>
42 #include <asm/bootinfo.h>
43 #include <asm/io.h>
44 #include <asm/irq.h>
45 #include <asm/irq_cpu.h>
46 #include <asm/mipsregs.h>
47 #include <asm/titan_dep.h>
48 
49 /* Hypertransport specific */
50 #define IRQ_ACK_BITS 0x00000000 /* Ack bits */
51 
52 #define HYPERTRANSPORT_INTA 0x78 /* INTA# */
53 #define HYPERTRANSPORT_INTB 0x79 /* INTB# */
54 #define HYPERTRANSPORT_INTC 0x7a /* INTC# */
55 #define HYPERTRANSPORT_INTD 0x7b /* INTD# */
56 
57 extern void titan_mailbox_irq(void);
58 
59 #ifdef CONFIG_HYPERTRANSPORT
60 /*
61  * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
62  * For interprocessor interrupts, the best thing to do is to use the INTMSG
63  * register. We use the same external interrupt line, i.e. INTB3 and monitor
64  * another status bit
65  */
66 static void ll_ht_smp_irq_handler(int irq)
67 {
69 
70  /* Ack all the bits that correspond to the interrupt sources */
71  if (status != 0)
73 
75  if (status != 0)
77 
78 #ifdef CONFIG_HT_LEVEL_TRIGGER
79  /*
80  * Level Trigger Mode only. Send the HT EOI message back to the source.
81  */
82  switch (status) {
83  case 0x1000000:
85  break;
86  case 0x2000000:
88  break;
89  case 0x4000000:
91  break;
92  case 0x8000000:
94  break;
95  case 0x0000001:
96  /* PLX */
98  OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS);
99  break;
100  case 0xf000000:
105  break;
106  }
107 #endif /* CONFIG_HT_LEVEL_TRIGGER */
108 
109  do_IRQ(irq);
110 }
111 #endif
112 
114 {
115  unsigned int cause = read_c0_cause();
116  unsigned int status = read_c0_status();
117  unsigned int pending = cause & status;
118 
119  if (pending & STATUSF_IP7) {
120  do_IRQ(7);
121  } else if (pending & STATUSF_IP2) {
122 #ifdef CONFIG_HYPERTRANSPORT
123  ll_ht_smp_irq_handler(2);
124 #else
125  do_IRQ(2);
126 #endif
127  } else if (pending & STATUSF_IP3) {
128  do_IRQ(3);
129  } else if (pending & STATUSF_IP4) {
130  do_IRQ(4);
131  } else if (pending & STATUSF_IP5) {
132 #ifdef CONFIG_SMP
134 #else
135  do_IRQ(5);
136 #endif
137  } else if (pending & STATUSF_IP6) {
138  do_IRQ(4);
139  }
140 }
141 
142 /*
143  * Initialize the next level interrupt handler
144  */
146 {
147  clear_c0_status(ST0_IM);
148 
152 }