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  * arch/arm/mach-ks8695/irq.c
3  *
4  * Copyright (C) 2006 Ben Dooks <[email protected]>
5  * Copyright (C) 2006 Simtec Electronics
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/interrupt.h>
25 #include <linux/ioport.h>
26 #include <linux/device.h>
27 #include <linux/io.h>
28 
29 #include <mach/hardware.h>
30 #include <asm/irq.h>
31 
32 #include <asm/mach/irq.h>
33 
34 #include <mach/regs-irq.h>
35 #include <mach/regs-gpio.h>
36 
37 static void ks8695_irq_mask(struct irq_data *d)
38 {
39  unsigned long inten;
40 
42  inten &= ~(1 << d->irq);
43 
45 }
46 
47 static void ks8695_irq_unmask(struct irq_data *d)
48 {
49  unsigned long inten;
50 
52  inten |= (1 << d->irq);
53 
55 }
56 
57 static void ks8695_irq_ack(struct irq_data *d)
58 {
60 }
61 
62 
63 static struct irq_chip ks8695_irq_level_chip;
64 static struct irq_chip ks8695_irq_edge_chip;
65 
66 
67 static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
68 {
69  unsigned long ctrl, mode;
70  unsigned short level_triggered = 0;
71 
73 
74  switch (type) {
76  mode = IOPC_TM_HIGH;
77  level_triggered = 1;
78  break;
79  case IRQ_TYPE_LEVEL_LOW:
80  mode = IOPC_TM_LOW;
81  level_triggered = 1;
82  break;
84  mode = IOPC_TM_RISING;
85  break;
87  mode = IOPC_TM_FALLING;
88  break;
89  case IRQ_TYPE_EDGE_BOTH:
90  mode = IOPC_TM_EDGE;
91  break;
92  default:
93  return -EINVAL;
94  }
95 
96  switch (d->irq) {
97  case KS8695_IRQ_EXTERN0:
98  ctrl &= ~IOPC_IOEINT0TM;
99  ctrl |= IOPC_IOEINT0_MODE(mode);
100  break;
101  case KS8695_IRQ_EXTERN1:
102  ctrl &= ~IOPC_IOEINT1TM;
103  ctrl |= IOPC_IOEINT1_MODE(mode);
104  break;
105  case KS8695_IRQ_EXTERN2:
106  ctrl &= ~IOPC_IOEINT2TM;
107  ctrl |= IOPC_IOEINT2_MODE(mode);
108  break;
109  case KS8695_IRQ_EXTERN3:
110  ctrl &= ~IOPC_IOEINT3TM;
111  ctrl |= IOPC_IOEINT3_MODE(mode);
112  break;
113  default:
114  return -EINVAL;
115  }
116 
117  if (level_triggered) {
118  irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
120  }
121  else {
122  irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
124  }
125 
127  return 0;
128 }
129 
130 static struct irq_chip ks8695_irq_level_chip = {
131  .irq_ack = ks8695_irq_mask,
132  .irq_mask = ks8695_irq_mask,
133  .irq_unmask = ks8695_irq_unmask,
134  .irq_set_type = ks8695_irq_set_type,
135 };
136 
137 static struct irq_chip ks8695_irq_edge_chip = {
138  .irq_ack = ks8695_irq_ack,
139  .irq_mask = ks8695_irq_mask,
140  .irq_unmask = ks8695_irq_unmask,
141  .irq_set_type = ks8695_irq_set_type,
142 };
143 
145 {
146  unsigned int irq;
147 
148  /* Disable all interrupts initially */
151 
152  for (irq = 0; irq < NR_IRQS; irq++) {
153  switch (irq) {
154  /* Level-triggered interrupts */
158  case KS8695_IRQ_UART_RX:
159  case KS8695_IRQ_COMM_TX:
160  case KS8695_IRQ_COMM_RX:
161  irq_set_chip_and_handler(irq,
162  &ks8695_irq_level_chip,
164  break;
165 
166  /* Edge-triggered interrupts */
167  default:
168  /* clear pending bit */
169  ks8695_irq_ack(irq_get_irq_data(irq));
170  irq_set_chip_and_handler(irq,
171  &ks8695_irq_edge_chip,
173  }
174 
176  }
177 }