summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-18 07:22:51 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-18 07:22:51 -0800
commit2656c076e31a3ce3ab2a987a578e7122dc2af51d (patch)
tree98ee4e9c816191c72fc7faaf1934f6c4e5e1f3d6 /drivers
parent811803c5572b296e0031e0099203de90d77c7bcf (diff)
parentf365cfd0d8b6d8fb3583d23d48f54efa88ee8563 (diff)
downloadkernel-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.c41
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)