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: 4078f5757144 ("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>
This commit is contained in:
parent
7a70b0b978
commit
89c4bbe2a0
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user