From 9b61543e0a8082b3155f3a204eb5a67945fdb483 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 23 May 2005 10:03:52 +1000 Subject: [PATCH] --- yaml --- r: 1323 b: refs/heads/master c: 1263cc67c09bc7f913a6877f3ba0427f0b76617e h: refs/heads/master i: 1321: 5efcd24f20df2e8bcb714d5ab71843be17097251 1319: 4a4262947c7f5a0182d3ecc0ac382b64f745bc4d v: v3 --- [refs] | 2 +- trunk/arch/ppc64/kernel/prom_init.c | 44 +++++++++++++++++++++++++- trunk/drivers/i2c/busses/i2c-keywest.c | 5 +++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 020a2c919816..6a493e9c3102 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b5c44c2147a447f77e07fecdb087ae288e1f4e40 +refs/heads/master: 1263cc67c09bc7f913a6877f3ba0427f0b76617e diff --git a/trunk/arch/ppc64/kernel/prom_init.c b/trunk/arch/ppc64/kernel/prom_init.c index 35ec42de962e..6f79b7b9b445 100644 --- a/trunk/arch/ppc64/kernel/prom_init.c +++ b/trunk/arch/ppc64/kernel/prom_init.c @@ -1750,7 +1750,44 @@ static void __init flatten_device_tree(void) prom_printf("Device tree struct 0x%x -> 0x%x\n", RELOC(dt_struct_start), RELOC(dt_struct_end)); - } +} + + +static void __init fixup_device_tree(void) +{ + unsigned long offset = reloc_offset(); + phandle u3, i2c, mpic; + u32 u3_rev; + u32 interrupts[2]; + u32 parent; + + /* Some G5s have a missing interrupt definition, fix it up here */ + u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); + if ((long)u3 <= 0) + return; + i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); + if ((long)i2c <= 0) + return; + mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); + if ((long)mpic <= 0) + return; + + /* check if proper rev of u3 */ + if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0) + return; + if (u3_rev != 0x35) + return; + /* does it need fixup ? */ + if (prom_getproplen(i2c, "interrupts") > 0) + return; + /* interrupt on this revision of u3 is number 0 and level */ + interrupts[0] = 0; + interrupts[1] = 1; + prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); + parent = (u32)mpic; + prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); +} + static void __init prom_find_boot_cpu(void) { @@ -1919,6 +1956,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end))); } + /* + * Fixup any known bugs in the device-tree + */ + fixup_device_tree(); + /* * Now finally create the flattened device-tree */ diff --git a/trunk/drivers/i2c/busses/i2c-keywest.c b/trunk/drivers/i2c/busses/i2c-keywest.c index dd0d4c463146..867d443e7133 100644 --- a/trunk/drivers/i2c/busses/i2c-keywest.c +++ b/trunk/drivers/i2c/busses/i2c-keywest.c @@ -516,6 +516,11 @@ create_iface(struct device_node *np, struct device *dev) u32 *psteps, *prate; int rc; + if (np->n_intrs < 1 || np->n_addrs < 1) { + printk(KERN_ERR "%s: Missing interrupt or address !\n", + np->full_name); + return -ENODEV; + } if (pmac_low_i2c_lock(np)) return -ENODEV;