- if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL
- && len == sizeof(unsigned))
- address = (u_long) * up;
- else {
- for (i = 0; i < dp->n_addrs; ++i)
- if (dp->addrs[i].size >=
- pitch * height * depth / 8)
- break;
- if (i >= dp->n_addrs) {
+
+ 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 == OF_BAD_ADDR; 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 */
+
+ /* This one is dodgy, we may drop it ... */
+ if (address == OF_BAD_ADDR &&
+ (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
+ len == sizeof(unsigned int))
+ address = (u64) * up;
+
+ if (address == OF_BAD_ADDR) {
+ for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
+ != NULL; i++) {
+ if (!(flags & IORESOURCE_MEM))
+ continue;
+ if (asize >= pitch * height * depth / 8)
+ break;
+ }
+ if (addrp == NULL) {