summaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/edma.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index aeb67e0..d5a76c6 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -113,23 +113,6 @@
#define CHMAP_EXIST BIT(24)
/*
- * This will go away when the private EDMA API is folded
- * into this driver and the platform device(s) are
- * instantiated in the arch code. We can only get away
- * with this simplification because DA8XX may not be built
- * in the same kernel image with other DaVinci parts. This
- * avoids having to sprinkle dmaengine driver platform devices
- * and data throughout all the existing board files.
- */
-#ifdef CONFIG_ARCH_DAVINCI_DA8XX
-#define EDMA_CTLRS 2
-#define EDMA_CHANS 32
-#else
-#define EDMA_CTLRS 1
-#define EDMA_CHANS 64
-#endif /* CONFIG_ARCH_DAVINCI_DA8XX */
-
-/*
* Max of 20 segments per channel to conserve PaRAM slots
* Also note that MAX_NR_SG should be atleast the no.of periods
* that are required for ASoC, otherwise DMA prep calls will
@@ -140,16 +123,12 @@
#define EDMA_MAX_SLOTS MAX_NR_SG
#define EDMA_DESCRIPTORS 16
-#define EDMA_MAX_PARAMENTRY 512
-
#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
#define EDMA_CONT_PARAMS_ANY 1001
#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
-#define EDMA_MAX_CC 2
-
/* PaRAM slots are laid out like this */
struct edmacc_param {
u32 opt;
@@ -256,22 +235,22 @@ struct edma_cc {
/* The edma_inuse bit for each PaRAM slot is clear unless the
* channel is in use ... by ARM or DSP, for QDMA, or whatever.
*/
- DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+ unsigned long *edma_inuse;
/* The edma_unused bit for each channel is clear unless
* it is not being used on this platform. It uses a bit
* of SOC-specific initialization code.
*/
- DECLARE_BITMAP(edma_unused, EDMA_CHANS);
+ unsigned long *edma_unused;
struct dma_interrupt_data {
void (*callback)(unsigned channel, unsigned short ch_status,
void *data);
void *data;
- } intr_data[EDMA_CHANS];
+ } *intr_data;
struct dma_device dma_slave;
- struct edma_chan slave_chans[EDMA_CHANS];
+ struct edma_chan *slave_chans;
int dummy_slot;
};
@@ -457,6 +436,8 @@ static int prepare_unused_channel_list(struct device *dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct edma_cc *ecc = data;
+ int dma_req_min = EDMA_CTLR_CHAN(ecc->id, 0);
+ int dma_req_max = dma_req_min + ecc->num_channels;
int i, count;
struct of_phandle_args dma_spec;
@@ -491,11 +472,15 @@ static int prepare_unused_channel_list(struct device *dev, void *data)
/* For non-OF case */
for (i = 0; i < pdev->num_resources; i++) {
struct resource *res = &pdev->resource[i];
+ int dma_req;
+
+ if (!(res->flags & IORESOURCE_DMA))
+ continue;
- if ((res->flags & IORESOURCE_DMA) && (int)res->start >= 0) {
+ dma_req = (int)res->start;
+ if (dma_req >= dma_req_min && dma_req < dma_req_max)
clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
ecc->edma_unused);
- }
}
return 0;
@@ -1978,7 +1963,7 @@ static void __init edma_chan_init(struct edma_cc *ecc, struct dma_device *dma,
{
int i, j;
- for (i = 0; i < EDMA_CHANS; i++) {
+ for (i = 0; i < ecc->num_channels; i++) {
struct edma_chan *echan = &echans[i];
echan->ch_num = EDMA_CTLR_CHAN(ecc->id, i);
echan->ecc = ecc;
@@ -2247,6 +2232,27 @@ static int edma_probe(struct platform_device *pdev)
if (ret)
return ret;
+ /* Allocate memory based on the information we got from the IP */
+ ecc->slave_chans = devm_kcalloc(dev, ecc->num_channels,
+ sizeof(*ecc->slave_chans), GFP_KERNEL);
+ if (!ecc->slave_chans)
+ return -ENOMEM;
+
+ ecc->intr_data = devm_kcalloc(dev, ecc->num_channels,
+ sizeof(*ecc->intr_data), GFP_KERNEL);
+ if (!ecc->intr_data)
+ return -ENOMEM;
+
+ ecc->edma_unused = devm_kcalloc(dev, BITS_TO_LONGS(ecc->num_channels),
+ sizeof(unsigned long), GFP_KERNEL);
+ if (!ecc->edma_unused)
+ return -ENOMEM;
+
+ ecc->edma_inuse = devm_kcalloc(dev, BITS_TO_LONGS(ecc->num_slots),
+ sizeof(unsigned long), GFP_KERNEL);
+ if (!ecc->edma_inuse)
+ return -ENOMEM;
+
ecc->default_queue = info->default_queue;
for (i = 0; i < ecc->num_slots; i++)
OpenPOWER on IntegriCloud