Lines Matching refs:atchan
35 * atc_ / atchan : ATmel DMA Channel entity related
59 static struct at_desc *atc_first_active(struct at_dma_chan *atchan)
61 return list_first_entry(&atchan->active_list,
65 static struct at_desc *atc_first_queued(struct at_dma_chan *atchan)
67 return list_first_entry(&atchan->queue,
104 * @atchan: channel we want a new descriptor for
106 static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
113 spin_lock_bh(&atchan->lock);
114 list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
121 dev_dbg(chan2dev(&atchan->chan_common),
124 spin_unlock_bh(&atchan->lock);
125 dev_vdbg(chan2dev(&atchan->chan_common),
130 ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC);
132 spin_lock_bh(&atchan->lock);
133 atchan->descs_allocated++;
134 spin_unlock_bh(&atchan->lock);
136 dev_err(chan2dev(&atchan->chan_common),
146 * @atchan: channel we work on
149 static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
154 spin_lock_bh(&atchan->lock);
156 dev_vdbg(chan2dev(&atchan->chan_common),
159 list_splice_init(&desc->tx_list, &atchan->free_list);
160 dev_vdbg(chan2dev(&atchan->chan_common),
162 list_add(&desc->desc_node, &atchan->free_list);
163 spin_unlock_bh(&atchan->lock);
169 * @atchan: channel we work on
172 * Called with atchan->lock held and bh disabled
175 atc_assign_cookie(struct at_dma_chan *atchan, struct at_desc *desc)
177 dma_cookie_t cookie = atchan->chan_common.cookie;
182 atchan->chan_common.cookie = cookie;
190 * @atchan: the channel we want to start
193 * Called with atchan->lock held and bh disabled
195 static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
197 struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
200 if (atc_chan_is_enabled(atchan)) {
201 dev_err(chan2dev(&atchan->chan_common),
203 dev_err(chan2dev(&atchan->chan_common),
205 channel_readl(atchan, SADDR),
206 channel_readl(atchan, DADDR),
207 channel_readl(atchan, CTRLA),
208 channel_readl(atchan, CTRLB),
209 channel_readl(atchan, DSCR));
215 vdbg_dump_regs(atchan);
221 channel_writel(atchan, SADDR, 0);
222 channel_writel(atchan, DADDR, 0);
223 channel_writel(atchan, CTRLA, 0);
224 channel_writel(atchan, CTRLB, 0);
225 channel_writel(atchan, DSCR, first->txd.phys);
226 dma_writel(atdma, CHER, atchan->mask);
228 vdbg_dump_regs(atchan);
233 * @atchan: channel we work on
236 * Called with atchan->lock held and bh disabled */
238 atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
244 dev_vdbg(chan2dev(&atchan->chan_common),
247 atchan->completed_cookie = txd->cookie;
252 list_splice_init(&desc->tx_list, &atchan->free_list);
254 list_move(&desc->desc_node, &atchan->free_list);
257 if (!atchan->chan_common.private) {
258 struct device *parent = chan2parent(&atchan->chan_common);
293 * @atchan: channel to complete transactions for
298 * Called with atchan->lock held and bh disabled
300 static void atc_complete_all(struct at_dma_chan *atchan)
305 dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
307 BUG_ON(atc_chan_is_enabled(atchan));
313 if (!list_empty(&atchan->queue))
314 atc_dostart(atchan, atc_first_queued(atchan));
316 list_splice_init(&atchan->active_list, &list);
318 list_splice_init(&atchan->queue, &atchan->active_list);
321 atc_chain_complete(atchan, desc);
326 * @atchan: channel to be cleaned up
328 * Called with atchan->lock held and bh disabled
330 static void atc_cleanup_descriptors(struct at_dma_chan *atchan)
335 dev_vdbg(chan2dev(&atchan->chan_common), "cleanup descriptors\n");
337 list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
351 atc_chain_complete(atchan, desc);
357 * @atchan: channel where the transaction ended
359 * Called with atchan->lock held and bh disabled
361 static void atc_advance_work(struct at_dma_chan *atchan)
363 dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
365 if (list_empty(&atchan->active_list) ||
366 list_is_singular(&atchan->active_list)) {
367 atc_complete_all(atchan);
369 atc_chain_complete(atchan, atc_first_active(atchan));
371 atc_dostart(atchan, atc_first_active(atchan));
378 * @atchan: channel where error occurs
380 * Called with atchan->lock held and bh disabled
382 static void atc_handle_error(struct at_dma_chan *atchan)
392 bad_desc = atc_first_active(atchan);
397 list_splice_init(&atchan->queue, atchan->active_list.prev);
400 if (!list_empty(&atchan->active_list))
401 atc_dostart(atchan, atc_first_active(atchan));
410 dev_crit(chan2dev(&atchan->chan_common),
412 dev_crit(chan2dev(&atchan->chan_common),
414 atc_dump_lli(atchan, &bad_desc->lli);
416 atc_dump_lli(atchan, &child->lli);
419 atc_chain_complete(atchan, bad_desc);
427 struct at_dma_chan *atchan = (struct at_dma_chan *)data;
430 if (atc_chan_is_enabled(atchan)) {
431 dev_err(chan2dev(&atchan->chan_common),
436 spin_lock(&atchan->lock);
437 if (test_and_clear_bit(0, &atchan->error_status))
438 atc_handle_error(atchan);
440 atc_advance_work(atchan);
442 spin_unlock(&atchan->lock);
448 struct at_dma_chan *atchan;
466 atchan = &atdma->chan[i];
470 dma_writel(atdma, CHDR, atchan->mask);
472 set_bit(0, &atchan->error_status);
474 tasklet_schedule(&atchan->tasklet);
498 struct at_dma_chan *atchan = to_at_dma_chan(tx->chan);
501 spin_lock_bh(&atchan->lock);
502 cookie = atc_assign_cookie(atchan, desc);
504 if (list_empty(&atchan->active_list)) {
507 atc_dostart(atchan, desc);
508 list_add_tail(&desc->desc_node, &atchan->active_list);
512 list_add_tail(&desc->desc_node, &atchan->queue);
515 spin_unlock_bh(&atchan->lock);
532 struct at_dma_chan *atchan = to_at_dma_chan(chan);
576 desc = atc_desc_get(atchan);
612 atc_desc_put(atchan, first);
630 struct at_dma_chan *atchan = to_at_dma_chan(chan);
669 desc = atc_desc_get(atchan);
711 desc = atc_desc_get(atchan);
759 atc_desc_put(atchan, first);
766 struct at_dma_chan *atchan = to_at_dma_chan(chan);
781 spin_lock_bh(&atchan->lock);
783 dma_writel(atdma, CHDR, atchan->mask);
786 while (dma_readl(atdma, CHSR) & atchan->mask)
790 list_splice_init(&atchan->queue, &list);
791 list_splice_init(&atchan->active_list, &list);
795 atc_chain_complete(atchan, desc);
797 spin_unlock_bh(&atchan->lock);
817 struct at_dma_chan *atchan = to_at_dma_chan(chan);
822 spin_lock_bh(&atchan->lock);
824 last_complete = atchan->completed_cookie;
829 atc_cleanup_descriptors(atchan);
831 last_complete = atchan->completed_cookie;
837 spin_unlock_bh(&atchan->lock);
853 struct at_dma_chan *atchan = to_at_dma_chan(chan);
857 if (!atc_chan_is_enabled(atchan)) {
858 spin_lock_bh(&atchan->lock);
859 atc_advance_work(atchan);
860 spin_unlock_bh(&atchan->lock);
873 struct at_dma_chan *atchan = to_at_dma_chan(chan);
884 if (atc_chan_is_enabled(atchan)) {
906 if (!list_empty(&atchan->free_list))
907 return atchan->descs_allocated;
920 spin_lock_bh(&atchan->lock);
921 atchan->descs_allocated = i;
922 list_splice(&tmp_list, &atchan->free_list);
923 atchan->completed_cookie = chan->cookie = 1;
924 spin_unlock_bh(&atchan->lock);
927 channel_writel(atchan, CFG, cfg);
931 atchan->descs_allocated);
933 return atchan->descs_allocated;
942 struct at_dma_chan *atchan = to_at_dma_chan(chan);
948 atchan->descs_allocated);
951 BUG_ON(!list_empty(&atchan->active_list));
952 BUG_ON(!list_empty(&atchan->queue));
953 BUG_ON(atc_chan_is_enabled(atchan));
955 list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
961 list_splice_init(&atchan->free_list, &list);
962 atchan->descs_allocated = 0;
1064 struct at_dma_chan *atchan = &atdma->chan[i];
1066 atchan->chan_common.device = &atdma->dma_common;
1067 atchan->chan_common.cookie = atchan->completed_cookie = 1;
1068 atchan->chan_common.chan_id = i;
1069 list_add_tail(&atchan->chan_common.device_node,
1072 atchan->ch_regs = atdma->regs + ch_regs(i);
1073 spin_lock_init(&atchan->lock);
1074 atchan->mask = 1 << i;
1076 INIT_LIST_HEAD(&atchan->active_list);
1077 INIT_LIST_HEAD(&atchan->queue);
1078 INIT_LIST_HEAD(&atchan->free_list);
1080 tasklet_init(&atchan->tasklet, atc_tasklet,
1081 (unsigned long)atchan);
1082 atc_enable_irq(atchan);
1143 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1146 atc_disable_irq(atchan);
1147 tasklet_disable(&atchan->tasklet);
1149 tasklet_kill(&atchan->tasklet);