[Intel-gfx] [PATCH] [RFC] drm/kms: Add separate hotplug event call for drm connector

Mohammed Khajapasha mohammed.khajapasha at intel.com
Wed Sep 2 11:31:39 UTC 2020


Add separate hotplug event call for drm connector.
Currently from uevent, user space doesn't know
which connector got disconnected when multiple
connectors are connected to DRM.

Signed-off-by: Mohammed Khajapasha <mohammed.khajapasha at intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 30 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_sysfs.c        | 24 ++++++++++++++++++++++++
 include/drm/drm_probe_helper.h     |  2 ++
 include/drm/drm_sysfs.h            |  2 ++
 4 files changed, 58 insertions(+)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index d6017726cc2a..d9a38569cfe1 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -588,6 +588,36 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
 
+/**
+ * drm_kms_connector_hotplug_helper - fire off KMS connector hotplug event
+ * @dev: drm_device whose connector state changed
+ * @connector: drm_connector which connected/disconnected
+ *
+ * This function fires off the uevent for userspace and also calls the
+ * output_poll_changed function, which is most commonly used to inform the fbdev
+ * emulation code and allow it to update the fbcon output configuration.
+ *
+ * Drivers should call this from their hotplug handling code when a change is
+ * detected. Note that this function does not do any output detection of its
+ * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
+ * driver already.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ *
+ */
+void drm_kms_connector_hotplug_helper(struct drm_device *dev,
+		struct drm_connector *connector)
+{
+	drm_sysfs_connector_hotplug_event(dev, connector);
+
+	if (dev->mode_config.funcs->output_poll_changed)
+		dev->mode_config.funcs->output_poll_changed(dev);
+
+	drm_client_dev_hotplug(dev);
+}
+EXPORT_SYMBOL(drm_kms_connector_hotplug_helper);
+
 /**
  * drm_kms_helper_hotplug_event - fire off KMS hotplug events
  * @dev: drm_device whose connector state changed
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index f0336c804639..10016a61d468 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -344,6 +344,30 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+/**
+ * drm_sysfs_connector_hotplug_event - generate a connector hotplug uevent
+ * @dev: DRM device
+ * @connector: drm_connector which connect/disconnected for hotplug
+ *
+ * Send a uevent for the DRM device specified by @dev. Currently we only
+ * set HOTPLUG=1 and connector id in the uevent environment, but this could be
+ * expanded to deal with other types of events.
+ */
+void drm_sysfs_connector_hotplug_event(struct drm_device *dev,
+		struct drm_connector *connector)
+{
+	char hotplug_str[] = "HOTPLUG=1", conn_id[21];
+	char *envp[] = { hotplug_str, conn_id, NULL };
+
+	snprintf(conn_id, ARRAY_SIZE(conn_id),
+			"CONNECTOR=%u", connector->base.id);
+
+	DRM_DEBUG("generating connector hotplug event\n");
+
+	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(drm_sysfs_connector_hotplug_event);
+
 /**
  * drm_sysfs_connector_status_event - generate a DRM uevent for connector
  * property status change
diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h
index 8d3ed2834d34..813475adaf01 100644
--- a/include/drm/drm_probe_helper.h
+++ b/include/drm/drm_probe_helper.h
@@ -19,6 +19,8 @@ void drm_kms_helper_poll_init(struct drm_device *dev);
 void drm_kms_helper_poll_fini(struct drm_device *dev);
 bool drm_helper_hpd_irq_event(struct drm_device *dev);
 void drm_kms_helper_hotplug_event(struct drm_device *dev);
+void drm_kms_connector_hotplug_helper(struct drm_device *dev,
+		struct drm_connector *connector);
 
 void drm_kms_helper_poll_disable(struct drm_device *dev);
 void drm_kms_helper_poll_enable(struct drm_device *dev);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index d454ef617b2c..1be92541df84 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -11,6 +11,8 @@ int drm_class_device_register(struct device *dev);
 void drm_class_device_unregister(struct device *dev);
 
 void drm_sysfs_hotplug_event(struct drm_device *dev);
+void drm_sysfs_connector_hotplug_event(struct drm_device *dev,
+		struct drm_connector *connector);
 void drm_sysfs_connector_status_event(struct drm_connector *connector,
 				      struct drm_property *property);
 #endif
-- 
2.24.1



More information about the Intel-gfx mailing list