Unverified Commit 89c4bbe2 authored by Dave Stevenson's avatar Dave Stevenson Committed by Maxime Ripard
Browse files

drm/vc4: dsi: Release workaround buffer and DMA



On Pi0-3 the driver allocates a buffer and requests a DMA channel
because the ARM can't write to DSI1's registers directly.

However, we never release that buffer or channel. Let's add a
device-managed action to release each.

Fixes: 4078f575 ("drm/vc4: Add DSI driver")
Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20220613144800.326124-12-maxime@cerno.tech


Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
parent 7a70b0b9
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -1487,13 +1487,29 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi)
				      dsi->clk_onecell);
}

static void vc4_dsi_dma_mem_release(void *ptr)
{
	struct vc4_dsi *dsi = ptr;
	struct device *dev = &dsi->pdev->dev;

	dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr);
	dsi->reg_dma_mem = NULL;
}

static void vc4_dsi_dma_chan_release(void *ptr)
{
	struct vc4_dsi *dsi = ptr;

	dma_release_channel(dsi->reg_dma_chan);
	dsi->reg_dma_chan = NULL;
}

static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = dev_get_drvdata(master);
	struct vc4_dsi *dsi = dev_get_drvdata(dev);
	struct vc4_dsi_encoder *vc4_dsi_encoder;
	dma_cap_mask_t dma_mask;
	int ret;

	dsi->variant = of_device_get_match_data(dev);
@@ -1527,6 +1543,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
	 * so set up a channel for talking to it.
	 */
	if (dsi->variant->broken_axi_workaround) {
		dma_cap_mask_t dma_mask;

		dsi->reg_dma_mem = dma_alloc_coherent(dev, 4,
						      &dsi->reg_dma_paddr,
						      GFP_KERNEL);
@@ -1535,8 +1553,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
			return -ENOMEM;
		}

		ret = devm_add_action_or_reset(dev, vc4_dsi_dma_mem_release, dsi);
		if (ret)
			return ret;

		dma_cap_zero(dma_mask);
		dma_cap_set(DMA_MEMCPY, dma_mask);

		dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask);
		if (IS_ERR(dsi->reg_dma_chan)) {
			ret = PTR_ERR(dsi->reg_dma_chan);
@@ -1546,6 +1569,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
			return ret;
		}

		ret = devm_add_action_or_reset(dev, vc4_dsi_dma_chan_release, dsi);
		if (ret)
			return ret;

		/* Get the physical address of the device's registers.  The
		 * struct resource for the regs gives us the bus address
		 * instead.