hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/dma/dw-edma/dw-edma-core.c
....@@ -166,7 +166,7 @@
166166 dw_edma_free_desc(vd2dw_edma_desc(vdesc));
167167 }
168168
169
-static void dw_edma_start_transfer(struct dw_edma_chan *chan)
169
+static int dw_edma_start_transfer(struct dw_edma_chan *chan)
170170 {
171171 struct dw_edma_chunk *child;
172172 struct dw_edma_desc *desc;
....@@ -174,16 +174,16 @@
174174
175175 vd = vchan_next_desc(&chan->vc);
176176 if (!vd)
177
- return;
177
+ return 0;
178178
179179 desc = vd2dw_edma_desc(vd);
180180 if (!desc)
181
- return;
181
+ return 0;
182182
183183 child = list_first_entry_or_null(&desc->chunk->list,
184184 struct dw_edma_chunk, list);
185185 if (!child)
186
- return;
186
+ return 0;
187187
188188 dw_edma_v0_core_start(child, !desc->xfer_sz);
189189 desc->xfer_sz += child->ll_region.sz;
....@@ -191,6 +191,8 @@
191191 list_del(&child->list);
192192 kfree(child);
193193 desc->chunks_alloc--;
194
+
195
+ return 1;
194196 }
195197
196198 static int dw_edma_device_config(struct dma_chan *dchan,
....@@ -274,9 +276,12 @@
274276 struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
275277 unsigned long flags;
276278
279
+ if (!chan->configured)
280
+ return;
281
+
277282 spin_lock_irqsave(&chan->vc.lock, flags);
278
- if (chan->configured && chan->request == EDMA_REQ_NONE &&
279
- chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) {
283
+ if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE &&
284
+ chan->status == EDMA_ST_IDLE) {
280285 chan->status = EDMA_ST_BUSY;
281286 dw_edma_start_transfer(chan);
282287 }
....@@ -497,14 +502,14 @@
497502 switch (chan->request) {
498503 case EDMA_REQ_NONE:
499504 desc = vd2dw_edma_desc(vd);
500
- if (desc->chunks_alloc) {
501
- chan->status = EDMA_ST_BUSY;
502
- dw_edma_start_transfer(chan);
503
- } else {
505
+ if (!desc->chunks_alloc) {
504506 list_del(&vd->node);
505507 vchan_cookie_complete(vd);
506
- chan->status = EDMA_ST_IDLE;
507508 }
509
+
510
+ /* Continue transferring if there are remaining chunks or issued requests.
511
+ */
512
+ chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
508513 break;
509514
510515 case EDMA_REQ_STOP: