Skip to content

Commit

Permalink
drm/vc4: dsi: Release workaround buffer and DMA
Browse files Browse the repository at this point in the history
[ Upstream commit 89c4bbe ]

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: 4078f57 ("drm/vc4: Add DSI driver")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20220613144800.326124-12-maxime@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
6by9 authored and gregkh committed Aug 17, 2022
1 parent 3d722c0 commit 80e2db7
Showing 1 changed file with 28 additions and 1 deletion.
29 changes: 28 additions & 1 deletion drivers/gpu/drm/vc4/vc4_dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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.
Expand Down

0 comments on commit 80e2db7

Please sign in to comment.