@@ -214,7 +214,8 @@ struct xilinx_dpdma_tx_desc {
214214 * @running: true if the channel is running
215215 * @first_frame: flag for the first frame of stream
216216 * @video_group: flag if multi-channel operation is needed for video channels
217- * @lock: lock to access struct xilinx_dpdma_chan
217+ * @lock: lock to access struct xilinx_dpdma_chan. Must be taken before
218+ * @vchan.lock, if both are to be held.
218219 * @desc_pool: descriptor allocation pool
219220 * @err_task: error IRQ bottom half handler
220221 * @desc: References to descriptors being processed
@@ -1097,12 +1098,14 @@ static void xilinx_dpdma_chan_vsync_irq(struct xilinx_dpdma_chan *chan)
10971098 * Complete the active descriptor, if any, promote the pending
10981099 * descriptor to active, and queue the next transfer, if any.
10991100 */
1101+ spin_lock (& chan -> vchan .lock );
11001102 if (chan -> desc .active )
11011103 vchan_cookie_complete (& chan -> desc .active -> vdesc );
11021104 chan -> desc .active = pending ;
11031105 chan -> desc .pending = NULL ;
11041106
11051107 xilinx_dpdma_chan_queue_transfer (chan );
1108+ spin_unlock (& chan -> vchan .lock );
11061109
11071110out :
11081111 spin_unlock_irqrestore (& chan -> lock , flags );
@@ -1264,10 +1267,12 @@ static void xilinx_dpdma_issue_pending(struct dma_chan *dchan)
12641267 struct xilinx_dpdma_chan * chan = to_xilinx_chan (dchan );
12651268 unsigned long flags ;
12661269
1267- spin_lock_irqsave (& chan -> vchan .lock , flags );
1270+ spin_lock_irqsave (& chan -> lock , flags );
1271+ spin_lock (& chan -> vchan .lock );
12681272 if (vchan_issue_pending (& chan -> vchan ))
12691273 xilinx_dpdma_chan_queue_transfer (chan );
1270- spin_unlock_irqrestore (& chan -> vchan .lock , flags );
1274+ spin_unlock (& chan -> vchan .lock );
1275+ spin_unlock_irqrestore (& chan -> lock , flags );
12711276}
12721277
12731278static int xilinx_dpdma_config (struct dma_chan * dchan ,
@@ -1495,7 +1500,9 @@ static void xilinx_dpdma_chan_err_task(struct tasklet_struct *t)
14951500 XILINX_DPDMA_EINTR_CHAN_ERR_MASK << chan -> id );
14961501
14971502 spin_lock_irqsave (& chan -> lock , flags );
1503+ spin_lock (& chan -> vchan .lock );
14981504 xilinx_dpdma_chan_queue_transfer (chan );
1505+ spin_unlock (& chan -> vchan .lock );
14991506 spin_unlock_irqrestore (& chan -> lock , flags );
15001507}
15011508
0 commit comments