diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2017-01-02 05:07:37 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-19 14:18:03 -0500 |
commit | 6c6ae8c43df99284b3260082b43b5858b701bd5e (patch) | |
tree | 1ed30b38bdc5583aecafdb7ad611c56501cac286 | |
parent | 3fbaff3adc763d999fa803bc1aeb5e49c48ce5c0 (diff) |
dmaengine: omap-dma: Fix dynamic lch_map allocation
commit 836c3ce2566fb8c1754f8d7c9534cad9bc8a6879 upstream.
The original patch did not done what it was supposed to be doing and even
worst it broke legacy boot (OMAP1).
The lch_map size should be the number of available logical channels in sDMA
and the od->dma_requests should store the number of available DMA request
lines usable in sDMA.
In legacy mode we do not have a way to get the DMA request count, in that
case we use OMAP_SDMA_REQUESTS (127), despite the fact that OMAP1510 have
only 31 DMA request line.
Fixes: 2d1a9a946fae ("dmaengine: omap-dma: Dynamically allocate memory for lch_map")
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/dma/omap-dma.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 7ca27d4b1c54..6b16ce390dce 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c | |||
@@ -1339,6 +1339,7 @@ static int omap_dma_probe(struct platform_device *pdev) | |||
1339 | struct omap_dmadev *od; | 1339 | struct omap_dmadev *od; |
1340 | struct resource *res; | 1340 | struct resource *res; |
1341 | int rc, i, irq; | 1341 | int rc, i, irq; |
1342 | u32 lch_count; | ||
1342 | 1343 | ||
1343 | od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL); | 1344 | od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL); |
1344 | if (!od) | 1345 | if (!od) |
@@ -1381,20 +1382,31 @@ static int omap_dma_probe(struct platform_device *pdev) | |||
1381 | spin_lock_init(&od->lock); | 1382 | spin_lock_init(&od->lock); |
1382 | spin_lock_init(&od->irq_lock); | 1383 | spin_lock_init(&od->irq_lock); |
1383 | 1384 | ||
1384 | if (!pdev->dev.of_node) { | 1385 | /* Number of DMA requests */ |
1385 | od->dma_requests = od->plat->dma_attr->lch_count; | 1386 | od->dma_requests = OMAP_SDMA_REQUESTS; |
1386 | if (unlikely(!od->dma_requests)) | 1387 | if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node, |
1387 | od->dma_requests = OMAP_SDMA_REQUESTS; | 1388 | "dma-requests", |
1388 | } else if (of_property_read_u32(pdev->dev.of_node, "dma-requests", | 1389 | &od->dma_requests)) { |
1389 | &od->dma_requests)) { | ||
1390 | dev_info(&pdev->dev, | 1390 | dev_info(&pdev->dev, |
1391 | "Missing dma-requests property, using %u.\n", | 1391 | "Missing dma-requests property, using %u.\n", |
1392 | OMAP_SDMA_REQUESTS); | 1392 | OMAP_SDMA_REQUESTS); |
1393 | od->dma_requests = OMAP_SDMA_REQUESTS; | ||
1394 | } | 1393 | } |
1395 | 1394 | ||
1396 | od->lch_map = devm_kcalloc(&pdev->dev, od->dma_requests, | 1395 | /* Number of available logical channels */ |
1397 | sizeof(*od->lch_map), GFP_KERNEL); | 1396 | if (!pdev->dev.of_node) { |
1397 | lch_count = od->plat->dma_attr->lch_count; | ||
1398 | if (unlikely(!lch_count)) | ||
1399 | lch_count = OMAP_SDMA_CHANNELS; | ||
1400 | } else if (of_property_read_u32(pdev->dev.of_node, "dma-channels", | ||
1401 | &lch_count)) { | ||
1402 | dev_info(&pdev->dev, | ||
1403 | "Missing dma-channels property, using %u.\n", | ||
1404 | OMAP_SDMA_CHANNELS); | ||
1405 | lch_count = OMAP_SDMA_CHANNELS; | ||
1406 | } | ||
1407 | |||
1408 | od->lch_map = devm_kcalloc(&pdev->dev, lch_count, sizeof(*od->lch_map), | ||
1409 | GFP_KERNEL); | ||
1398 | if (!od->lch_map) | 1410 | if (!od->lch_map) |
1399 | return -ENOMEM; | 1411 | return -ENOMEM; |
1400 | 1412 | ||