From: Dave Airlie airl...@redhat.com
This provides add/remove support for platform devices at xfree86 ddx level.
v2: cleanup properly if no driver found.
v3: load the modesetting driver before checking driver list.
Signed-off-by: Dave Airlie airl...@redhat.com
---
hw/xfree86/common/xf86platformBus.c| 103
hw/xfree86/common/xf86platformBus.h|5 ++
hw/xfree86/os-support/linux/lnx_platform.c | 49 +
3 files changed, 157 insertions(+)
diff --git a/hw/xfree86/common/xf86platformBus.c
b/hw/xfree86/common/xf86platformBus.c
index 50b7636..0cc6c0a 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -376,4 +376,107 @@ xf86platformProbeDev(DriverPtr drvp)
return foundScreen;
}
+int
+xf86platformAddDevice(int index)
+{
+int i, old_screens, scr_index;
+DriverPtr drvp = NULL;
+int entity;
+screenLayoutPtr layout;
+static char *hotplug_driver_name = modesetting;
+
+/* force load the driver for now */
+xf86LoadOneModule(hotplug_driver_name, NULL);
+
+for (i = 0; i xf86NumDrivers; i++) {
+if (!xf86DriverList[i])
+continue;
+
+if (!strcmp(xf86DriverList[i]-driverName, hotplug_driver_name)) {
+drvp = xf86DriverList[i];
+break;
+}
+}
+if (i == xf86NumDrivers)
+return -1;
+
+old_screens = xf86NumGPUScreens;
+entity = xf86ClaimPlatformSlot(xf86_platform_devices[index],
+ drvp, 0, 0, 0);
+if (!drvp-platformProbe(drvp, entity, PLATFORM_PROBE_GPU_SCREEN,
xf86_platform_devices[index], 0)) {
+xf86UnclaimPlatformSlot(xf86_platform_devices[index], NULL);
+}
+if (old_screens == xf86NumGPUScreens)
+return -1;
+i = old_screens;
+
+for (layout = xf86ConfigLayout.screens; layout-screen != NULL;
+ layout++) {
+xf86GPUScreens[i]-confScreen = layout-screen;
+break;
+}
+
+if (xf86GPUScreens[i]-PreInit
+xf86GPUScreens[i]-PreInit(xf86GPUScreens[i], 0))
+xf86GPUScreens[i]-configured = TRUE;
+
+if (!xf86GPUScreens[i]-configured) {
+ErrorF(hotplugged device %d didn't configure\n, i);
+xf86DeleteScreen(xf86GPUScreens[i]);
+return -1;
+}
+
+ scr_index = AddGPUScreen(xf86GPUScreens[i]-ScreenInit, 0, NULL);
+
+ dixSetPrivate(xf86GPUScreens[i]-pScreen-devPrivates,
+ xf86ScreenKey, xf86GPUScreens[i]);
+
+ CreateScratchPixmapsForScreen(xf86GPUScreens[i]-pScreen);
+
+ return 0;
+}
+
+void
+xf86platformRemoveDevice(int index)
+{
+EntityPtr entity;
+int ent_num, i, j;
+Bool found;
+
+for (ent_num = 0; ent_num xf86NumEntities; ent_num++) {
+entity = xf86Entities[ent_num];
+if (entity-bus.type == BUS_PLATFORM
+entity-bus.id.plat == xf86_platform_devices[index])
+break;
+}
+if (ent_num == xf86NumEntities)
+goto out;
+
+found = FALSE;
+for (i = 0; i xf86NumGPUScreens; i++) {
+for (j = 0; j xf86GPUScreens[i]-numEntities; j++)
+if (xf86GPUScreens[i]-entityList[j] == ent_num) {
+found = TRUE;
+break;
+}
+if (found)
+break;
+}
+if (!found) {
+ErrorF(failed to find screen to remove\n);
+goto out;
+}
+
+xf86GPUScreens[i]-pScreen-CloseScreen(xf86GPUScreens[i]-pScreen);
+
+RemoveGPUScreen(xf86GPUScreens[i]-pScreen);
+xf86DeleteScreen(xf86GPUScreens[i]);
+
+xf86UnclaimPlatformSlot(xf86_platform_devices[index], NULL);
+
+xf86_remove_platform_device(index);
+
+ out:
+return;
+}
#endif
diff --git a/hw/xfree86/common/xf86platformBus.h
b/hw/xfree86/common/xf86platformBus.h
index 15a3022..49afc24 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -47,6 +47,11 @@ xf86_remove_platform_device(int dev_index);
extern Bool
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
+extern int
+xf86platformAddDevice(int index);
+extern void
+xf86platformRemoveDevice(int index);
+
extern _X_EXPORT char *
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int
attrib_id);
extern _X_EXPORT Bool
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c
b/hw/xfree86/os-support/linux/lnx_platform.c
index 9c63ee5..76f5583 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -15,6 +15,8 @@
#include xf86platformBus.h
#include xf86Bus.h
+#include hotplug.h
+
static Bool
get_drm_info(struct OdevAttributes *attribs, char *path)
{
@@ -127,4 +129,51 @@ out_free:
config_odev_free_attribute_list(attribs);
}
+void NewGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+int old_num = xf86_num_platform_devices;
+int ret;
+xf86PlatformDeviceProbe(attribs);
+
+if (old_num ==