diff options
-rw-r--r-- | drivers/dma/dw/core.c | 34 | ||||
-rw-r--r-- | drivers/dma/hsu/hsu.c | 13 | ||||
-rw-r--r-- | drivers/dma/hsu/hsu.h | 3 |
3 files changed, 30 insertions, 20 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 */ |
diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index eef145edb936..ee510515ce18 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c | |||
@@ -64,10 +64,10 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc) | |||
64 | 64 | ||
65 | if (hsuc->direction == DMA_MEM_TO_DEV) { | 65 | if (hsuc->direction == DMA_MEM_TO_DEV) { |
66 | bsr = config->dst_maxburst; | 66 | bsr = config->dst_maxburst; |
67 | mtsr = config->dst_addr_width; | 67 | mtsr = config->src_addr_width; |
68 | } else if (hsuc->direction == DMA_DEV_TO_MEM) { | 68 | } else if (hsuc->direction == DMA_DEV_TO_MEM) { |
69 | bsr = config->src_maxburst; | 69 | bsr = config->src_maxburst; |
70 | mtsr = config->src_addr_width; | 70 | mtsr = config->dst_addr_width; |
71 | } | 71 | } |
72 | 72 | ||
73 | hsu_chan_disable(hsuc); | 73 | hsu_chan_disable(hsuc); |
@@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc) | |||
135 | sr = hsu_chan_readl(hsuc, HSU_CH_SR); | 135 | sr = hsu_chan_readl(hsuc, HSU_CH_SR); |
136 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); | 136 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); |
137 | 137 | ||
138 | return sr; | 138 | return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY); |
139 | } | 139 | } |
140 | 140 | ||
141 | irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) | 141 | irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) |
@@ -254,10 +254,13 @@ static void hsu_dma_issue_pending(struct dma_chan *chan) | |||
254 | static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) | 254 | static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) |
255 | { | 255 | { |
256 | struct hsu_dma_desc *desc = hsuc->desc; | 256 | struct hsu_dma_desc *desc = hsuc->desc; |
257 | size_t bytes = desc->length; | 257 | size_t bytes = 0; |
258 | int i; | 258 | int i; |
259 | 259 | ||
260 | i = desc->active % HSU_DMA_CHAN_NR_DESC; | 260 | for (i = desc->active; i < desc->nents; i++) |
261 | bytes += desc->sg[i].len; | ||
262 | |||
263 | i = HSU_DMA_CHAN_NR_DESC - 1; | ||
261 | do { | 264 | do { |
262 | bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i)); | 265 | bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i)); |
263 | } while (--i >= 0); | 266 | } while (--i >= 0); |
diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h index 578a8ee8cd05..6b070c22b1df 100644 --- a/drivers/dma/hsu/hsu.h +++ b/drivers/dma/hsu/hsu.h | |||
@@ -41,6 +41,9 @@ | |||
41 | #define HSU_CH_SR_DESCTO(x) BIT(8 + (x)) | 41 | #define HSU_CH_SR_DESCTO(x) BIT(8 + (x)) |
42 | #define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8)) | 42 | #define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8)) |
43 | #define HSU_CH_SR_CHE BIT(15) | 43 | #define HSU_CH_SR_CHE BIT(15) |
44 | #define HSU_CH_SR_DESCE(x) BIT(16 + (x)) | ||
45 | #define HSU_CH_SR_DESCE_ANY (BIT(19) | BIT(18) | BIT(17) | BIT(16)) | ||
46 | #define HSU_CH_SR_CDESC_ANY (BIT(31) | BIT(30)) | ||
44 | 47 | ||
45 | /* Bits in HSU_CH_CR */ | 48 | /* Bits in HSU_CH_CR */ |
46 | #define HSU_CH_CR_CHA BIT(0) | 49 | #define HSU_CH_CR_CHA BIT(0) |