diff options
author | Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com> | 2021-08-27 09:21:44 +0000 |
---|---|---|
committer | Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com> | 2021-08-27 09:21:44 +0000 |
commit | 49ef8ef4cd120f04cd5b4f05fdf89fdfce961505 (patch) | |
tree | db18a88869914632873359eb366ca93ddcf6fba1 /drivers/dma | |
parent | ed8f0b9dafc6dfcfccb4507a8ae71aa294b2088b (diff) | |
parent | fd80923202c6bfd723742fc32426a7aa3632abaa (diff) |
Merge tag 'v5.4.143' into 5.4-2.3.x-imx
Linux 5.4.143
Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/of-dma.c | 9 | ||||
-rw-r--r-- | drivers/dma/sh/usb-dmac.c | 2 | ||||
-rw-r--r-- | drivers/dma/xilinx/xilinx_dma.c | 12 |
3 files changed, 20 insertions, 3 deletions
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index 4bbf4172b9bf..e3f1d4ab8e4f 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -65,8 +65,12 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, return NULL; ofdma_target = of_dma_find_controller(&dma_spec_target); - if (!ofdma_target) - return NULL; + if (!ofdma_target) { + ofdma->dma_router->route_free(ofdma->dma_router->dev, + route_data); + chan = ERR_PTR(-EPROBE_DEFER); + goto err; + } chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target); if (IS_ERR_OR_NULL(chan)) { @@ -77,6 +81,7 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, chan->route_data = route_data; } +err: /* * Need to put the node back since the ofdma->of_dma_route_allocate * has taken it for generating the new, translated dma_spec diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 8f7ceb698226..1cc06900153e 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -855,8 +855,8 @@ static int usb_dmac_probe(struct platform_device *pdev) error: of_dma_controller_free(pdev->dev.of_node); - pm_runtime_put(&pdev->dev); error_pm: + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 1b5f3e9f43d7..ce18bca45ff2 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -333,6 +333,7 @@ struct xilinx_dma_tx_descriptor { * @genlock: Support genlock mode * @err: Channel has errors * @idle: Check for channel idle + * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -370,6 +371,7 @@ struct xilinx_dma_chan { bool genlock; bool err; bool idle; + bool terminating; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -844,6 +846,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) /* Run any dependencies, then free the descriptor */ dma_run_dependencies(&desc->async_tx); xilinx_dma_free_tx_descriptor(chan, desc); + + /* + * While we ran a callback the user called a terminate function, + * which takes care of cleaning up any remaining descriptors + */ + if (chan->terminating) + break; } spin_unlock_irqrestore(&chan->lock, flags); @@ -1618,6 +1627,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) if (desc->cyclic) chan->cyclic = true; + chan->terminating = false; + spin_unlock_irqrestore(&chan->lock, flags); return cookie; @@ -2074,6 +2085,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan) } /* Remove and free all of the descriptors in the lists */ + chan->terminating = true; xilinx_dma_free_descriptors(chan); chan->idle = true; |