]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
ARM: edma: Mark xbar related channels as used
authorMisael Lopez Cruz <misael.lopez@ti.com>
Tue, 26 May 2015 03:38:58 +0000 (22:38 -0500)
committerMisael Lopez Cruz <misael.lopez@ti.com>
Fri, 5 Jun 2015 20:51:46 +0000 (15:51 -0500)
eDMA channels not being used in the platform are assumed to
be without event association.  The ones detected as 'used'
are those from DT nodes whose "dmas" property have a direct
reference to the eDMA controller node.

However, when a DMA crossbar is present the "dmas" property
actually points to the crossbar node, not to the DMA controller.
The DMA crossbar related channels can be identified in the
controller's translation function and marked as 'used' in
the platform.

Due to the current direct mapping between DMA requests and eDMA
channels, it's possible that the DMA channel corresponding to
the crossbar-translated DMA request might have been already
taken by another client.  The conflict might occur if such
client uses memcpy transfer type.

Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
arch/arm/common/edma.c

index 1baa939a1383a2cac53cc14ab04b1a7d39d5ef02..aedad21f3bc263d6bf2342dc5b7deb9da0129a0a 100644 (file)
@@ -1584,6 +1584,18 @@ static struct of_dma_filter_info edma_filter_info = {
        .filter_fn = edma_filter_fn,
 };
 
+struct dma_chan *edma_of_xlate(struct of_phandle_args *dma_spec,
+                              struct of_dma *ofdma)
+{
+       struct dma_chan *chan = of_dma_simple_xlate(dma_spec, ofdma);
+
+       if (chan)
+               clear_bit(EDMA_CHAN_SLOT(dma_spec->args[0]),
+                         edma_cc[0]->edma_unused);
+
+       return chan;
+}
+
 static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
                                                      struct device_node *node)
 {
@@ -1600,7 +1612,7 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
 
        dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
        dma_cap_set(DMA_CYCLIC, edma_filter_info.dma_cap);
-       of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
+       of_dma_controller_register(dev->of_node, edma_of_xlate,
                                   &edma_filter_info);
 
        return info;