blob: 58a4c7b90b8bb27256269a97d9eb927886a5aa4a [file] [log] [blame]
Paul Mackerras14cf11a2005-09-26 16:04:21 +10001/*
2 * Support for the interrupt controllers found on Power Macintosh,
3 * currently Apple's "Grand Central" interrupt controller in all
4 * it's incarnations. OpenPIC support used on newer machines is
5 * in a separate file
6 *
7 * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +11008 * Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org)
9 * IBM, Corp.
Paul Mackerras14cf11a2005-09-26 16:04:21 +100010 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 *
16 */
17
Paul Mackerras14cf11a2005-09-26 16:04:21 +100018#include <linux/stddef.h>
19#include <linux/init.h>
20#include <linux/sched.h>
21#include <linux/signal.h>
22#include <linux/pci.h>
23#include <linux/interrupt.h>
24#include <linux/sysdev.h>
25#include <linux/adb.h>
26#include <linux/pmu.h>
Paul Mackerras3c3f42d2005-10-10 22:58:41 +100027#include <linux/module.h>
Paul Mackerras14cf11a2005-09-26 16:04:21 +100028
29#include <asm/sections.h>
30#include <asm/io.h>
31#include <asm/smp.h>
32#include <asm/prom.h>
33#include <asm/pci-bridge.h>
34#include <asm/time.h>
Paul Mackerras14cf11a2005-09-26 16:04:21 +100035#include <asm/pmac_feature.h>
36#include <asm/mpic.h>
37
Paul Mackerras3c3f42d2005-10-10 22:58:41 +100038#include "pmac.h"
Paul Mackerras14cf11a2005-09-26 16:04:21 +100039
40/*
41 * XXX this should be in xmon.h, but putting it there means xmon.h
42 * has to include <linux/interrupt.h> (to get irqreturn_t), which
43 * causes all sorts of problems. -- paulus
44 */
45extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
46
Paul Mackerras3c3f42d2005-10-10 22:58:41 +100047#ifdef CONFIG_PPC32
Paul Mackerras14cf11a2005-09-26 16:04:21 +100048struct pmac_irq_hw {
49 unsigned int event;
50 unsigned int enable;
51 unsigned int ack;
52 unsigned int level;
53};
54
55/* Default addresses */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +110056static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
Paul Mackerras14cf11a2005-09-26 16:04:21 +100057
58#define GC_LEVEL_MASK 0x3ff00000
59#define OHARE_LEVEL_MASK 0x1ff00000
60#define HEATHROW_LEVEL_MASK 0x1ff00000
61
62static int max_irqs;
63static int max_real_irqs;
64static u32 level_mask[4];
65
66static DEFINE_SPINLOCK(pmac_pic_lock);
67
Paul Mackerras14cf11a2005-09-26 16:04:21 +100068#define GATWICK_IRQ_POOL_SIZE 10
69static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
70
Stephen Rothwell756e7102005-11-09 18:07:45 +110071#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
72static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +100073static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
74static int pmac_irq_cascade = -1;
Stephen Rothwell756e7102005-11-09 18:07:45 +110075
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +100076static void __pmac_retrigger(unsigned int irq_nr)
Paul Mackerras14cf11a2005-09-26 16:04:21 +100077{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +100078 if (irq_nr >= max_real_irqs && pmac_irq_cascade > 0) {
79 __set_bit(irq_nr, ppc_lost_interrupts);
80 irq_nr = pmac_irq_cascade;
81 mb();
82 }
83 if (!__test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
Paul Mackerras14cf11a2005-09-26 16:04:21 +100084 atomic_inc(&ppc_n_lost_interrupts);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +100085 set_dec(1);
Paul Mackerras14cf11a2005-09-26 16:04:21 +100086 }
87}
88
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +110089static void pmac_mask_and_ack_irq(unsigned int irq_nr)
Paul Mackerras14cf11a2005-09-26 16:04:21 +100090{
91 unsigned long bit = 1UL << (irq_nr & 0x1f);
92 int i = irq_nr >> 5;
93 unsigned long flags;
94
95 if ((unsigned)irq_nr >= max_irqs)
96 return;
97
Paul Mackerras14cf11a2005-09-26 16:04:21 +100098 spin_lock_irqsave(&pmac_pic_lock, flags);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +100099 __clear_bit(irq_nr, ppc_cached_irq_mask);
100 if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts))
101 atomic_dec(&ppc_n_lost_interrupts);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000102 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
103 out_le32(&pmac_irq_hw[i]->ack, bit);
104 do {
105 /* make sure ack gets to controller before we enable
106 interrupts */
107 mb();
108 } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
109 != (ppc_cached_irq_mask[i] & bit));
110 spin_unlock_irqrestore(&pmac_pic_lock, flags);
111}
112
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000113static void pmac_ack_irq(unsigned int irq_nr)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000114{
115 unsigned long bit = 1UL << (irq_nr & 0x1f);
116 int i = irq_nr >> 5;
117 unsigned long flags;
118
119 if ((unsigned)irq_nr >= max_irqs)
120 return;
121
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000122 spin_lock_irqsave(&pmac_pic_lock, flags);
123 if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts))
124 atomic_dec(&ppc_n_lost_interrupts);
125 out_le32(&pmac_irq_hw[i]->ack, bit);
126 (void)in_le32(&pmac_irq_hw[i]->ack);
127 spin_unlock_irqrestore(&pmac_pic_lock, flags);
128}
129
130static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
131{
132 unsigned long bit = 1UL << (irq_nr & 0x1f);
133 int i = irq_nr >> 5;
134
135 if ((unsigned)irq_nr >= max_irqs)
136 return;
137
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000138 /* enable unmasked interrupts */
139 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
140
141 do {
142 /* make sure mask gets to controller before we
143 return to user */
144 mb();
145 } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
146 != (ppc_cached_irq_mask[i] & bit));
147
148 /*
149 * Unfortunately, setting the bit in the enable register
150 * when the device interrupt is already on *doesn't* set
151 * the bit in the flag register or request another interrupt.
152 */
153 if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000154 __pmac_retrigger(irq_nr);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000155}
156
157/* When an irq gets requested for the first client, if it's an
158 * edge interrupt, we clear any previous one on the controller
159 */
160static unsigned int pmac_startup_irq(unsigned int irq_nr)
161{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000162 unsigned long flags;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000163 unsigned long bit = 1UL << (irq_nr & 0x1f);
164 int i = irq_nr >> 5;
165
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000166 spin_lock_irqsave(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000167 if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
168 out_le32(&pmac_irq_hw[i]->ack, bit);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000169 __set_bit(irq_nr, ppc_cached_irq_mask);
170 __pmac_set_irq_mask(irq_nr, 0);
171 spin_unlock_irqrestore(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000172
173 return 0;
174}
175
176static void pmac_mask_irq(unsigned int irq_nr)
177{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000178 unsigned long flags;
179
180 spin_lock_irqsave(&pmac_pic_lock, flags);
181 __clear_bit(irq_nr, ppc_cached_irq_mask);
182 __pmac_set_irq_mask(irq_nr, 0);
183 spin_unlock_irqrestore(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000184}
185
186static void pmac_unmask_irq(unsigned int irq_nr)
187{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000188 unsigned long flags;
189
190 spin_lock_irqsave(&pmac_pic_lock, flags);
191 __set_bit(irq_nr, ppc_cached_irq_mask);
192 __pmac_set_irq_mask(irq_nr, 0);
193 spin_unlock_irqrestore(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000194}
195
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000196static int pmac_retrigger(unsigned int irq_nr)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000197{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000198 unsigned long flags;
199
200 spin_lock_irqsave(&pmac_pic_lock, flags);
201 __pmac_retrigger(irq_nr);
202 spin_unlock_irqrestore(&pmac_pic_lock, flags);
203 return 1;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000204}
205
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000206static struct irq_chip pmac_pic = {
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000207 .typename = " PMAC-PIC ",
208 .startup = pmac_startup_irq,
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000209 .mask = pmac_mask_irq,
210 .ack = pmac_ack_irq,
211 .mask_ack = pmac_mask_and_ack_irq,
212 .unmask = pmac_unmask_irq,
213 .retrigger = pmac_retrigger,
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000214};
215
216static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
217{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000218 unsigned long flags;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000219 int irq, bits;
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000220 int rc = IRQ_NONE;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000221
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000222 spin_lock_irqsave(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000223 for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
224 int i = irq >> 5;
225 bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
226 /* We must read level interrupts from the level register */
227 bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
228 bits &= ppc_cached_irq_mask[i];
229 if (bits == 0)
230 continue;
231 irq += __ilog2(bits);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000232 spin_unlock_irqrestore(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000233 __do_IRQ(irq, regs);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000234 spin_lock_irqsave(&pmac_pic_lock, flags);
235 rc = IRQ_HANDLED;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000236 }
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000237 spin_unlock_irqrestore(&pmac_pic_lock, flags);
238 return rc;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000239}
240
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100241static int pmac_get_irq(struct pt_regs *regs)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000242{
243 int irq;
244 unsigned long bits = 0;
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000245 unsigned long flags;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000246
247#ifdef CONFIG_SMP
248 void psurge_smp_message_recv(struct pt_regs *);
249
250 /* IPI's are a hack on the powersurge -- Cort */
251 if ( smp_processor_id() != 0 ) {
252 psurge_smp_message_recv(regs);
253 return -2; /* ignore, already handled */
254 }
255#endif /* CONFIG_SMP */
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000256 spin_lock_irqsave(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000257 for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
258 int i = irq >> 5;
259 bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
260 /* We must read level interrupts from the level register */
261 bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
262 bits &= ppc_cached_irq_mask[i];
263 if (bits == 0)
264 continue;
265 irq += __ilog2(bits);
266 break;
267 }
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000268 spin_unlock_irqrestore(&pmac_pic_lock, flags);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000269
270 return irq;
271}
272
273/* This routine will fix some missing interrupt values in the device tree
274 * on the gatwick mac-io controller used by some PowerBooks
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100275 *
276 * Walking of OF nodes could use a bit more fixing up here, but it's not
277 * very important as this is all boot time code on static portions of the
278 * device-tree.
279 *
280 * However, the modifications done to "intrs" will have to be removed and
281 * replaced with proper updates of the "interrupts" properties or
282 * AAPL,interrupts, yet to be decided, once the dynamic parsing is there.
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000283 */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100284static void __init pmac_fix_gatwick_interrupts(struct device_node *gw,
285 int irq_base)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000286{
287 struct device_node *node;
288 int count;
289
290 memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000291 count = 0;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100292 for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) {
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000293 /* Fix SCC */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100294 if ((strcasecmp(node->name, "escc") == 0) && node->child) {
295 if (node->child->n_intrs < 3) {
296 node->child->intrs = &gatwick_int_pool[count];
297 count += 3;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000298 }
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100299 node->child->n_intrs = 3;
300 node->child->intrs[0].line = 15+irq_base;
301 node->child->intrs[1].line = 4+irq_base;
302 node->child->intrs[2].line = 5+irq_base;
303 printk(KERN_INFO "irq: fixed SCC on gatwick"
304 " (%d,%d,%d)\n",
305 node->child->intrs[0].line,
306 node->child->intrs[1].line,
307 node->child->intrs[2].line);
308 }
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000309 /* Fix media-bay & left SWIM */
310 if (strcasecmp(node->name, "media-bay") == 0) {
311 struct device_node* ya_node;
312
313 if (node->n_intrs == 0)
314 node->intrs = &gatwick_int_pool[count++];
315 node->n_intrs = 1;
316 node->intrs[0].line = 29+irq_base;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100317 printk(KERN_INFO "irq: fixed media-bay on gatwick"
318 " (%d)\n", node->intrs[0].line);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000319
320 ya_node = node->child;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100321 while(ya_node) {
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000322 if (strcasecmp(ya_node->name, "floppy") == 0) {
323 if (ya_node->n_intrs < 2) {
324 ya_node->intrs = &gatwick_int_pool[count];
325 count += 2;
326 }
327 ya_node->n_intrs = 2;
328 ya_node->intrs[0].line = 19+irq_base;
329 ya_node->intrs[1].line = 1+irq_base;
330 printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
331 ya_node->intrs[0].line, ya_node->intrs[1].line);
332 }
333 if (strcasecmp(ya_node->name, "ata4") == 0) {
334 if (ya_node->n_intrs < 2) {
335 ya_node->intrs = &gatwick_int_pool[count];
336 count += 2;
337 }
338 ya_node->n_intrs = 2;
339 ya_node->intrs[0].line = 14+irq_base;
340 ya_node->intrs[1].line = 3+irq_base;
341 printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
342 ya_node->intrs[0].line, ya_node->intrs[1].line);
343 }
344 ya_node = ya_node->sibling;
345 }
346 }
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000347 }
348 if (count > 10) {
349 printk("WARNING !! Gatwick interrupt pool overflow\n");
350 printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
351 printk(" requested = %d\n", count);
352 }
353}
354
355/*
356 * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
357 * card which includes an ohare chip that acts as a second interrupt
358 * controller. If we find this second ohare, set it up and fix the
359 * interrupt value in the device tree for the ethernet chip.
360 */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100361static void __init enable_second_ohare(struct device_node *np)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000362{
363 unsigned char bus, devfn;
364 unsigned short cmd;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000365 struct device_node *ether;
366
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100367 /* This code doesn't strictly belong here, it could be part of
368 * either the PCI initialisation or the feature code. It's kept
369 * here for historical reasons.
370 */
371 if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
372 struct pci_controller* hose =
373 pci_find_hose_for_OF_device(np);
374 if (!hose) {
375 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
376 return;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000377 }
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100378 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
379 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
380 cmd &= ~PCI_COMMAND_IO;
381 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000382 }
383
384 /* Fix interrupt for the modem/ethernet combo controller. The number
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100385 * in the device tree (27) is bogus (correct for the ethernet-only
386 * board but not the combo ethernet/modem board).
387 * The real interrupt is 28 on the second controller -> 28+32 = 60.
388 */
389 ether = of_find_node_by_name(NULL, "pci1011,14");
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000390 if (ether && ether->n_intrs > 0) {
391 ether->intrs[0].line = 60;
392 printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
393 ether->intrs[0].line);
394 }
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100395 of_node_put(ether);
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000396}
397
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000398#ifdef CONFIG_XMON
399static struct irqaction xmon_action = {
400 .handler = xmon_irq,
401 .flags = 0,
402 .mask = CPU_MASK_NONE,
403 .name = "NMI - XMON"
404};
405#endif
406
407static struct irqaction gatwick_cascade_action = {
408 .handler = gatwick_action,
Thomas Gleixner67144652006-07-01 19:29:22 -0700409 .flags = IRQF_DISABLED,
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000410 .mask = CPU_MASK_NONE,
411 .name = "cascade",
412};
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100413
414static void __init pmac_pic_probe_oldstyle(void)
415{
416 int i;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100417 struct device_node *master = NULL;
418 struct device_node *slave = NULL;
419 u8 __iomem *addr;
420 struct resource r;
421
422 /* Set our get_irq function */
423 ppc_md.get_irq = pmac_get_irq;
424
425 /*
426 * Find the interrupt controller type & node
427 */
428
429 if ((master = of_find_node_by_name(NULL, "gc")) != NULL) {
430 max_irqs = max_real_irqs = 32;
431 level_mask[0] = GC_LEVEL_MASK;
432 } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) {
433 max_irqs = max_real_irqs = 32;
434 level_mask[0] = OHARE_LEVEL_MASK;
435
436 /* We might have a second cascaded ohare */
437 slave = of_find_node_by_name(NULL, "pci106b,7");
438 if (slave) {
439 max_irqs = 64;
440 level_mask[1] = OHARE_LEVEL_MASK;
441 enable_second_ohare(slave);
442 }
443 } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
444 max_irqs = max_real_irqs = 64;
445 level_mask[0] = HEATHROW_LEVEL_MASK;
446 level_mask[1] = 0;
447
448 /* We might have a second cascaded heathrow */
449 slave = of_find_node_by_name(master, "mac-io");
450
451 /* Check ordering of master & slave */
452 if (device_is_compatible(master, "gatwick")) {
453 struct device_node *tmp;
454 BUG_ON(slave == NULL);
455 tmp = master;
456 master = slave;
457 slave = tmp;
458 }
459
460 /* We found a slave */
461 if (slave) {
462 max_irqs = 128;
463 level_mask[2] = HEATHROW_LEVEL_MASK;
464 level_mask[3] = 0;
465 pmac_fix_gatwick_interrupts(slave, max_real_irqs);
466 }
467 }
468 BUG_ON(master == NULL);
469
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000470 /* Mark level interrupts and set handlers */
471 for (i = 0; i < max_irqs; i++) {
472 int level = !!(level_mask[i >> 5] & (1UL << (i & 0x1f)));
473 if (level)
474 irq_desc[i].status |= IRQ_LEVEL;
475 else
476 irq_desc[i].status |= IRQ_DELAYED_DISABLE;
477 set_irq_chip_and_handler(i, &pmac_pic, level ?
478 handle_level_irq : handle_edge_irq);
479 }
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100480
481 /* Get addresses of first controller if we have a node for it */
482 BUG_ON(of_address_to_resource(master, 0, &r));
483
484 /* Map interrupts of primary controller */
485 addr = (u8 __iomem *) ioremap(r.start, 0x40);
486 i = 0;
487 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
488 (addr + 0x20);
489 if (max_real_irqs > 32)
490 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
491 (addr + 0x10);
492 of_node_put(master);
493
494 printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n",
495 master->full_name, max_real_irqs);
496
497 /* Map interrupts of cascaded controller */
498 if (slave && !of_address_to_resource(slave, 0, &r)) {
499 addr = (u8 __iomem *)ioremap(r.start, 0x40);
500 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
501 (addr + 0x20);
502 if (max_irqs > 64)
503 pmac_irq_hw[i++] =
504 (volatile struct pmac_irq_hw __iomem *)
505 (addr + 0x10);
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000506 pmac_irq_cascade = slave->intrs[0].line;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100507
508 printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
509 " cascade: %d\n", slave->full_name,
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000510 max_irqs - max_real_irqs, pmac_irq_cascade);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100511 }
512 of_node_put(slave);
513
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000514 /* Disable all interrupts in all controllers */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100515 for (i = 0; i * 32 < max_irqs; ++i)
516 out_le32(&pmac_irq_hw[i]->enable, 0);
517
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000518 /* Hookup cascade irq */
519 if (slave)
520 setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100521
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100522 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
523#ifdef CONFIG_XMON
524 setup_irq(20, &xmon_action);
525#endif
526}
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000527#endif /* CONFIG_PPC32 */
528
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000529static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc,
530 struct pt_regs *regs)
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000531{
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000532 struct mpic *mpic = desc->handler_data;
533 unsigned int max = 100;
534
535 while(max--) {
536 int cascade_irq = mpic_get_one_irq(mpic, regs);
537 if (max == 99)
538 desc->chip->eoi(irq);
539 if (irq < 0)
540 break;
541 generic_handle_irq(cascade_irq, regs);
542 };
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000543}
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000544
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100545static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
546{
547#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
548 struct device_node* pswitch;
549 int nmi_irq;
550
551 pswitch = of_find_node_by_name(NULL, "programmer-switch");
552 if (pswitch && pswitch->n_intrs) {
553 nmi_irq = pswitch->intrs[0].line;
554 mpic_irq_set_priority(nmi_irq, 9);
555 setup_irq(nmi_irq, &xmon_action);
556 }
557 of_node_put(pswitch);
558#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
559}
560
Benjamin Herrenschmidt1beb6a72005-12-14 13:10:10 +1100561static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
562 int master)
563{
564 unsigned char senses[128];
565 int offset = master ? 0 : 128;
566 int count = master ? 128 : 124;
567 const char *name = master ? " MPIC 1 " : " MPIC 2 ";
568 struct resource r;
569 struct mpic *mpic;
570 unsigned int flags = master ? MPIC_PRIMARY : 0;
571 int rc;
572
573 rc = of_address_to_resource(np, 0, &r);
574 if (rc)
575 return NULL;
576
577 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);
578
579 prom_get_irq_senses(senses, offset, offset + count);
580
581 flags |= MPIC_WANTS_RESET;
582 if (get_property(np, "big-endian", NULL))
583 flags |= MPIC_BIG_ENDIAN;
584
585 /* Primary Big Endian means HT interrupts. This is quite dodgy
586 * but works until I find a better way
587 */
588 if (master && (flags & MPIC_BIG_ENDIAN))
589 flags |= MPIC_BROKEN_U3;
590
591 mpic = mpic_alloc(r.start, flags, 0, offset, count, master ? 252 : 0,
592 senses, count, name);
593 if (mpic == NULL)
594 return NULL;
595
596 mpic_init(mpic);
597
598 return mpic;
599 }
600
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100601static int __init pmac_pic_probe_mpic(void)
602{
603 struct mpic *mpic1, *mpic2;
604 struct device_node *np, *master = NULL, *slave = NULL;
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100605
606 /* We can have up to 2 MPICs cascaded */
607 for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))
608 != NULL;) {
609 if (master == NULL &&
Benjamin Herrenschmidt1beb6a72005-12-14 13:10:10 +1100610 get_property(np, "interrupts", NULL) == NULL)
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100611 master = of_node_get(np);
612 else if (slave == NULL)
613 slave = of_node_get(np);
614 if (master && slave)
615 break;
616 }
617
618 /* Check for bogus setups */
619 if (master == NULL && slave != NULL) {
620 master = slave;
621 slave = NULL;
622 }
623
624 /* Not found, default to good old pmac pic */
625 if (master == NULL)
626 return -ENODEV;
627
628 /* Set master handler */
629 ppc_md.get_irq = mpic_get_irq;
630
631 /* Setup master */
Benjamin Herrenschmidt1beb6a72005-12-14 13:10:10 +1100632 mpic1 = pmac_setup_one_mpic(master, 1);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100633 BUG_ON(mpic1 == NULL);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100634
635 /* Install NMI if any */
636 pmac_pic_setup_mpic_nmi(mpic1);
637
638 of_node_put(master);
639
640 /* No slave, let's go out */
641 if (slave == NULL || slave->n_intrs < 1)
642 return 0;
643
Benjamin Herrenschmidt1beb6a72005-12-14 13:10:10 +1100644 mpic2 = pmac_setup_one_mpic(slave, 0);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100645 if (mpic2 == NULL) {
Benjamin Herrenschmidt1beb6a72005-12-14 13:10:10 +1100646 printk(KERN_ERR "Failed to setup slave MPIC\n");
647 of_node_put(slave);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100648 return 0;
649 }
Benjamin Herrenschmidtb9e5b4e2006-07-03 19:32:51 +1000650 set_irq_data(slave->intrs[0].line, mpic2);
651 set_irq_chained_handler(slave->intrs[0].line, pmac_u3_cascade);
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100652
653 of_node_put(slave);
654 return 0;
655}
656
657
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000658void __init pmac_pic_init(void)
659{
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000660 /* We first try to detect Apple's new Core99 chipset, since mac-io
661 * is quite different on those machines and contains an IBM MPIC2.
662 */
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100663 if (pmac_pic_probe_mpic() == 0)
Paul Mackerras20c8c212005-09-28 20:28:14 +1000664 return;
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000665
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000666#ifdef CONFIG_PPC32
Benjamin Herrenschmidtcc5d0182005-12-13 18:01:21 +1100667 pmac_pic_probe_oldstyle();
668#endif
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000669}
670
Paul Mackerrasa0005032005-11-02 15:08:17 +1100671#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000672/*
673 * These procedures are used in implementing sleep on the powerbooks.
674 * sleep_save_intrs() saves the states of all interrupt enables
675 * and disables all interrupts except for the nominated one.
676 * sleep_restore_intrs() restores the states of all interrupt enables.
677 */
678unsigned long sleep_save_mask[2];
679
680/* This used to be passed by the PMU driver but that link got
681 * broken with the new driver model. We use this tweak for now...
682 */
683static int pmacpic_find_viaint(void)
684{
685 int viaint = -1;
686
687#ifdef CONFIG_ADB_PMU
688 struct device_node *np;
689
690 if (pmu_get_model() != PMU_OHARE_BASED)
691 goto not_found;
692 np = of_find_node_by_name(NULL, "via-pmu");
693 if (np == NULL)
694 goto not_found;
695 viaint = np->intrs[0].line;
696#endif /* CONFIG_ADB_PMU */
697
698not_found:
699 return viaint;
700}
701
702static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
703{
704 int viaint = pmacpic_find_viaint();
705
706 sleep_save_mask[0] = ppc_cached_irq_mask[0];
707 sleep_save_mask[1] = ppc_cached_irq_mask[1];
708 ppc_cached_irq_mask[0] = 0;
709 ppc_cached_irq_mask[1] = 0;
710 if (viaint > 0)
711 set_bit(viaint, ppc_cached_irq_mask);
712 out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
713 if (max_real_irqs > 32)
714 out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
715 (void)in_le32(&pmac_irq_hw[0]->event);
716 /* make sure mask gets to controller before we return to caller */
717 mb();
718 (void)in_le32(&pmac_irq_hw[0]->enable);
719
720 return 0;
721}
722
723static int pmacpic_resume(struct sys_device *sysdev)
724{
725 int i;
726
727 out_le32(&pmac_irq_hw[0]->enable, 0);
728 if (max_real_irqs > 32)
729 out_le32(&pmac_irq_hw[1]->enable, 0);
730 mb();
731 for (i = 0; i < max_real_irqs; ++i)
732 if (test_bit(i, sleep_save_mask))
733 pmac_unmask_irq(i);
734
735 return 0;
736}
737
Paul Mackerrasa0005032005-11-02 15:08:17 +1100738#endif /* CONFIG_PM && CONFIG_PPC32 */
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000739
740static struct sysdev_class pmacpic_sysclass = {
741 set_kset_name("pmac_pic"),
742};
743
744static struct sys_device device_pmacpic = {
745 .id = 0,
746 .cls = &pmacpic_sysclass,
747};
748
749static struct sysdev_driver driver_pmacpic = {
Paul Mackerrasa0005032005-11-02 15:08:17 +1100750#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000751 .suspend = &pmacpic_suspend,
752 .resume = &pmacpic_resume,
Paul Mackerrasa0005032005-11-02 15:08:17 +1100753#endif /* CONFIG_PM && CONFIG_PPC32 */
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000754};
755
756static int __init init_pmacpic_sysfs(void)
757{
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000758#ifdef CONFIG_PPC32
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000759 if (max_irqs == 0)
760 return -ENODEV;
Paul Mackerras3c3f42d2005-10-10 22:58:41 +1000761#endif
Paul Mackerras14cf11a2005-09-26 16:04:21 +1000762 printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
763 sysdev_class_register(&pmacpic_sysclass);
764 sysdev_register(&device_pmacpic);
765 sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
766 return 0;
767}
768
769subsys_initcall(init_pmacpic_sysfs);
770