提交 2d0a0745 编写于 作者: T Thomas Petazzoni

dma: mv_xor: use request_irq() instead of devm_request_irq()

Even through the usage of devm_*() functions is generally recommended
over their classic variants, in the case of devm_request_irq()
combined with irq_of_parse_and_map(), it doesn't work nicely.

We have the following scenario:

 irq_of_parse_and_map(...)
 devm_request_irq(...)

For some reason, the driver initialization fails at a later
point. Since irq_of_parse_and_map() is no device-managed, we do a:

 irq_dispose_mapping(...)

Unfortunately, this doesn't work, because the free_irq() must be done
prior to calling irq_dispose_mapping(). But with the devm mechanism,
the automatic free_irq() would happen only after we get out of the
->probe() function.

So basically, we revert to using request_irq() with traditional error
handling, so that in case of error, free_irq() gets called before
irq_dispose_mapping().
Signed-off-by: NThomas Petazzoni <thomas.petazzoni@free-electrons.com>
上级 c4b4b732
...@@ -1162,9 +1162,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev, ...@@ -1162,9 +1162,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
/* clear errors before enabling interrupts */ /* clear errors before enabling interrupts */
mv_xor_device_clear_err_status(mv_chan); mv_xor_device_clear_err_status(mv_chan);
ret = devm_request_irq(&pdev->dev, mv_chan->irq, ret = request_irq(mv_chan->irq, mv_xor_interrupt_handler,
mv_xor_interrupt_handler, 0, dev_name(&pdev->dev), mv_chan);
0, dev_name(&pdev->dev), mv_chan);
if (ret) if (ret)
goto err_free_dma; goto err_free_dma;
...@@ -1185,14 +1184,14 @@ mv_xor_channel_add(struct mv_xor_device *xordev, ...@@ -1185,14 +1184,14 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
ret = mv_xor_memcpy_self_test(mv_chan); ret = mv_xor_memcpy_self_test(mv_chan);
dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret); dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret);
if (ret) if (ret)
goto err_free_dma; goto err_free_irq;
} }
if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
ret = mv_xor_xor_self_test(mv_chan); ret = mv_xor_xor_self_test(mv_chan);
dev_dbg(&pdev->dev, "xor self test returned %d\n", ret); dev_dbg(&pdev->dev, "xor self test returned %d\n", ret);
if (ret) if (ret)
goto err_free_dma; goto err_free_irq;
} }
dev_info(&pdev->dev, "Marvell XOR: " dev_info(&pdev->dev, "Marvell XOR: "
...@@ -1205,6 +1204,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev, ...@@ -1205,6 +1204,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
dma_async_device_register(dma_dev); dma_async_device_register(dma_dev);
return mv_chan; return mv_chan;
err_free_irq:
free_irq(mv_chan->irq, mv_chan);
err_free_dma: err_free_dma:
dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE,
mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册