From 0aedc43f0b847ed48f96fcdd6dc0ccbf21e2a4ca Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Thu, 1 Jun 2017 16:35:59 -0700 Subject: drm: msm: add support for a custom hotplug event Add support for a custom hotplug event that is triggered when the status of the connector has changed. The event string of the custom event will be in the following format: "name= status=" For example, when the DisplayPort connector has its status updated to connected then the event string that is used as part of the hotplug event will be as follows: "name=DP-1 status=connected" If the connector name is not known or is invalid at the time that the event is triggered then the name will be reported as "unknown". Change-Id: I5d6164d1e8e651cb05527733d68fa86fefb9e6ce Signed-off-by: Tatenda Chipeperekwa Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/msm_drv.c | 59 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index a441f3d15542..87faf3844bc9 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -26,11 +26,68 @@ #include "msm_gem.h" #include "msm_mmu.h" +static void msm_drm_helper_hotplug_event(struct drm_device *dev) +{ + struct drm_connector *connector; + char *event_string; + char const *connector_name; + char *envp[2]; + + if (!dev) { + DRM_ERROR("hotplug_event failed, invalid input\n"); + return; + } + + if (!dev->mode_config.poll_enabled) + return; + + event_string = kzalloc(SZ_4K, GFP_KERNEL); + if (!event_string) { + DRM_ERROR("failed to allocate event string\n"); + return; + } + + mutex_lock(&dev->mode_config.mutex); + drm_for_each_connector(connector, dev) { + /* Only handle HPD capable connectors. */ + if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) + continue; + + connector->status = connector->funcs->detect(connector, false); + + if (connector->name) + connector_name = connector->name; + else + connector_name = "unknown"; + + snprintf(event_string, SZ_4K, "name=%s status=%s\n", + connector_name, + drm_get_connector_status_name(connector->status)); + DRM_DEBUG("generating hotplug event [%s]\n", event_string); + envp[0] = event_string; + envp[1] = NULL; + kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, + envp); + } + mutex_unlock(&dev->mode_config.mutex); + kfree(event_string); +} + static void msm_fb_output_poll_changed(struct drm_device *dev) { - struct msm_drm_private *priv = dev->dev_private; + struct msm_drm_private *priv = NULL; + + if (!dev) { + DRM_ERROR("output_poll_changed failed, invalid input\n"); + return; + } + + priv = dev->dev_private; + if (priv->fbdev) drm_fb_helper_hotplug_event(priv->fbdev); + else + msm_drm_helper_hotplug_event(dev); } static const struct drm_mode_config_funcs mode_config_funcs = { -- cgit v1.2.3