Commit 71b1bd4c authored by Maxime Ripard's avatar Maxime Ripard

drm/vc4: dpi: Protect device resources

Our current code now mixes some resources whose lifetime are tied to the
device (clocks, IO mappings, etc.) and some that are tied to the DRM device
(encoder, bridge).

The device one will be freed at unbind time, but the DRM one will only be
freed when the last user of the DRM device closes its file handle.

So we end up with a time window during which we can call the encoder hooks,
but we don't have access to the underlying resources and device.

Let's protect all those sections with drm_dev_enter() and drm_dev_exit() so
that we bail out if we are during that window.
Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20220711173939.1132294-32-maxime@cerno.tech
parent 055af023
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h> #include <drm/drm_bridge.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include <drm/drm_panel.h> #include <drm/drm_panel.h>
...@@ -112,9 +113,16 @@ static const struct debugfs_reg32 dpi_regs[] = { ...@@ -112,9 +113,16 @@ static const struct debugfs_reg32 dpi_regs[] = {
static void vc4_dpi_encoder_disable(struct drm_encoder *encoder) static void vc4_dpi_encoder_disable(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev;
struct vc4_dpi *dpi = to_vc4_dpi(encoder); struct vc4_dpi *dpi = to_vc4_dpi(encoder);
int idx;
if (!drm_dev_enter(dev, &idx))
return;
clk_disable_unprepare(dpi->pixel_clock); clk_disable_unprepare(dpi->pixel_clock);
drm_dev_exit(idx);
} }
static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
...@@ -125,6 +133,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) ...@@ -125,6 +133,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
struct drm_connector_list_iter conn_iter; struct drm_connector_list_iter conn_iter;
struct drm_connector *connector = NULL, *connector_scan; struct drm_connector *connector = NULL, *connector_scan;
u32 dpi_c = DPI_ENABLE; u32 dpi_c = DPI_ENABLE;
int idx;
int ret; int ret;
/* Look up the connector attached to DPI so we can get the /* Look up the connector attached to DPI so we can get the
...@@ -204,6 +213,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) ...@@ -204,6 +213,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
dpi_c |= DPI_VSYNC_DISABLE; dpi_c |= DPI_VSYNC_DISABLE;
} }
if (!drm_dev_enter(dev, &idx))
return;
DPI_WRITE(DPI_C, dpi_c); DPI_WRITE(DPI_C, dpi_c);
ret = clk_set_rate(dpi->pixel_clock, mode->clock * 1000); ret = clk_set_rate(dpi->pixel_clock, mode->clock * 1000);
...@@ -213,6 +225,8 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) ...@@ -213,6 +225,8 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
ret = clk_prepare_enable(dpi->pixel_clock); ret = clk_prepare_enable(dpi->pixel_clock);
if (ret) if (ret)
DRM_ERROR("Failed to set clock rate: %d\n", ret); DRM_ERROR("Failed to set clock rate: %d\n", ret);
drm_dev_exit(idx);
} }
static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder *encoder, static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder *encoder,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment