Patchwork [01/15] i2c/powermac: Register i2c devices from device-tree

login
register
mail settings
Submitter Andreas Schwab
Date June 10, 2012, 11:35 a.m.
Message ID <m2zk8bz9f2.fsf@igel.home>
Download mbox | patch
Permalink /patch/163984/
State Superseded
Delegated to: Benjamin Herrenschmidt
Headers show

Comments

Andreas Schwab - June 10, 2012, 11:35 a.m.
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> Ah, excellent, so a small quirk in i2c_powermac is the way to go then,
> we can detect it by name and hack up something. Either that or even
> better, in prom_init, we could add the missing property to the
> device-tree.

How does that look like?  Though I'm not sure this is the right
approach.  Those models with the onyx chip that lack the pcm3052
compatible property apparently have no OF node at all to key off the
workaround.

Andreas.

Patch

diff --git i/arch/powerpc/kernel/prom_init.c w/arch/powerpc/kernel/prom_init.c
index 1b488e5..1b04159 100644
--- i/arch/powerpc/kernel/prom_init.c
+++ w/arch/powerpc/kernel/prom_init.c
@@ -2554,7 +2554,7 @@  static void __init fixup_device_tree_chrp(void)
 #endif
 
 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
-static void __init fixup_device_tree_pmac(void)
+static void __init fixup_device_tree_pmac_u3_i2c(void)
 {
 	phandle u3, i2c, mpic;
 	u32 u3_rev;
@@ -2593,6 +2593,39 @@  static void __init fixup_device_tree_pmac(void)
 	prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
 		     &parent, sizeof(parent));
 }
+
+static void __init fixup_device_tree_pmac_deq(void)
+{
+	phandle deq;
+	u32 i2c_address;
+
+	/*
+	 * On older G5s the tas3004 is described by a deq node missing a
+	 * compatible definition, instead of a codec node with a
+	 * tas3004,code compatible property. Fix that up here.
+	 */
+	deq = call_prom("finddevice", 1, 1, ADDR("/ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a"));
+	if (!PHANDLE_VALID(deq))
+		return;
+	/* Check for proper i2c-address. */
+	if (prom_getprop(deq, "i2c-address", &i2c_address, sizeof(i2c_address)) == PROM_ERROR)
+		return;
+	i2c_address = (i2c_address >> 1) & 0x7f;
+	if (i2c_address != 0x34 && i2c_address != 0x35)
+		return;
+
+	prom_printf("fixing up missing compatible for deq node...\n");
+
+	prom_setprop (deq, "/ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a",
+		      "compatible", &RELOC("tas3004\0codec\0"),
+		      sizeof("tas3004\0codec\0"));
+}
+
+static void __init fixup_device_tree_pmac(void)
+{
+	fixup_device_tree_pmac_u3_i2c();
+	fixup_device_tree_pmac_deq();
+}
 #else
 #define fixup_device_tree_pmac()
 #endif