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

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.techSigned-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
parent 7a70b0b9
......@@ -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.
......
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