diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-18 07:22:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-18 07:22:51 -0800 |
commit | 2656c076e31a3ce3ab2a987a578e7122dc2af51d (patch) | |
tree | 98ee4e9c816191c72fc7faaf1934f6c4e5e1f3d6 /drivers | |
parent | 811803c5572b296e0031e0099203de90d77c7bcf (diff) | |
parent | f365cfd0d8b6d8fb3583d23d48f54efa88ee8563 (diff) | |
download | kernel-crypto-2656c076e31a3ce3ab2a987a578e7122dc2af51d.tar.gz kernel-crypto-2656c076e31a3ce3ab2a987a578e7122dc2af51d.tar.xz kernel-crypto-2656c076e31a3ce3ab2a987a578e7122dc2af51d.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/offb.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 2c856838694..00d87f5bb7b 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -26,6 +26,7 @@ #include <linux/fb.h> #include <linux/init.h> #include <linux/ioport.h> +#include <linux/pci.h> #include <asm/io.h> #include <asm/prom.h> @@ -325,8 +326,8 @@ static void __init offb_init_nodriver(struct device_node *dp) int *pp, i; unsigned int len; int width = 640, height = 480, depth = 8, pitch; - unsigned *up; - unsigned long address; + unsigned int rsize, *up; + unsigned long address = 0; if ((pp = (int *) get_property(dp, "depth", &len)) != NULL && len == sizeof(int)) @@ -344,10 +345,40 @@ static void __init offb_init_nodriver(struct device_node *dp) pitch = 0x1000; } else pitch = width; - if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL - && len == sizeof(unsigned)) + + rsize = (unsigned long)pitch * (unsigned long)height * + (unsigned long)(depth / 8); + + /* Try to match device to a PCI device in order to get a properly + * translated address rather then trying to decode the open firmware + * stuff in various incorrect ways + */ +#ifdef CONFIG_PCI + /* First try to locate the PCI device if any */ + { + struct pci_dev *pdev = NULL; + + for_each_pci_dev(pdev) { + if (dp == pci_device_to_OF_node(pdev)) + break; + } + if (pdev) { + for (i = 0; i < 6 && address == 0; i++) { + if ((pci_resource_flags(pdev, i) & + IORESOURCE_MEM) && + (pci_resource_len(pdev, i) >= rsize)) + address = pci_resource_start(pdev, i); + } + pci_dev_put(pdev); + } + } +#endif /* CONFIG_PCI */ + + if (address == 0 && + (up = (unsigned *) get_property(dp, "address", &len)) != NULL && + len == sizeof(unsigned)) address = (u_long) * up; - else { + if (address == 0) { for (i = 0; i < dp->n_addrs; ++i) if (dp->addrs[i].size >= pitch * height * depth / 8) |