[PATCH 09/16] drm/udl: Support DRM hot-unplugging
Thomas Zimmermann
tzimmermann at suse.de
Mon Sep 19 13:04:01 UTC 2022
Add drm_dev_enter() and drm_dev_exit() to the various modesetting
functions that interact with the device. After hot-unplugging the
device, these functions will return early. So far, the udl driver
relied on USB interfaces to handle unplugging of the device.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
drivers/gpu/drm/udl/udl_modeset.c | 43 ++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 97d68cf88bd8..aaa828034a04 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -12,6 +12,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_damage_helper.h>
+#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -295,14 +296,21 @@ static const uint64_t udl_primary_plane_fmtmods[] = {
static void udl_primary_plane_helper_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
+ struct drm_device *dev = plane->dev;
struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb;
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct drm_rect rect;
+ int idx;
+
+ if (!drm_dev_enter(dev, &idx))
+ return;
if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &rect))
udl_handle_damage(fb, &shadow_plane_state->data[0], &rect);
+
+ drm_dev_exit(idx);
}
static void udl_primary_plane_helper_atomic_disable(struct drm_plane *plane,
@@ -348,10 +356,14 @@ static void udl_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom
struct drm_display_mode *mode = &crtc_state->mode;
struct urb *urb;
char *buf;
+ int idx;
+
+ if (!drm_dev_enter(dev, &idx))
+ return;
urb = udl_get_urb(dev);
if (!urb)
- return;
+ goto out;
buf = (char *)urb->transfer_buffer;
buf = udl_vidreg_lock(buf);
@@ -366,6 +378,9 @@ static void udl_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom
buf = udl_dummy_render(buf);
udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer);
+
+out:
+ drm_dev_exit(idx);
}
static void udl_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
@@ -373,10 +388,14 @@ static void udl_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato
struct drm_device *dev = crtc->dev;
struct urb *urb;
char *buf;
+ int idx;
+
+ if (!drm_dev_enter(dev, &idx))
+ return;
urb = udl_get_urb(dev);
if (!urb)
- return;
+ goto out;
buf = (char *)urb->transfer_buffer;
buf = udl_vidreg_lock(buf);
@@ -385,6 +404,9 @@ static void udl_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato
buf = udl_dummy_render(buf);
udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer);
+
+out:
+ drm_dev_exit(idx);
}
static const struct drm_crtc_helper_funcs udl_crtc_helper_funcs = {
@@ -471,17 +493,26 @@ static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, size_t le
static enum drm_connector_status udl_connector_detect(struct drm_connector *connector, bool force)
{
- struct udl_device *udl = to_udl(connector->dev);
+ struct drm_device *dev = connector->dev;
+ struct udl_device *udl = to_udl(dev);
struct udl_connector *udl_connector = to_udl_connector(connector);
+ enum drm_connector_status status = connector_status_disconnected;
+ int idx;
/* cleanup previous EDID */
kfree(udl_connector->edid);
+ udl_connector->edid = NULL;
- udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl);
- if (!udl_connector->edid)
+ if (!drm_dev_enter(dev, &idx))
return connector_status_disconnected;
- return connector_status_connected;
+ udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl);
+ if (udl_connector->edid)
+ status = connector_status_connected;
+
+ drm_dev_exit(idx);
+
+ return status;
}
static void udl_connector_destroy(struct drm_connector *connector)
--
2.37.3
More information about the dri-devel
mailing list