[PATCH 09/36] xfree86: add platform bus hotplug support (v3)

2012-07-05 Thread Dave Airlie
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 == 

Re: [PATCH 09/36] xfree86: add platform bus hotplug support (v3)

2012-07-05 Thread Keith Packard
Dave Airlie airl...@gmail.com writes:

 +
 +for (layout = xf86ConfigLayout.screens; layout-screen != NULL;
 + layout++) {
 +xf86GPUScreens[i]-confScreen = layout-screen;
 +break;
 +}

This loop is insane.

Otherwise, this is all

Reviewed-by: Keith Packard kei...@keithp.com

-- 
keith.pack...@intel.com


pgp91fobDpqYv.pgp
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel