Commit b341e32e authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras

[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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 1e28a7dd
...@@ -325,8 +325,8 @@ static void __init offb_init_nodriver(struct device_node *dp) ...@@ -325,8 +325,8 @@ static void __init offb_init_nodriver(struct device_node *dp)
int *pp, i; int *pp, i;
unsigned int len; unsigned int len;
int width = 640, height = 480, depth = 8, pitch; int width = 640, height = 480, depth = 8, pitch;
unsigned *up; unsigned int rsize, *up;
unsigned long address; unsigned long address = 0;
if ((pp = (int *) get_property(dp, "depth", &len)) != NULL if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int)) && len == sizeof(int))
...@@ -344,10 +344,40 @@ static void __init offb_init_nodriver(struct device_node *dp) ...@@ -344,10 +344,40 @@ static void __init offb_init_nodriver(struct device_node *dp)
pitch = 0x1000; pitch = 0x1000;
} else } else
pitch = width; 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; address = (u_long) * up;
else { if (address == 0) {
for (i = 0; i < dp->n_addrs; ++i) for (i = 0; i < dp->n_addrs; ++i)
if (dp->addrs[i].size >= if (dp->addrs[i].size >=
pitch * height * depth / 8) pitch * height * depth / 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment