aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/dw/core.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 5ad0ec1f0e29..97199b3c25a2 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
130static void dwc_initialize(struct dw_dma_chan *dwc) 130static void dwc_initialize(struct dw_dma_chan *dwc)
131{ 131{
132 struct dw_dma *dw = to_dw_dma(dwc->chan.device); 132 struct dw_dma *dw = to_dw_dma(dwc->chan.device);
133 struct dw_dma_slave *dws = dwc->chan.private;
134 u32 cfghi = DWC_CFGH_FIFO_MODE; 133 u32 cfghi = DWC_CFGH_FIFO_MODE;
135 u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); 134 u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
136 135
137 if (dwc->initialized == true) 136 if (dwc->initialized == true)
138 return; 137 return;
139 138
140 if (dws) { 139 cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
141 /* 140 cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
142 * We need controller-specific data to set up slave
143 * transfers.
144 */
145 BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
146
147 cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
148 cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
149 } else {
150 cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
151 cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
152 }
153 141
154 channel_writel(dwc, CFG_LO, cfglo); 142 channel_writel(dwc, CFG_LO, cfglo);
155 channel_writel(dwc, CFG_HI, cfghi); 143 channel_writel(dwc, CFG_HI, cfghi);
@@ -941,7 +929,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
941 struct dw_dma_chan *dwc = to_dw_dma_chan(chan); 929 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
942 struct dw_dma_slave *dws = param; 930 struct dw_dma_slave *dws = param;
943 931
944 if (!dws || dws->dma_dev != chan->device->dev) 932 if (dws->dma_dev != chan->device->dev)
945 return false; 933 return false;
946 934
947 /* We have to copy data since dws can be temporary storage */ 935 /* We have to copy data since dws can be temporary storage */
@@ -1165,6 +1153,14 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
1165 * doesn't mean what you think it means), and status writeback. 1153 * doesn't mean what you think it means), and status writeback.
1166 */ 1154 */
1167 1155
1156 /*
1157 * We need controller-specific data to set up slave transfers.
1158 */
1159 if (chan->private && !dw_dma_filter(chan, chan->private)) {
1160 dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
1161 return -EINVAL;
1162 }
1163
1168 /* Enable controller here if needed */ 1164 /* Enable controller here if needed */
1169 if (!dw->in_use) 1165 if (!dw->in_use)
1170 dw_dma_on(dw); 1166 dw_dma_on(dw);
@@ -1226,6 +1222,14 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
1226 spin_lock_irqsave(&dwc->lock, flags); 1222 spin_lock_irqsave(&dwc->lock, flags);
1227 list_splice_init(&dwc->free_list, &list); 1223 list_splice_init(&dwc->free_list, &list);
1228 dwc->descs_allocated = 0; 1224 dwc->descs_allocated = 0;
1225
1226 /* Clear custom channel configuration */
1227 dwc->src_id = 0;
1228 dwc->dst_id = 0;
1229
1230 dwc->src_master = 0;
1231 dwc->dst_master = 0;
1232
1229 dwc->initialized = false; 1233 dwc->initialized = false;
1230 1234
1231 /* Disable interrupts */ 1235 /* Disable interrupts */