aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2008-01-25 00:25:32 -0500
committerGrant Likely <grant.likely@secretlab.ca>2008-01-26 17:32:18 -0500
commit94d2dde738a50124d1f1b1b40bd5b9d0ed22e2e2 (patch)
treebd49bc0ce469824c806c40be9bc8cdead3934e3c
parent24ce6bc4a2b75509b29372f1e5e7e0fe51d98e66 (diff)
[POWERPC] Efika: prune fixups and make them more carefull
Prune back Efika fixups to only include changes that are actually required to get a working system. Most of the drivers can accept the compatible properties, even if they don't match the what is recommented in the generic names recommended practice document. This patch also adds extra checks so that fixups are not performed blindly. Instead, the code first verifies that the device tree is faulty before making any changes. This way, if the Efika firmware is updated to fix these issues, then the fixups will no longer get applied. At this point; here is the list of fixups needed for the efika: 1. If the device_type property on the root node is 'chrp', then Linux won't boot. Change device_type to 'efika' to avoid this condition 2. Add full interrupt list to the bestcomm node. In actual fact, the bestcomm interrupts property is technically correct, it just doesn't expose the same granularity as the device driver expects. All other 5200 device trees provide a separate irq number for each bestcomm channel. Rather than hack the driver, it's simpler to fix it up 3. /builtin/sound node is missing an interrupts property 4. /builtin/ethernet node is missing a phy-handle property and the device driver doesn't know what to do without one. Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--arch/powerpc/kernel/prom_init.c149
1 files changed, 79 insertions, 70 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 5d89a21dd0d6..5ab4c8466cc9 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2142,82 +2142,34 @@ static void __init fixup_device_tree_pmac(void)
2142#endif 2142#endif
2143 2143
2144#ifdef CONFIG_PPC_EFIKA 2144#ifdef CONFIG_PPC_EFIKA
2145/* The current fw of the Efika has a device tree needs quite a few 2145/*
2146 * fixups to be compliant with the mpc52xx bindings. It's currently 2146 * The MPC5200 FEC driver requires an phy-handle property to tell it how
2147 * unknown if it will ever be compliant (come on bPlan ...) so we do fixups. 2147 * to talk to the phy. If the phy-handle property is missing, then this
2148 * NOTE that we (barely) tolerate it because the EFIKA was out before 2148 * function is called to add the appropriate nodes and link it to the
2149 * the bindings were finished, for any new boards -> RTFM ! */ 2149 * ethernet node.
2150 2150 */
2151struct subst_entry { 2151static void __init fixup_device_tree_efika_add_phy(void)
2152 char *path;
2153 char *property;
2154 void *value;
2155 int value_len;
2156};
2157
2158static void __init fixup_device_tree_efika(void)
2159{ 2152{
2160 /* Substitution table */
2161 #define prop_cstr(x) x, sizeof(x)
2162 int prop_sound_irq[3] = { 2, 2, 0 };
2163 int prop_bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2164 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2165 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2166 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2167 struct subst_entry efika_subst_table[] = {
2168 { "/", "device_type", prop_cstr("efika") },
2169 { "/builtin", "device_type", prop_cstr("soc") },
2170 { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
2171 { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
2172 { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
2173 { "/builtin/ethernet", "compatible", prop_cstr("mpc5200b-fec\0mpc5200-fec") },
2174 { "/builtin/pic", "compatible", prop_cstr("mpc5200b-pic\0mpc5200-pic") },
2175 { "/builtin/serial", "compatible", prop_cstr("mpc5200b-psc-uart\0mpc5200-psc-uart") },
2176 { "/builtin/sound", "compatible", prop_cstr("mpc5200b-psc-ac97\0mpc5200-psc-ac97") },
2177 { "/builtin/sound", "interrupts", prop_sound_irq, sizeof(prop_sound_irq) },
2178 { "/builtin/sram", "compatible", prop_cstr("mpc5200b-sram\0mpc5200-sram") },
2179 { "/builtin/sram", "device_type", prop_cstr("sram") },
2180 {}
2181 };
2182 #undef prop_cstr
2183
2184 /* Vars */
2185 u32 node; 2153 u32 node;
2186 char prop[64]; 2154 char prop[64];
2187 int rv, i; 2155 int rv;
2188 2156
2189 /* Check if we're really running on a EFIKA */ 2157 /* Check if /builtin/ethernet exists - bail if it doesn't */
2190 node = call_prom("finddevice", 1, 1, ADDR("/")); 2158 node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
2191 if (!PHANDLE_VALID(node)) 2159 if (!PHANDLE_VALID(node))
2192 return; 2160 return;
2193 2161
2194 rv = prom_getprop(node, "model", prop, sizeof(prop)); 2162 /* Check if the phy-handle property exists - bail if it does */
2195 if (rv == PROM_ERROR) 2163 rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2196 return; 2164 if (!rv)
2197 if (strcmp(prop, "EFIKA5K2"))
2198 return; 2165 return;
2199 2166
2200 prom_printf("Applying EFIKA device tree fixups\n"); 2167 /*
2201 2168 * At this point the ethernet device doesn't have a phy described.
2202 /* Process substitution table */ 2169 * Now we need to add the missing phy node and linkage
2203 for (i=0; efika_subst_table[i].path; i++) { 2170 */
2204 struct subst_entry *se = &efika_subst_table[i];
2205
2206 node = call_prom("finddevice", 1, 1, ADDR(se->path));
2207 if (!PHANDLE_VALID(node)) {
2208 prom_printf("fixup_device_tree_efika: ",
2209 "skipped entry %x - not found\n", i);
2210 continue;
2211 }
2212
2213 rv = prom_setprop(node, se->path, se->property,
2214 se->value, se->value_len );
2215 if (rv == PROM_ERROR)
2216 prom_printf("fixup_device_tree_efika: ",
2217 "skipped entry %x - setprop error\n", i);
2218 }
2219 2171
2220 /* Make sure ethernet mdio bus node exists */ 2172 /* Check for an MDIO bus node - if missing then create one */
2221 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio")); 2173 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2222 if (!PHANDLE_VALID(node)) { 2174 if (!PHANDLE_VALID(node)) {
2223 prom_printf("Adding Ethernet MDIO node\n"); 2175 prom_printf("Adding Ethernet MDIO node\n");
@@ -2226,8 +2178,8 @@ static void __init fixup_device_tree_efika(void)
2226 " new-device" 2178 " new-device"
2227 " 1 encode-int s\" #address-cells\" property" 2179 " 1 encode-int s\" #address-cells\" property"
2228 " 0 encode-int s\" #size-cells\" property" 2180 " 0 encode-int s\" #size-cells\" property"
2229 " s\" mdio\" 2dup device-name device-type" 2181 " s\" mdio\" device-name"
2230 " s\" mpc5200b-fec-phy\" encode-string" 2182 " s\" fsl,mpc5200b-mdio\" encode-string"
2231 " s\" compatible\" property" 2183 " s\" compatible\" property"
2232 " 0xf0003000 0x400 reg" 2184 " 0xf0003000 0x400 reg"
2233 " 0x2 encode-int" 2185 " 0x2 encode-int"
@@ -2237,8 +2189,10 @@ static void __init fixup_device_tree_efika(void)
2237 " finish-device"); 2189 " finish-device");
2238 }; 2190 };
2239 2191
2240 /* Make sure ethernet phy device node exist */ 2192 /* Check for a PHY device node - if missing then create one and
2241 node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio/ethernet-phy")); 2193 * give it's phandle to the ethernet node */
2194 node = call_prom("finddevice", 1, 1,
2195 ADDR("/builtin/mdio/ethernet-phy"));
2242 if (!PHANDLE_VALID(node)) { 2196 if (!PHANDLE_VALID(node)) {
2243 prom_printf("Adding Ethernet PHY node\n"); 2197 prom_printf("Adding Ethernet PHY node\n");
2244 call_prom("interpret", 1, 1, 2198 call_prom("interpret", 1, 1,
@@ -2254,7 +2208,62 @@ static void __init fixup_device_tree_efika(void)
2254 " s\" phy-handle\" property" 2208 " s\" phy-handle\" property"
2255 " device-end"); 2209 " device-end");
2256 } 2210 }
2211}
2212
2213static void __init fixup_device_tree_efika(void)
2214{
2215 int sound_irq[3] = { 2, 2, 0 };
2216 int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2217 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2218 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2219 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2220 u32 node;
2221 char prop[64];
2222 int rv, len;
2223
2224 /* Check if we're really running on a EFIKA */
2225 node = call_prom("finddevice", 1, 1, ADDR("/"));
2226 if (!PHANDLE_VALID(node))
2227 return;
2228
2229 rv = prom_getprop(node, "model", prop, sizeof(prop));
2230 if (rv == PROM_ERROR)
2231 return;
2232 if (strcmp(prop, "EFIKA5K2"))
2233 return;
2234
2235 prom_printf("Applying EFIKA device tree fixups\n");
2236
2237 /* Claiming to be 'chrp' is death */
2238 node = call_prom("finddevice", 1, 1, ADDR("/"));
2239 rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2240 if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2241 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2242
2243 /* Fixup bestcomm interrupts property */
2244 node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2245 if (PHANDLE_VALID(node)) {
2246 len = prom_getproplen(node, "interrupts");
2247 if (len == 12) {
2248 prom_printf("Fixing bestcomm interrupts property\n");
2249 prom_setprop(node, "/builtin/bestcom", "interrupts",
2250 bcomm_irq, sizeof(bcomm_irq));
2251 }
2252 }
2253
2254 /* Fixup sound interrupts property */
2255 node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2256 if (PHANDLE_VALID(node)) {
2257 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2258 if (rv == PROM_ERROR) {
2259 prom_printf("Adding sound interrupts property\n");
2260 prom_setprop(node, "/builtin/sound", "interrupts",
2261 sound_irq, sizeof(sound_irq));
2262 }
2263 }
2257 2264
2265 /* Make sure ethernet phy-handle property exists */
2266 fixup_device_tree_efika_add_phy();
2258} 2267}
2259#else 2268#else
2260#define fixup_device_tree_efika() 2269#define fixup_device_tree_efika()