aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-12-13 21:10:10 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:03:17 -0500
commit1beb6a7d6cbed3ac03500ce9b5b9bb632c512039 (patch)
tree727aa76da5a82fca449dadf3cebbadc414ad6555 /arch/powerpc/kernel/prom.c
parentcd0c7f06803be06a5cf4564aa5a900f4b6aea603 (diff)
[PATCH] powerpc: Experimental support for new G5 Macs (#2)
This adds some very basic support for the new machines, including the Quad G5 (tested), and other new dual core based machines and iMac G5 iSight (untested). This is still experimental ! There is no thermal control yet, there is no proper handing of MSIs, etc.. but it boots, I have all 4 cores up on my machine. Compared to the previous version of this patch, this one adds DART IOMMU support for the U4 chipset and thus should work fine on setups with more than 2Gb of RAM. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 1b97e13657e5..977ee3adaf2d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -298,6 +298,16 @@ static int __devinit finish_node_interrupts(struct device_node *np,
298 int i, j, n, sense; 298 int i, j, n, sense;
299 unsigned int *irq, virq; 299 unsigned int *irq, virq;
300 struct device_node *ic; 300 struct device_node *ic;
301 int trace = 0;
302
303 //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0)
304#define TRACE(fmt...)
305
306 if (!strcmp(np->name, "smu-doorbell"))
307 trace = 1;
308
309 TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n",
310 num_interrupt_controllers);
301 311
302 if (num_interrupt_controllers == 0) { 312 if (num_interrupt_controllers == 0) {
303 /* 313 /*
@@ -332,11 +342,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
332 } 342 }
333 343
334 ints = (unsigned int *) get_property(np, "interrupts", &intlen); 344 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
345 TRACE("ints=%p, intlen=%d\n", ints, intlen);
335 if (ints == NULL) 346 if (ints == NULL)
336 return 0; 347 return 0;
337 intrcells = prom_n_intr_cells(np); 348 intrcells = prom_n_intr_cells(np);
338 intlen /= intrcells * sizeof(unsigned int); 349 intlen /= intrcells * sizeof(unsigned int);
339 350 TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen);
340 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); 351 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
341 if (!np->intrs) 352 if (!np->intrs)
342 return -ENOMEM; 353 return -ENOMEM;
@@ -347,6 +358,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
347 intrcount = 0; 358 intrcount = 0;
348 for (i = 0; i < intlen; ++i, ints += intrcells) { 359 for (i = 0; i < intlen; ++i, ints += intrcells) {
349 n = map_interrupt(&irq, &ic, np, ints, intrcells); 360 n = map_interrupt(&irq, &ic, np, ints, intrcells);
361 TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n);
350 if (n <= 0) 362 if (n <= 0)
351 continue; 363 continue;
352 364
@@ -357,6 +369,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
357 np->intrs[intrcount].sense = map_isa_senses[sense]; 369 np->intrs[intrcount].sense = map_isa_senses[sense];
358 } else { 370 } else {
359 virq = virt_irq_create_mapping(irq[0]); 371 virq = virt_irq_create_mapping(irq[0]);
372 TRACE("virq=%d\n", virq);
360#ifdef CONFIG_PPC64 373#ifdef CONFIG_PPC64
361 if (virq == NO_IRQ) { 374 if (virq == NO_IRQ) {
362 printk(KERN_CRIT "Could not allocate interrupt" 375 printk(KERN_CRIT "Could not allocate interrupt"
@@ -366,6 +379,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
366#endif 379#endif
367 np->intrs[intrcount].line = irq_offset_up(virq); 380 np->intrs[intrcount].line = irq_offset_up(virq);
368 sense = (n > 1)? (irq[1] & 3): 1; 381 sense = (n > 1)? (irq[1] & 3): 1;
382
383 /* Apple uses bits in there in a different way, let's
384 * only keep the real sense bit on macs
385 */
386 if (_machine == PLATFORM_POWERMAC)
387 sense &= 0x1;
369 np->intrs[intrcount].sense = map_mpic_senses[sense]; 388 np->intrs[intrcount].sense = map_mpic_senses[sense];
370 } 389 }
371 390
@@ -375,12 +394,13 @@ static int __devinit finish_node_interrupts(struct device_node *np,
375 char *name = get_property(ic->parent, "name", NULL); 394 char *name = get_property(ic->parent, "name", NULL);
376 if (name && !strcmp(name, "u3")) 395 if (name && !strcmp(name, "u3"))
377 np->intrs[intrcount].line += 128; 396 np->intrs[intrcount].line += 128;
378 else if (!(name && !strcmp(name, "mac-io"))) 397 else if (!(name && (!strcmp(name, "mac-io") ||
398 !strcmp(name, "u4"))))
379 /* ignore other cascaded controllers, such as 399 /* ignore other cascaded controllers, such as
380 the k2-sata-root */ 400 the k2-sata-root */
381 break; 401 break;
382 } 402 }
383#endif 403#endif /* CONFIG_PPC64 */
384 if (n > 2) { 404 if (n > 2) {
385 printk("hmmm, got %d intr cells for %s:", n, 405 printk("hmmm, got %d intr cells for %s:", n,
386 np->full_name); 406 np->full_name);