aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-03 07:36:01 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-03 07:36:01 -0400
commit0ebfff1491ef85d41ddf9c633834838be144f69f (patch)
tree5b469a6d61a9fcfbf94e7b6d411e544dbdec8dec /drivers/macintosh
parentf63e115fb50db39706b955b81e3375ef6bab2268 (diff)
[POWERPC] Add new interrupt mapping core and change platforms to use it
This adds the new irq remapper core and removes the old one. Because there are some fundamental conflicts with the old code, like the value of NO_IRQ which I'm now setting to 0 (as per discussions with Linus), etc..., this commit also changes the relevant platform and driver code over to use the new remapper (so as not to cause difficulties later in bisecting). This patch removes the old pre-parsing of the open firmware interrupt tree along with all the bogus assumptions it made to try to renumber interrupts according to the platform. This is all to be handled by the new code now. For the pSeries XICS interrupt controller, a single remapper host is created for the whole machine regardless of how many interrupt presentation and source controllers are found, and it's set to match any device node that isn't a 8259. That works fine on pSeries and avoids having to deal with some of the complexities of split source controllers vs. presentation controllers in the pSeries device trees. The powerpc i8259 PIC driver now always requests the legacy interrupt range. It also has the feature of being able to match any device node (including NULL) if passed no device node as an input. That will help porting over platforms with broken device-trees like Pegasos who don't have a proper interrupt tree. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/macio-adb.c19
-rw-r--r--drivers/macintosh/macio_asic.c152
-rw-r--r--drivers/macintosh/smu.c6
-rw-r--r--drivers/macintosh/via-cuda.c24
-rw-r--r--drivers/macintosh/via-pmu.c33
5 files changed, 138 insertions, 96 deletions
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index 314fc0830d90..4b08852c35ee 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -90,22 +90,12 @@ int macio_init(void)
90{ 90{
91 struct device_node *adbs; 91 struct device_node *adbs;
92 struct resource r; 92 struct resource r;
93 unsigned int irq;
93 94
94 adbs = find_compatible_devices("adb", "chrp,adb0"); 95 adbs = find_compatible_devices("adb", "chrp,adb0");
95 if (adbs == 0) 96 if (adbs == 0)
96 return -ENXIO; 97 return -ENXIO;
97 98
98#if 0
99 { int i = 0;
100
101 printk("macio_adb_init: node = %p, addrs =", adbs->node);
102 while(!of_address_to_resource(adbs, i, &r))
103 printk(" %x(%x)", r.start, r.end - r.start);
104 printk(", intrs =");
105 for (i = 0; i < adbs->n_intrs; ++i)
106 printk(" %x", adbs->intrs[i].line);
107 printk("\n"); }
108#endif
109 if (of_address_to_resource(adbs, 0, &r)) 99 if (of_address_to_resource(adbs, 0, &r))
110 return -ENXIO; 100 return -ENXIO;
111 adb = ioremap(r.start, sizeof(struct adb_regs)); 101 adb = ioremap(r.start, sizeof(struct adb_regs));
@@ -117,10 +107,9 @@ int macio_init(void)
117 out_8(&adb->active_lo.r, 0xff); 107 out_8(&adb->active_lo.r, 0xff);
118 out_8(&adb->autopoll.r, APE); 108 out_8(&adb->autopoll.r, APE);
119 109
120 if (request_irq(adbs->intrs[0].line, macio_adb_interrupt, 110 irq = irq_of_parse_and_map(adbs, 0);
121 0, "ADB", (void *)0)) { 111 if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) {
122 printk(KERN_ERR "ADB: can't get irq %d\n", 112 printk(KERN_ERR "ADB: can't get irq %d\n", irq);
123 adbs->intrs[0].line);
124 return -EAGAIN; 113 return -EAGAIN;
125 } 114 }
126 out_8(&adb->intr_enb.r, DFB | TAG); 115 out_8(&adb->intr_enb.r, DFB | TAG);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 40ae7b6a939d..80c0c665b5f6 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -280,75 +280,128 @@ static void macio_release_dev(struct device *dev)
280static int macio_resource_quirks(struct device_node *np, struct resource *res, 280static int macio_resource_quirks(struct device_node *np, struct resource *res,
281 int index) 281 int index)
282{ 282{
283 if (res->flags & IORESOURCE_MEM) { 283 /* Only quirks for memory resources for now */
284 /* Grand Central has too large resource 0 on some machines */ 284 if ((res->flags & IORESOURCE_MEM) == 0)
285 if (index == 0 && !strcmp(np->name, "gc")) 285 return 0;
286 res->end = res->start + 0x1ffff; 286
287 /* Grand Central has too large resource 0 on some machines */
288 if (index == 0 && !strcmp(np->name, "gc"))
289 res->end = res->start + 0x1ffff;
287 290
288 /* Airport has bogus resource 2 */ 291 /* Airport has bogus resource 2 */
289 if (index >= 2 && !strcmp(np->name, "radio")) 292 if (index >= 2 && !strcmp(np->name, "radio"))
290 return 1; 293 return 1;
291 294
292#ifndef CONFIG_PPC64 295#ifndef CONFIG_PPC64
293 /* DBDMAs may have bogus sizes */ 296 /* DBDMAs may have bogus sizes */
294 if ((res->start & 0x0001f000) == 0x00008000) 297 if ((res->start & 0x0001f000) == 0x00008000)
295 res->end = res->start + 0xff; 298 res->end = res->start + 0xff;
296#endif /* CONFIG_PPC64 */ 299#endif /* CONFIG_PPC64 */
297 300
298 /* ESCC parent eats child resources. We could have added a 301 /* ESCC parent eats child resources. We could have added a
299 * level of hierarchy, but I don't really feel the need 302 * level of hierarchy, but I don't really feel the need
300 * for it 303 * for it
301 */ 304 */
302 if (!strcmp(np->name, "escc")) 305 if (!strcmp(np->name, "escc"))
303 return 1; 306 return 1;
304 307
305 /* ESCC has bogus resources >= 3 */ 308 /* ESCC has bogus resources >= 3 */
306 if (index >= 3 && !(strcmp(np->name, "ch-a") && 309 if (index >= 3 && !(strcmp(np->name, "ch-a") &&
307 strcmp(np->name, "ch-b"))) 310 strcmp(np->name, "ch-b")))
308 return 1; 311 return 1;
309 312
310 /* Media bay has too many resources, keep only first one */ 313 /* Media bay has too many resources, keep only first one */
311 if (index > 0 && !strcmp(np->name, "media-bay")) 314 if (index > 0 && !strcmp(np->name, "media-bay"))
312 return 1; 315 return 1;
313 316
314 /* Some older IDE resources have bogus sizes */ 317 /* Some older IDE resources have bogus sizes */
315 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && 318 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
316 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { 319 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
317 if (index == 0 && (res->end - res->start) > 0xfff) 320 if (index == 0 && (res->end - res->start) > 0xfff)
318 res->end = res->start + 0xfff; 321 res->end = res->start + 0xfff;
319 if (index == 1 && (res->end - res->start) > 0xff) 322 if (index == 1 && (res->end - res->start) > 0xff)
320 res->end = res->start + 0xff; 323 res->end = res->start + 0xff;
321 }
322 } 324 }
323 return 0; 325 return 0;
324} 326}
325 327
328static void macio_create_fixup_irq(struct macio_dev *dev, int index,
329 unsigned int line)
330{
331 unsigned int irq;
326 332
327static void macio_setup_interrupts(struct macio_dev *dev) 333 irq = irq_create_mapping(NULL, line, 0);
334 if (irq != NO_IRQ) {
335 dev->interrupt[index].start = irq;
336 dev->interrupt[index].flags = IORESOURCE_IRQ;
337 dev->interrupt[index].name = dev->ofdev.dev.bus_id;
338 }
339 if (dev->n_interrupts <= index)
340 dev->n_interrupts = index + 1;
341}
342
343static void macio_add_missing_resources(struct macio_dev *dev)
328{ 344{
329 struct device_node *np = dev->ofdev.node; 345 struct device_node *np = dev->ofdev.node;
330 int i,j; 346 unsigned int irq_base;
347
348 /* Gatwick has some missing interrupts on child nodes */
349 if (dev->bus->chip->type != macio_gatwick)
350 return;
331 351
332 /* For now, we use pre-parsed entries in the device-tree for 352 /* irq_base is always 64 on gatwick. I have no cleaner way to get
333 * interrupt routing and addresses, but we should change that 353 * that value from here at this point
334 * to dynamically parsed entries and so get rid of most of the
335 * clutter in struct device_node
336 */ 354 */
337 for (i = j = 0; i < np->n_intrs; i++) { 355 irq_base = 64;
356
357 /* Fix SCC */
358 if (strcmp(np->name, "ch-a") == 0) {
359 macio_create_fixup_irq(dev, 0, 15 + irq_base);
360 macio_create_fixup_irq(dev, 1, 4 + irq_base);
361 macio_create_fixup_irq(dev, 2, 5 + irq_base);
362 printk(KERN_INFO "macio: fixed SCC irqs on gatwick\n");
363 }
364
365 /* Fix media-bay */
366 if (strcmp(np->name, "media-bay") == 0) {
367 macio_create_fixup_irq(dev, 0, 29 + irq_base);
368 printk(KERN_INFO "macio: fixed media-bay irq on gatwick\n");
369 }
370
371 /* Fix left media bay childs */
372 if (dev->media_bay != NULL && strcmp(np->name, "floppy") == 0) {
373 macio_create_fixup_irq(dev, 0, 19 + irq_base);
374 macio_create_fixup_irq(dev, 1, 1 + irq_base);
375 printk(KERN_INFO "macio: fixed left floppy irqs\n");
376 }
377 if (dev->media_bay != NULL && strcasecmp(np->name, "ata4") == 0) {
378 macio_create_fixup_irq(dev, 0, 14 + irq_base);
379 macio_create_fixup_irq(dev, 0, 3 + irq_base);
380 printk(KERN_INFO "macio: fixed left ide irqs\n");
381 }
382}
383
384static void macio_setup_interrupts(struct macio_dev *dev)
385{
386 struct device_node *np = dev->ofdev.node;
387 unsigned int irq;
388 int i = 0, j = 0;
389
390 for (;;) {
338 struct resource *res = &dev->interrupt[j]; 391 struct resource *res = &dev->interrupt[j];
339 392
340 if (j >= MACIO_DEV_COUNT_IRQS) 393 if (j >= MACIO_DEV_COUNT_IRQS)
341 break; 394 break;
342 res->start = np->intrs[i].line; 395 irq = irq_of_parse_and_map(np, i++);
343 res->flags = IORESOURCE_IO; 396 if (irq == NO_IRQ)
344 if (np->intrs[j].sense) 397 break;
345 res->flags |= IORESOURCE_IRQ_LOWLEVEL; 398 res->start = irq;
346 else 399 res->flags = IORESOURCE_IRQ;
347 res->flags |= IORESOURCE_IRQ_HIGHEDGE;
348 res->name = dev->ofdev.dev.bus_id; 400 res->name = dev->ofdev.dev.bus_id;
349 if (macio_resource_quirks(np, res, i)) 401 if (macio_resource_quirks(np, res, i - 1)) {
350 memset(res, 0, sizeof(struct resource)); 402 memset(res, 0, sizeof(struct resource));
351 else 403 continue;
404 } else
352 j++; 405 j++;
353 } 406 }
354 dev->n_interrupts = j; 407 dev->n_interrupts = j;
@@ -445,6 +498,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
445 /* Setup interrupts & resources */ 498 /* Setup interrupts & resources */
446 macio_setup_interrupts(dev); 499 macio_setup_interrupts(dev);
447 macio_setup_resources(dev, parent_res); 500 macio_setup_resources(dev, parent_res);
501 macio_add_missing_resources(dev);
448 502
449 /* Register with core */ 503 /* Register with core */
450 if (of_device_register(&dev->ofdev) != 0) { 504 if (of_device_register(&dev->ofdev) != 0) {
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index ff6d9bfdc3d2..f139a74696fe 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -497,8 +497,7 @@ int __init smu_init (void)
497 smu->doorbell = *data; 497 smu->doorbell = *data;
498 if (smu->doorbell < 0x50) 498 if (smu->doorbell < 0x50)
499 smu->doorbell += 0x50; 499 smu->doorbell += 0x50;
500 if (np->n_intrs > 0) 500 smu->db_irq = irq_of_parse_and_map(np, 0);
501 smu->db_irq = np->intrs[0].line;
502 501
503 of_node_put(np); 502 of_node_put(np);
504 503
@@ -515,8 +514,7 @@ int __init smu_init (void)
515 smu->msg = *data; 514 smu->msg = *data;
516 if (smu->msg < 0x50) 515 if (smu->msg < 0x50)
517 smu->msg += 0x50; 516 smu->msg += 0x50;
518 if (np->n_intrs > 0) 517 smu->msg_irq = irq_of_parse_and_map(np, 0);
519 smu->msg_irq = np->intrs[0].line;
520 of_node_put(np); 518 of_node_put(np);
521 } while(0); 519 } while(0);
522 520
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 6501db50fb83..69d5452fd22f 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -34,13 +34,6 @@
34static volatile unsigned char __iomem *via; 34static volatile unsigned char __iomem *via;
35static DEFINE_SPINLOCK(cuda_lock); 35static DEFINE_SPINLOCK(cuda_lock);
36 36
37#ifdef CONFIG_MAC
38#define CUDA_IRQ IRQ_MAC_ADB
39#define eieio()
40#else
41#define CUDA_IRQ vias->intrs[0].line
42#endif
43
44/* VIA registers - spaced 0x200 bytes apart */ 37/* VIA registers - spaced 0x200 bytes apart */
45#define RS 0x200 /* skip between registers */ 38#define RS 0x200 /* skip between registers */
46#define B 0 /* B-side data */ 39#define B 0 /* B-side data */
@@ -189,11 +182,24 @@ int __init find_via_cuda(void)
189 182
190static int __init via_cuda_start(void) 183static int __init via_cuda_start(void)
191{ 184{
185 unsigned int irq;
186
192 if (via == NULL) 187 if (via == NULL)
193 return -ENODEV; 188 return -ENODEV;
194 189
195 if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { 190#ifdef CONFIG_MAC
196 printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); 191 irq = IRQ_MAC_ADB;
192#else /* CONFIG_MAC */
193 irq = irq_of_parse_and_map(vias, 0);
194 if (irq == NO_IRQ) {
195 printk(KERN_ERR "via-cuda: can't map interrupts for %s\n",
196 vias->full_name);
197 return -ENODEV;
198 }
199#endif /* CONFIG_MAP */
200
201 if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
202 printk(KERN_ERR "via-cuda: can't request irq %d\n", irq);
197 return -EAGAIN; 203 return -EAGAIN;
198 } 204 }
199 205
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index c1193d34ec9e..06ca80bfd6b9 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -64,10 +64,6 @@
64#include <asm/backlight.h> 64#include <asm/backlight.h>
65#endif 65#endif
66 66
67#ifdef CONFIG_PPC32
68#include <asm/open_pic.h>
69#endif
70
71#include "via-pmu-event.h" 67#include "via-pmu-event.h"
72 68
73/* Some compile options */ 69/* Some compile options */
@@ -151,7 +147,7 @@ static int pmu_fully_inited = 0;
151static int pmu_has_adb; 147static int pmu_has_adb;
152static struct device_node *gpio_node; 148static struct device_node *gpio_node;
153static unsigned char __iomem *gpio_reg = NULL; 149static unsigned char __iomem *gpio_reg = NULL;
154static int gpio_irq = -1; 150static int gpio_irq = NO_IRQ;
155static int gpio_irq_enabled = -1; 151static int gpio_irq_enabled = -1;
156static volatile int pmu_suspended = 0; 152static volatile int pmu_suspended = 0;
157static spinlock_t pmu_lock; 153static spinlock_t pmu_lock;
@@ -403,22 +399,21 @@ static int __init pmu_init(void)
403 */ 399 */
404static int __init via_pmu_start(void) 400static int __init via_pmu_start(void)
405{ 401{
402 unsigned int irq;
403
406 if (vias == NULL) 404 if (vias == NULL)
407 return -ENODEV; 405 return -ENODEV;
408 406
409 batt_req.complete = 1; 407 batt_req.complete = 1;
410 408
411#ifndef CONFIG_PPC_MERGE 409 irq = irq_of_parse_and_map(vias, 0);
412 if (pmu_kind == PMU_KEYLARGO_BASED) 410 if (irq == NO_IRQ) {
413 openpic_set_irq_priority(vias->intrs[0].line, 411 printk(KERN_ERR "via-pmu: can't map interruptn");
414 OPENPIC_PRIORITY_DEFAULT + 1); 412 return -ENODEV;
415#endif 413 }
416 414 if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) {
417 if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU", 415 printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
418 (void *)0)) { 416 return -ENODEV;
419 printk(KERN_ERR "VIA-PMU: can't get irq %d\n",
420 vias->intrs[0].line);
421 return -EAGAIN;
422 } 417 }
423 418
424 if (pmu_kind == PMU_KEYLARGO_BASED) { 419 if (pmu_kind == PMU_KEYLARGO_BASED) {
@@ -426,10 +421,10 @@ static int __init via_pmu_start(void)
426 if (gpio_node == NULL) 421 if (gpio_node == NULL)
427 gpio_node = of_find_node_by_name(NULL, 422 gpio_node = of_find_node_by_name(NULL,
428 "pmu-interrupt"); 423 "pmu-interrupt");
429 if (gpio_node && gpio_node->n_intrs > 0) 424 if (gpio_node)
430 gpio_irq = gpio_node->intrs[0].line; 425 gpio_irq = irq_of_parse_and_map(gpio_node, 0);
431 426
432 if (gpio_irq != -1) { 427 if (gpio_irq != NO_IRQ) {
433 if (request_irq(gpio_irq, gpio1_interrupt, 0, 428 if (request_irq(gpio_irq, gpio1_interrupt, 0,
434 "GPIO1 ADB", (void *)0)) 429 "GPIO1 ADB", (void *)0))
435 printk(KERN_ERR "pmu: can't get irq %d" 430 printk(KERN_ERR "pmu: can't get irq %d"