diff options
| -rw-r--r-- | drivers/dma/amba-pl08x.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 6a35e37d14bc..c42c7ef6b93a 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
| @@ -473,10 +473,8 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan) | |||
| 473 | { | 473 | { |
| 474 | struct pl08x_phy_chan *ch; | 474 | struct pl08x_phy_chan *ch; |
| 475 | struct pl08x_txd *txd; | 475 | struct pl08x_txd *txd; |
| 476 | unsigned long flags; | ||
| 477 | size_t bytes = 0; | 476 | size_t bytes = 0; |
| 478 | 477 | ||
| 479 | spin_lock_irqsave(&plchan->vc.lock, flags); | ||
| 480 | ch = plchan->phychan; | 478 | ch = plchan->phychan; |
| 481 | txd = plchan->at; | 479 | txd = plchan->at; |
| 482 | 480 | ||
| @@ -516,27 +514,6 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan) | |||
| 516 | } | 514 | } |
| 517 | } | 515 | } |
| 518 | 516 | ||
| 519 | /* Sum up all queued transactions */ | ||
| 520 | if (!list_empty(&plchan->vc.desc_issued)) { | ||
| 521 | struct pl08x_txd *txdi; | ||
| 522 | list_for_each_entry(txdi, &plchan->vc.desc_issued, vd.node) { | ||
| 523 | struct pl08x_sg *dsg; | ||
| 524 | list_for_each_entry(dsg, &txd->dsg_list, node) | ||
| 525 | bytes += dsg->len; | ||
| 526 | } | ||
| 527 | } | ||
| 528 | |||
| 529 | if (!list_empty(&plchan->vc.desc_submitted)) { | ||
| 530 | struct pl08x_txd *txdi; | ||
| 531 | list_for_each_entry(txdi, &plchan->vc.desc_submitted, vd.node) { | ||
| 532 | struct pl08x_sg *dsg; | ||
| 533 | list_for_each_entry(dsg, &txd->dsg_list, node) | ||
| 534 | bytes += dsg->len; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | |||
| 538 | spin_unlock_irqrestore(&plchan->vc.lock, flags); | ||
| 539 | |||
| 540 | return bytes; | 517 | return bytes; |
| 541 | } | 518 | } |
| 542 | 519 | ||
| @@ -1171,23 +1148,53 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan, | |||
| 1171 | dma_cookie_t cookie, struct dma_tx_state *txstate) | 1148 | dma_cookie_t cookie, struct dma_tx_state *txstate) |
| 1172 | { | 1149 | { |
| 1173 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); | 1150 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); |
| 1151 | struct virt_dma_desc *vd; | ||
| 1152 | unsigned long flags; | ||
| 1174 | enum dma_status ret; | 1153 | enum dma_status ret; |
| 1154 | size_t bytes = 0; | ||
| 1175 | 1155 | ||
| 1176 | ret = dma_cookie_status(chan, cookie, txstate); | 1156 | ret = dma_cookie_status(chan, cookie, txstate); |
| 1177 | if (ret == DMA_SUCCESS) | 1157 | if (ret == DMA_SUCCESS) |
| 1178 | return ret; | 1158 | return ret; |
| 1179 | 1159 | ||
| 1180 | /* | 1160 | /* |
| 1161 | * There's no point calculating the residue if there's | ||
| 1162 | * no txstate to store the value. | ||
| 1163 | */ | ||
| 1164 | if (!txstate) { | ||
| 1165 | if (plchan->state == PL08X_CHAN_PAUSED) | ||
| 1166 | ret = DMA_PAUSED; | ||
| 1167 | return ret; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | spin_lock_irqsave(&plchan->vc.lock, flags); | ||
| 1171 | ret = dma_cookie_status(chan, cookie, txstate); | ||
| 1172 | if (ret != DMA_SUCCESS) { | ||
| 1173 | vd = vchan_find_desc(&plchan->vc, cookie); | ||
| 1174 | if (vd) { | ||
| 1175 | /* On the issued list, so hasn't been processed yet */ | ||
| 1176 | struct pl08x_txd *txd = to_pl08x_txd(&vd->tx); | ||
| 1177 | struct pl08x_sg *dsg; | ||
| 1178 | |||
| 1179 | list_for_each_entry(dsg, &txd->dsg_list, node) | ||
| 1180 | bytes += dsg->len; | ||
| 1181 | } else { | ||
| 1182 | bytes = pl08x_getbytes_chan(plchan); | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | spin_unlock_irqrestore(&plchan->vc.lock, flags); | ||
| 1186 | |||
| 1187 | /* | ||
| 1181 | * This cookie not complete yet | 1188 | * This cookie not complete yet |
| 1182 | * Get number of bytes left in the active transactions and queue | 1189 | * Get number of bytes left in the active transactions and queue |
| 1183 | */ | 1190 | */ |
| 1184 | dma_set_residue(txstate, pl08x_getbytes_chan(plchan)); | 1191 | dma_set_residue(txstate, bytes); |
| 1185 | 1192 | ||
| 1186 | if (plchan->state == PL08X_CHAN_PAUSED) | 1193 | if (plchan->state == PL08X_CHAN_PAUSED && ret == DMA_IN_PROGRESS) |
| 1187 | return DMA_PAUSED; | 1194 | ret = DMA_PAUSED; |
| 1188 | 1195 | ||
| 1189 | /* Whether waiting or running, we're in progress */ | 1196 | /* Whether waiting or running, we're in progress */ |
| 1190 | return DMA_IN_PROGRESS; | 1197 | return ret; |
| 1191 | } | 1198 | } |
| 1192 | 1199 | ||
| 1193 | /* PrimeCell DMA extension */ | 1200 | /* PrimeCell DMA extension */ |
