--- /dev/null
+From f22a11fdd33c8562461eda672b330307059b0912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Oct 2018 15:15:28 +0100
+Subject: dmaengine: imx-sdma: remove dma_slave_config direction usage and
+ leave sdma_event_enable()
+
+From: Vinod Koul <vkoul@kernel.org>
+
+[ Upstream commit 107d06441b709d31ce592535086992799ee51e17 ]
+
+dma_slave_config direction was marked as deprecated quite some
+time back, remove the usage from this driver so that the field
+can be removed
+
+ENBLn bit should be set before any dma request triggered, please
+refer to the below information from i.mx6sololite RM. Otherwise,
+spi/uart test will be fail because there is dma request from tx
+fifo always before dmaengine_prep_slave_sg() in where ENBLn set
+and violate the below rule.
+
+https://www.nxp.com/docs/en/reference-manual/IMX6SLRM.pdf:
+
+40.8.28 Channel Enable RAM (SDMAARM_CHNENBLn)
+"It is thus essential for the Arm platform to program them before
+any DMA request is triggered to the SDMA, otherwise an unpredictable
+combination of channels may be started".
+
+Signed-off-by: Robin Gong <yibin.gong@nxp.com>
+[vkoul: sqashed patch from Robin into direction change]
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/imx-sdma.c | 56 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 39 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
+index ceb82e74f5b4e..eea89c3b54c1e 100644
+--- a/drivers/dma/imx-sdma.c
++++ b/drivers/dma/imx-sdma.c
+@@ -335,6 +335,7 @@ struct sdma_desc {
+ * @sdma: pointer to the SDMA engine for this channel
+ * @channel: the channel number, matches dmaengine chan_id + 1
+ * @direction: transfer type. Needed for setting SDMA script
++ * @slave_config Slave configuration
+ * @peripheral_type: Peripheral type. Needed for setting SDMA script
+ * @event_id0: aka dma request line
+ * @event_id1: for channels that use 2 events
+@@ -362,6 +363,7 @@ struct sdma_channel {
+ struct sdma_engine *sdma;
+ unsigned int channel;
+ enum dma_transfer_direction direction;
++ struct dma_slave_config slave_config;
+ enum sdma_peripheral_type peripheral_type;
+ unsigned int event_id0;
+ unsigned int event_id1;
+@@ -440,6 +442,10 @@ struct sdma_engine {
+ struct sdma_buffer_descriptor *bd0;
+ };
+
++static int sdma_config_write(struct dma_chan *chan,
++ struct dma_slave_config *dmaengine_cfg,
++ enum dma_transfer_direction direction);
++
+ static struct sdma_driver_data sdma_imx31 = {
+ .chnenbl0 = SDMA_CHNENBL0_IMX31,
+ .num_events = 32,
+@@ -1122,18 +1128,6 @@ static int sdma_config_channel(struct dma_chan *chan)
+ sdmac->shp_addr = 0;
+ sdmac->per_addr = 0;
+
+- if (sdmac->event_id0) {
+- if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
+- return -EINVAL;
+- sdma_event_enable(sdmac, sdmac->event_id0);
+- }
+-
+- if (sdmac->event_id1) {
+- if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
+- return -EINVAL;
+- sdma_event_enable(sdmac, sdmac->event_id1);
+- }
+-
+ switch (sdmac->peripheral_type) {
+ case IMX_DMATYPE_DSP:
+ sdma_config_ownership(sdmac, false, true, true);
+@@ -1431,6 +1425,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
+ struct scatterlist *sg;
+ struct sdma_desc *desc;
+
++ sdma_config_write(chan, &sdmac->slave_config, direction);
++
+ desc = sdma_transfer_init(sdmac, direction, sg_len);
+ if (!desc)
+ goto err_out;
+@@ -1515,6 +1511,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
+
+ dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
+
++ sdma_config_write(chan, &sdmac->slave_config, direction);
++
+ desc = sdma_transfer_init(sdmac, direction, num_periods);
+ if (!desc)
+ goto err_out;
+@@ -1570,17 +1568,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
+ return NULL;
+ }
+
+-static int sdma_config(struct dma_chan *chan,
+- struct dma_slave_config *dmaengine_cfg)
++static int sdma_config_write(struct dma_chan *chan,
++ struct dma_slave_config *dmaengine_cfg,
++ enum dma_transfer_direction direction)
+ {
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
+
+- if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
++ if (direction == DMA_DEV_TO_MEM) {
+ sdmac->per_address = dmaengine_cfg->src_addr;
+ sdmac->watermark_level = dmaengine_cfg->src_maxburst *
+ dmaengine_cfg->src_addr_width;
+ sdmac->word_size = dmaengine_cfg->src_addr_width;
+- } else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
++ } else if (direction == DMA_DEV_TO_DEV) {
+ sdmac->per_address2 = dmaengine_cfg->src_addr;
+ sdmac->per_address = dmaengine_cfg->dst_addr;
+ sdmac->watermark_level = dmaengine_cfg->src_maxburst &
+@@ -1594,10 +1593,33 @@ static int sdma_config(struct dma_chan *chan,
+ dmaengine_cfg->dst_addr_width;
+ sdmac->word_size = dmaengine_cfg->dst_addr_width;
+ }
+- sdmac->direction = dmaengine_cfg->direction;
++ sdmac->direction = direction;
+ return sdma_config_channel(chan);
+ }
+
++static int sdma_config(struct dma_chan *chan,
++ struct dma_slave_config *dmaengine_cfg)
++{
++ struct sdma_channel *sdmac = to_sdma_chan(chan);
++
++ memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
++
++ /* Set ENBLn earlier to make sure dma request triggered after that */
++ if (sdmac->event_id0) {
++ if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
++ return -EINVAL;
++ sdma_event_enable(sdmac, sdmac->event_id0);
++ }
++
++ if (sdmac->event_id1) {
++ if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
++ return -EINVAL;
++ sdma_event_enable(sdmac, sdmac->event_id1);
++ }
++
++ return 0;
++}
++
+ static enum dma_status sdma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+--
+2.20.1
+