This source file includes following definitions.
- pnx833x_timer_dispatch
- pic_dispatch
- plat_irq_dispatch
- pnx833x_hard_enable_pic_irq
- pnx833x_hard_disable_pic_irq
- pnx833x_startup_pic_irq
- pnx833x_enable_pic_irq
- pnx833x_disable_pic_irq
- pnx833x_enable_gpio_irq
- pnx833x_disable_gpio_irq
- pnx833x_set_type_gpio_irq
- arch_init_irq
- get_c0_compare_int
- plat_time_init
1
2
3
4
5
6
7
8
9 #include <linux/kernel.h>
10 #include <linux/irq.h>
11 #include <linux/hardirq.h>
12 #include <linux/interrupt.h>
13 #include <asm/mipsregs.h>
14 #include <asm/irq_cpu.h>
15 #include <asm/setup.h>
16 #include <irq.h>
17 #include <irq-mapping.h>
18 #include <gpio.h>
19
20 static int mips_cpu_timer_irq;
21
22 static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] =
23 {
24 0,
25 4,
26 4,
27 1,
28 1,
29 6,
30 6,
31 7,
32 4,
33 5,
34 4,
35 4,
36 9,
37 9,
38 4,
39 9,
40 4,
41 9,
42 4,
43 4,
44 9,
45 9,
46 6,
47 6,
48 4,
49 4,
50 4,
51 3,
52 3,
53 4,
54 4,
55 4,
56 5,
57 4,
58 4,
59 4,
60 4,
61 #if defined(CONFIG_SOC_PNX8335)
62 4,
63 4,
64 9,
65 9,
66 9,
67 4,
68 4,
69 4,
70 4,
71 4,
72 4,
73 4,
74 4,
75 4,
76 4,
77 12,
78 3,
79 3,
80 4,
81 4,
82 4,
83 #endif
84 };
85
86 static void pnx833x_timer_dispatch(void)
87 {
88 do_IRQ(mips_cpu_timer_irq);
89 }
90
91 static void pic_dispatch(void)
92 {
93 unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC);
94
95 if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) {
96 unsigned long priority = PNX833X_PIC_INT_PRIORITY;
97 PNX833X_PIC_INT_PRIORITY = irq_prio[irq];
98
99 if (irq == PNX833X_PIC_GPIO_INT) {
100 unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE;
101 int pin;
102 while ((pin = ffs(mask & 0xffff))) {
103 pin -= 1;
104 do_IRQ(PNX833X_GPIO_IRQ_BASE + pin);
105 mask &= ~(1 << pin);
106 }
107 } else {
108 do_IRQ(irq + PNX833X_PIC_IRQ_BASE);
109 }
110
111 PNX833X_PIC_INT_PRIORITY = priority;
112 } else {
113 printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq);
114 }
115 }
116
117 asmlinkage void plat_irq_dispatch(void)
118 {
119 unsigned int pending = read_c0_status() & read_c0_cause();
120
121 if (pending & STATUSF_IP4)
122 pic_dispatch();
123 else if (pending & STATUSF_IP7)
124 do_IRQ(PNX833X_TIMER_IRQ);
125 else
126 spurious_interrupt();
127 }
128
129 static inline void pnx833x_hard_enable_pic_irq(unsigned int irq)
130 {
131
132
133
134 PNX833X_PIC_INT_REG(irq) = irq_prio[irq];
135 }
136
137 static inline void pnx833x_hard_disable_pic_irq(unsigned int irq)
138 {
139
140 PNX833X_PIC_INT_REG(irq) = 0;
141 }
142
143 static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
144
145 static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
146 {
147 unsigned long flags;
148 unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
149
150 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
151 pnx833x_hard_enable_pic_irq(pic_irq);
152 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
153 return 0;
154 }
155
156 static void pnx833x_enable_pic_irq(struct irq_data *d)
157 {
158 unsigned long flags;
159 unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
160
161 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
162 pnx833x_hard_enable_pic_irq(pic_irq);
163 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
164 }
165
166 static void pnx833x_disable_pic_irq(struct irq_data *d)
167 {
168 unsigned long flags;
169 unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
170
171 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
172 pnx833x_hard_disable_pic_irq(pic_irq);
173 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
174 }
175
176 static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
177
178 static void pnx833x_enable_gpio_irq(struct irq_data *d)
179 {
180 int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
181 unsigned long flags;
182 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
183 pnx833x_gpio_enable_irq(pin);
184 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
185 }
186
187 static void pnx833x_disable_gpio_irq(struct irq_data *d)
188 {
189 int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
190 unsigned long flags;
191 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
192 pnx833x_gpio_disable_irq(pin);
193 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
194 }
195
196 static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type)
197 {
198 int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
199 int gpio_mode;
200
201 switch (flow_type) {
202 case IRQ_TYPE_EDGE_RISING:
203 gpio_mode = GPIO_INT_EDGE_RISING;
204 break;
205 case IRQ_TYPE_EDGE_FALLING:
206 gpio_mode = GPIO_INT_EDGE_FALLING;
207 break;
208 case IRQ_TYPE_EDGE_BOTH:
209 gpio_mode = GPIO_INT_EDGE_BOTH;
210 break;
211 case IRQ_TYPE_LEVEL_HIGH:
212 gpio_mode = GPIO_INT_LEVEL_HIGH;
213 break;
214 case IRQ_TYPE_LEVEL_LOW:
215 gpio_mode = GPIO_INT_LEVEL_LOW;
216 break;
217 default:
218 gpio_mode = GPIO_INT_NONE;
219 break;
220 }
221
222 pnx833x_gpio_setup_irq(gpio_mode, pin);
223
224 return 0;
225 }
226
227 static struct irq_chip pnx833x_pic_irq_type = {
228 .name = "PNX-PIC",
229 .irq_enable = pnx833x_enable_pic_irq,
230 .irq_disable = pnx833x_disable_pic_irq,
231 };
232
233 static struct irq_chip pnx833x_gpio_irq_type = {
234 .name = "PNX-GPIO",
235 .irq_enable = pnx833x_enable_gpio_irq,
236 .irq_disable = pnx833x_disable_gpio_irq,
237 .irq_set_type = pnx833x_set_type_gpio_irq,
238 };
239
240 void __init arch_init_irq(void)
241 {
242 unsigned int irq;
243
244
245 mips_cpu_irq_init();
246
247
248 for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) {
249 pnx833x_hard_disable_pic_irq(irq);
250 irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type,
251 handle_simple_irq);
252 }
253
254 for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++)
255 irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type,
256 handle_simple_irq);
257
258
259 PNX833X_PIC_INT_PRIORITY = 0;
260
261
262 pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT);
263
264
265 if (cpu_has_vint)
266 set_vi_handler(4, pic_dispatch);
267
268 write_c0_status(read_c0_status() | IE_IRQ2);
269 }
270
271 unsigned int get_c0_compare_int(void)
272 {
273 if (cpu_has_vint)
274 set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch);
275
276 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
277 return mips_cpu_timer_irq;
278 }
279
280 void __init plat_time_init(void)
281 {
282
283
284 extern unsigned long mips_hpt_frequency;
285 unsigned long reg = PNX833X_CLOCK_CPUCP_CTL;
286
287 if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) {
288
289 mips_hpt_frequency = 25;
290 } else {
291 #if defined(CONFIG_SOC_PNX8335)
292
293 mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ));
294 #else
295 static const unsigned long int freq[4] = {240, 160, 120, 80};
296 mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)];
297 #endif
298 }
299
300 printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency);
301
302 mips_hpt_frequency *= 500000;
303 }