diff options
-rw-r--r-- | drivers/dma/dw/core.c | 34 |
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) | |||
130 | static void dwc_initialize(struct dw_dma_chan *dwc) | 130 | static 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 */ |