From: Peter Robinson --- xorg-server-1.16.0/hw/xfree86/common/xf86Init.c.orig 2014-08-26 19:29:26.802470808 +0100 +++ xorg-server-1.16.0/hw/xfree86/common/xf86Init.c 2014-08-26 19:31:21.495368739 +0100 @@ -546,10 +546,18 @@ if (xf86DriverList[i]->Identify != NULL) xf86DriverList[i]->Identify(0); - if (xf86DriverList[i]->driverFunc) + if (xf86DriverList[i]->driverFunc) { xf86DriverList[i]->driverFunc(NULL, GET_REQUIRED_HW_INTERFACES, &flags); + /* also let the driver know that it is safe to + * allow platformProbe() to claim the device + * if it is a non-pci platform device: + */ + xf86DriverList[i]->driverFunc(NULL, + SERVER_SUPPORTS_NON_PCI_PLATFORM_DEVS, + NULL); + } if (NEED_IO_ENABLED(flags)) want_hw_access = TRUE; --- xorg-server-1.16.0/hw/xfree86/common/xf86str.h.orig 2014-08-26 19:29:39.158675241 +0100 +++ xorg-server-1.16.0/hw/xfree86/common/xf86str.h 2014-08-26 19:31:21.495368739 +0100 @@ -258,6 +258,7 @@ RR_GET_MODE_MM, GET_REQUIRED_HW_INTERFACES = 10, SUPPORTS_SERVER_FDS = 11, + SERVER_SUPPORTS_NON_PCI_PLATFORM_DEVS = 12, } xorgDriverFuncOp; typedef Bool xorgDriverFuncProc(ScrnInfoPtr, xorgDriverFuncOp, void *); --- xorg-server-1.16.0/hw/xfree86/common/xf86platformBus.c.orig 2014-07-16 19:57:12.000000000 +0100 +++ xorg-server-1.16.0/hw/xfree86/common/xf86platformBus.c 2014-08-26 19:31:26.483451297 +0100 @@ -275,6 +275,41 @@ return i; } +static int +find_non_pci_driver(const char *busid, char *returnList[], int returnListMax) +{ + /* Add more entries here if we ever return more than 4 drivers for + any device */ + const char *driverList[5] = { NULL, NULL, NULL, NULL, NULL }; + int i = 0; + char *p, *s; + + s = xstrdup(busid); + p = strtok(s, ":"); + + if (strcmp(p, "platform")) + goto out; + + /* extract device name: */ + p = strtok(NULL, ":"); + + /* check for special cases where DDX driver name does not match busid: */ + if (!strcmp(p, "mdp")) { + driverList[i++] = "freedreno"; + } + + /* add name derived from busid last: */ + driverList[i++] = p; + + for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) { + returnList[i] = xnfstrdup(driverList[i]); + } + +out: + free(s); + return i; /* Number of entries added */ +} + /** * @return The numbers of found devices that match with the current system * drivers. @@ -305,6 +340,9 @@ if ((info != NULL) && (j < nmatches)) { j += xf86VideoPtrToDriverList(info, &(matches[j]), nmatches - j); + } else if (j < nmatches) { + char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID); + j += find_non_pci_driver(busid, &(matches[j]), nmatches - j); } } } @@ -323,6 +361,9 @@ pci = FALSE; } + /* First pass, look for PCI devices. If we find a suitable + * PCI device that takes priority. + */ for (i = 0; i < xf86_num_platform_devices; i++) { char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID); @@ -330,6 +371,24 @@ platform_find_pci_info(&xf86_platform_devices[i], busid); } } + + /* if we found something, we are done: */ + if (primaryBus.type != BUS_NONE) + return 0; + + /* Second pass, look for real platform devices (ie. in the linux- + * kernel sense of platform device.. something that is not pci) + */ + for (i = 0; i < xf86_num_platform_devices; i++) { + char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID); + + if (strncmp(busid, "platform:", 9) == 0) { + primaryBus.type = BUS_PLATFORM; + primaryBus.id.plat = &xf86_platform_devices[i]; + break; + } + } + return 0; } @@ -476,10 +535,8 @@ /* for non-seat0 servers assume first device is the master */ if (ServerIsNotSeat0()) break; - if (xf86_platform_devices[j].pdev) { - if (xf86IsPrimaryPlatform(&xf86_platform_devices[j])) - break; - } + if (xf86IsPrimaryPlatform(&xf86_platform_devices[j])) + break; } }