aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/offb.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-16 21:34:57 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-17 00:54:19 -0500
commitb341e32e5cc1a154cb0ac2f4229c2d040647804b (patch)
treec10e935a30c0d4f1a776650473e6fccc62d40291 /drivers/video/offb.c
parent1e28a7ddd3e713384e9c6768e7c502031dc205e2 (diff)
[PATCH] powerpc: Workaround for offb on 64 bits platforms
This fixes a problem with offb not parsing addresses properly on 64 bits machines, and thus crashing at boot. The problem is worked around by locating the matching PCI device and using the properly relocated PCI base addresses instead of misparsing the Open Firmware properties. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/video/offb.c')
-rw-r--r--drivers/video/offb.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 2c856838694..fe8ba364b3e 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -325,8 +325,8 @@ static void __init offb_init_nodriver(struct device_node *dp)
325 int *pp, i; 325 int *pp, i;
326 unsigned int len; 326 unsigned int len;
327 int width = 640, height = 480, depth = 8, pitch; 327 int width = 640, height = 480, depth = 8, pitch;
328 unsigned *up; 328 unsigned int rsize, *up;
329 unsigned long address; 329 unsigned long address = 0;
330 330
331 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL 331 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
332 && len == sizeof(int)) 332 && len == sizeof(int))
@@ -344,10 +344,40 @@ static void __init offb_init_nodriver(struct device_node *dp)
344 pitch = 0x1000; 344 pitch = 0x1000;
345 } else 345 } else
346 pitch = width; 346 pitch = width;
347 if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL 347
348 && len == sizeof(unsigned)) 348 rsize = (unsigned long)pitch * (unsigned long)height *
349 (unsigned long)(depth / 8);
350
351 /* Try to match device to a PCI device in order to get a properly
352 * translated address rather then trying to decode the open firmware
353 * stuff in various incorrect ways
354 */
355#ifdef CONFIG_PCI
356 /* First try to locate the PCI device if any */
357 {
358 struct pci_dev *pdev = NULL;
359
360 for_each_pci_dev(pdev) {
361 if (dp == pci_device_to_OF_node(pdev))
362 break;
363 }
364 if (pdev) {
365 for (i = 0; i < 6 && address == 0; i++) {
366 if ((pci_resource_flags(pdev, i) &
367 IORESOURCE_MEM) &&
368 (pci_resource_len(pdev, i) >= rsize))
369 address = pci_resource_start(pdev, i);
370 }
371 pci_dev_put(pdev);
372 }
373 }
374#endif /* CONFIG_PCI */
375
376 if (address == 0 &&
377 (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
378 len == sizeof(unsigned))
349 address = (u_long) * up; 379 address = (u_long) * up;
350 else { 380 if (address == 0) {
351 for (i = 0; i < dp->n_addrs; ++i) 381 for (i = 0; i < dp->n_addrs; ++i)
352 if (dp->addrs[i].size >= 382 if (dp->addrs[i].size >=
353 pitch * height * depth / 8) 383 pitch * height * depth / 8)