drm/client: Send hotplug event after registering a client
authorjsg <jsg@openbsd.org>
Wed, 26 Jul 2023 06:13:01 +0000 (06:13 +0000)
committerjsg <jsg@openbsd.org>
Wed, 26 Jul 2023 06:13:01 +0000 (06:13 +0000)
From Thomas Zimmermann
7c880188c71066449a76de71de772198a0c30a7c in linux-6.1.y/6.1.40
27655b9bb9f0d9c32b8de8bec649b676898c52d5 in mainline linux

sys/dev/pci/drm/drm_client.c
sys/dev/pci/drm/drm_fb_helper.c

index 2b230b4..dcbeeb6 100644 (file)
@@ -122,13 +122,34 @@ EXPORT_SYMBOL(drm_client_init);
  * drm_client_register() it is no longer permissible to call drm_client_release()
  * directly (outside the unregister callback), instead cleanup will happen
  * automatically on driver unload.
+ *
+ * Registering a client generates a hotplug event that allows the client
+ * to set up its display from pre-existing outputs. The client must have
+ * initialized its state to able to handle the hotplug event successfully.
  */
 void drm_client_register(struct drm_client_dev *client)
 {
        struct drm_device *dev = client->dev;
+       int ret;
 
        mutex_lock(&dev->clientlist_mutex);
        list_add(&client->list, &dev->clientlist);
+
+       if (client->funcs && client->funcs->hotplug) {
+               /*
+                * Perform an initial hotplug event to pick up the
+                * display configuration for the client. This step
+                * has to be performed *after* registering the client
+                * in the list of clients, or a concurrent hotplug
+                * event might be lost; leaving the display off.
+                *
+                * Hold the clientlist_mutex as for a regular hotplug
+                * event.
+                */
+               ret = client->funcs->hotplug(client);
+               if (ret)
+                       drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
+       }
        mutex_unlock(&dev->clientlist_mutex);
 }
 EXPORT_SYMBOL(drm_client_register);
index 449ee16..d334a77 100644 (file)
@@ -2717,10 +2717,6 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
                preferred_bpp = 32;
        fb_helper->preferred_bpp = preferred_bpp;
 
-       ret = drm_fbdev_client_hotplug(&fb_helper->client);
-       if (ret)
-               drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
-
        drm_client_register(&fb_helper->client);
 }
 EXPORT_SYMBOL(drm_fbdev_generic_setup);