Skip to content

Commit

Permalink
dmaengine: ti-dma-crossbar: dra7: Use bitops instead of idr
Browse files Browse the repository at this point in the history
The use of idr was nice, but it was a bit heavy and we did not need the
features it provides. Using simple bitmap to track allocated DMA channels
is adequate here and it will be easier to add support for reserving
channels later on.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
  • Loading branch information
Peter Ujfalusi authored and Vinod Koul committed Nov 30, 2015
1 parent 2adb274 commit ec9bfa1
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions drivers/dma/ti-dma-crossbar.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
#include <linux/idr.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
Expand Down Expand Up @@ -198,7 +197,8 @@ struct ti_dra7_xbar_data {
void __iomem *iomem;

struct dma_router dmarouter;
struct idr map_idr;
struct mutex mutex;
unsigned long *dma_inuse;

u16 safe_val; /* Value to rest the crossbar lines */
u32 xbar_requests; /* number of DMA requests connected to XBAR */
Expand All @@ -225,7 +225,9 @@ static void ti_dra7_xbar_free(struct device *dev, void *route_data)
map->xbar_in, map->xbar_out);

ti_dra7_xbar_write(xbar->iomem, map->xbar_out, xbar->safe_val);
idr_remove(&xbar->map_idr, map->xbar_out);
mutex_lock(&xbar->mutex);
clear_bit(map->xbar_out, xbar->dma_inuse);
mutex_unlock(&xbar->mutex);
kfree(map);
}

Expand Down Expand Up @@ -255,8 +257,17 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
return ERR_PTR(-ENOMEM);
}

map->xbar_out = idr_alloc(&xbar->map_idr, NULL, 0, xbar->dma_requests,
GFP_KERNEL);
mutex_lock(&xbar->mutex);
map->xbar_out = find_first_zero_bit(xbar->dma_inuse,
xbar->dma_requests);
mutex_unlock(&xbar->mutex);
if (map->xbar_out == xbar->dma_requests) {
dev_err(&pdev->dev, "Run out of free DMA requests\n");
kfree(map);
return ERR_PTR(-ENOMEM);
}
set_bit(map->xbar_out, xbar->dma_inuse);

map->xbar_in = (u16)dma_spec->args[0];

dma_spec->args[0] = map->xbar_out + xbar->dma_offset;
Expand Down Expand Up @@ -303,8 +314,6 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
if (!xbar)
return -ENOMEM;

idr_init(&xbar->map_idr);

dma_node = of_parse_phandle(node, "dma-masters", 0);
if (!dma_node) {
dev_err(&pdev->dev, "Can't get DMA master node\n");
Expand All @@ -326,6 +335,12 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
}
of_node_put(dma_node);

xbar->dma_inuse = devm_kcalloc(&pdev->dev,
BITS_TO_LONGS(xbar->dma_requests),
sizeof(unsigned long), GFP_KERNEL);
if (!xbar->dma_inuse)
return -ENOMEM;

if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
dev_info(&pdev->dev,
"Missing XBAR input information, using %u.\n",
Expand All @@ -347,6 +362,7 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
xbar->dmarouter.route_free = ti_dra7_xbar_free;
xbar->dma_offset = (u32)match->data;

mutex_init(&xbar->mutex);
platform_set_drvdata(pdev, xbar);

/* Reset the crossbar */
Expand Down

0 comments on commit ec9bfa1

Please sign in to comment.