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  * Interrupt handing routines for NEC VR4100 series.
3  *
4  * Copyright (C) 2005-2007 Yoichi Yuasa <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
22 #include <linux/irq.h>
23 
24 #include <asm/irq_cpu.h>
25 #include <asm/vr41xx/irq.h>
26 
27 typedef struct irq_cascade {
28  int (*get_irq)(unsigned int);
30 
32 
33 static struct irqaction cascade_irqaction = {
34  .handler = no_action,
35  .name = "cascade",
36  .flags = IRQF_NO_THREAD,
37 };
38 
39 int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
40 {
41  int retval = 0;
42 
43  if (irq >= NR_IRQS)
44  return -EINVAL;
45 
46  if (irq_cascade[irq].get_irq != NULL)
47  free_irq(irq, NULL);
48 
50 
51  if (get_irq != NULL) {
52  retval = setup_irq(irq, &cascade_irqaction);
53  if (retval < 0)
55  }
56 
57  return retval;
58 }
59 
61 
62 static void irq_dispatch(unsigned int irq)
63 {
64  irq_cascade_t *cascade;
65 
66  if (irq >= NR_IRQS) {
68  return;
69  }
70 
71  cascade = irq_cascade + irq;
72  if (cascade->get_irq != NULL) {
73  struct irq_desc *desc = irq_to_desc(irq);
74  struct irq_data *idata = irq_desc_get_irq_data(desc);
75  struct irq_chip *chip = irq_desc_get_chip(desc);
76  int ret;
77 
78  if (chip->irq_mask_ack)
79  chip->irq_mask_ack(idata);
80  else {
81  chip->irq_mask(idata);
82  chip->irq_ack(idata);
83  }
84  ret = cascade->get_irq(irq);
85  irq = ret;
86  if (ret < 0)
88  else
89  irq_dispatch(irq);
90  if (!irqd_irq_disabled(idata) && chip->irq_unmask)
91  chip->irq_unmask(idata);
92  } else
93  do_IRQ(irq);
94 }
95 
97 {
98  unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
99 
100  if (pending & CAUSEF_IP7)
101  do_IRQ(TIMER_IRQ);
102  else if (pending & 0x7800) {
103  if (pending & CAUSEF_IP3)
104  irq_dispatch(INT1_IRQ);
105  else if (pending & CAUSEF_IP4)
106  irq_dispatch(INT2_IRQ);
107  else if (pending & CAUSEF_IP5)
108  irq_dispatch(INT3_IRQ);
109  else if (pending & CAUSEF_IP6)
110  irq_dispatch(INT4_IRQ);
111  } else if (pending & CAUSEF_IP2)
112  irq_dispatch(INT0_IRQ);
113  else if (pending & CAUSEF_IP0)
115  else if (pending & CAUSEF_IP1)
117  else
119 }
120 
122 {
124 }