diff options
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 149 |
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 | */ | |
2151 | struct subst_entry { | 2151 | static void __init fixup_device_tree_efika_add_phy(void) |
2152 | char *path; | ||
2153 | char *property; | ||
2154 | void *value; | ||
2155 | int value_len; | ||
2156 | }; | ||
2157 | |||
2158 | static 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 | |||
2213 | static 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() |