|
@@ -22,6 +22,7 @@
|
|
|
#include <mach/regs-icu.h>
|
|
|
#include <linux/platform_data/dma-mmp_tdma.h>
|
|
|
#include <linux/of_device.h>
|
|
|
+#include <linux/of_dma.h>
|
|
|
|
|
|
#include "dmaengine.h"
|
|
|
|
|
@@ -541,6 +542,45 @@ static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+struct mmp_tdma_filter_param {
|
|
|
+ struct device_node *of_node;
|
|
|
+ unsigned int chan_id;
|
|
|
+};
|
|
|
+
|
|
|
+static bool mmp_tdma_filter_fn(struct dma_chan *chan, void *fn_param)
|
|
|
+{
|
|
|
+ struct mmp_tdma_filter_param *param = fn_param;
|
|
|
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
|
|
|
+ struct dma_device *pdma_device = tdmac->chan.device;
|
|
|
+
|
|
|
+ if (pdma_device->dev->of_node != param->of_node)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (chan->chan_id != param->chan_id)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+struct dma_chan *mmp_tdma_xlate(struct of_phandle_args *dma_spec,
|
|
|
+ struct of_dma *ofdma)
|
|
|
+{
|
|
|
+ struct mmp_tdma_device *tdev = ofdma->of_dma_data;
|
|
|
+ dma_cap_mask_t mask = tdev->device.cap_mask;
|
|
|
+ struct mmp_tdma_filter_param param;
|
|
|
+
|
|
|
+ if (dma_spec->args_count != 1)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ param.of_node = ofdma->of_node;
|
|
|
+ param.chan_id = dma_spec->args[0];
|
|
|
+
|
|
|
+ if (param.chan_id >= TDMA_CHANNEL_NUM)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ return dma_request_channel(mask, mmp_tdma_filter_fn, ¶m);
|
|
|
+}
|
|
|
+
|
|
|
static struct of_device_id mmp_tdma_dt_ids[] = {
|
|
|
{ .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA},
|
|
|
{ .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU},
|
|
@@ -631,6 +671,16 @@ static int mmp_tdma_probe(struct platform_device *pdev)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ if (pdev->dev.of_node) {
|
|
|
+ ret = of_dma_controller_register(pdev->dev.of_node,
|
|
|
+ mmp_tdma_xlate, tdev);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(tdev->device.dev,
|
|
|
+ "failed to register controller\n");
|
|
|
+ dma_async_device_unregister(&tdev->device);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
dev_info(tdev->device.dev, "initialized\n");
|
|
|
return 0;
|
|
|
}
|