With the advent of MST we now receive notifications through uevents of
not just the comings and goings of the GPUs themselves, but of the
individual connectors. Differentiate between these events and filter out
the calls to add/remove the actual GPU if we only have topology updates.

Signed-off-by: Chris Wilson <[email protected]>
Cc: Dave Airlie <[email protected]>
---
 config/udev.c | 82 ++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 50 insertions(+), 32 deletions(-)

diff --git a/config/udev.c b/config/udev.c
index 1e4a9d7..dbe32c4 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -69,6 +69,23 @@ static const char *itoa(int i)
     return itoa_buf;
 }
 
+static enum { NO, OTHER, GPU } is_drm_device(struct udev_device *device)
+{
+    const char *sysname;
+
+    if (strcmp(udev_device_get_subsystem(device), "drm"))
+       return NO;
+
+    sysname = udev_device_get_sysname(device);
+    if (strncmp(sysname, "card", 4))
+       return OTHER;
+
+    if (strchr(sysname, '-'))
+       return OTHER;
+
+    return GPU;
+}
+
 static void
 device_added(struct udev_device *udev_device)
 {
@@ -87,7 +104,6 @@ device_added(struct udev_device *udev_device)
     dev_t devnum;
 
     path = udev_device_get_devnode(udev_device);
-
     syspath = udev_device_get_syspath(udev_device);
 
     if (!path || !syspath)
@@ -106,21 +122,18 @@ device_added(struct udev_device *udev_device)
     devnum = udev_device_get_devnum(udev_device);
 
 #ifdef CONFIG_UDEV_KMS
-    if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
-        const char *sysname = udev_device_get_sysname(udev_device);
-
-        if (strncmp(sysname, "card", 4) != 0)
-            return;
-
-        /* Check for devices already added through xf86platformProbe() */
-        if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum)))
-            return;
-
-        LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
-
-        config_udev_odev_setup_attribs(path, syspath, major(devnum),
-                                       minor(devnum), NewGPUDeviceRequest);
-        return;
+    switch (is_drm_device(udev_device)) {
+    case NO:
+       break;
+    case GPU:
+       /* Check for devices already added through xf86platformProbe() */
+       if (!xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) 
{
+           LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
+           config_udev_odev_setup_attribs(path, syspath, major(devnum),
+                                          minor(devnum), NewGPUDeviceRequest);
+       }
+    case OTHER:
+       return;
     }
 #endif
 
@@ -291,25 +304,30 @@ device_added(struct udev_device *udev_device)
 static void
 device_removed(struct udev_device *device)
 {
-    char *value;
+    dev_t devnum = udev_device_get_devnum(device);
     const char *syspath = udev_device_get_syspath(device);
+    char *value;
 
-#ifdef CONFIG_UDEV_KMS
-    if (!strcmp(udev_device_get_subsystem(device), "drm")) {
-        const char *sysname = udev_device_get_sysname(device);
-        const char *path = udev_device_get_devnode(device);
-        dev_t devnum = udev_device_get_devnum(device);
-
-        if (strncmp(sysname,"card", 4) != 0)
-            return;
-        ErrorF("removing GPU device %s %s\n", syspath, path);
-        if (!path)
-            return;
+    if (syspath == NULL)
+       return;
 
-        config_udev_odev_setup_attribs(path, syspath, major(devnum),
-                                       minor(devnum), DeleteGPUDeviceRequest);
-        /* Retry vtenter after a drm node removal */
-        systemd_logind_vtenter();
+#ifdef CONFIG_UDEV_KMS
+    switch (is_drm_device(device)) {
+    case NO:
+       break;
+    case GPU:
+       if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) {
+           const char *path = udev_device_get_devnode(device);
+           if (path) {
+               LogMessage(X_INFO, "config/udev: Removing drm device (%s)\n", 
path);
+               config_udev_odev_setup_attribs(path, syspath,
+                                              major(devnum), minor(devnum),
+                                              DeleteGPUDeviceRequest);
+               /* Retry vtenter after a drm node removal */
+               systemd_logind_vtenter();
+           }
+       }
+    case OTHER:
         return;
     }
 #endif
-- 
2.0.1

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to