Lines Matching refs:pd_chan

176 struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan)  in pdc_first_active()  argument
178 return list_first_entry(&pd_chan->active_list, in pdc_first_active()
183 struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan) in pdc_first_queued() argument
185 return list_first_entry(&pd_chan->queue, in pdc_first_queued()
215 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pdc_set_dir() local
229 if (pd_chan->dir == DMA_MEM_TO_DEV) in pdc_set_dir()
247 if (pd_chan->dir == DMA_MEM_TO_DEV) in pdc_set_dir()
295 static u32 pdc_get_status0(struct pch_dma_chan *pd_chan) in pdc_get_status0() argument
297 struct pch_dma *pd = to_pd(pd_chan->chan.device); in pdc_get_status0()
302 DMA_STATUS_BITS_PER_CH * pd_chan->chan.chan_id)); in pdc_get_status0()
305 static u32 pdc_get_status2(struct pch_dma_chan *pd_chan) in pdc_get_status2() argument
307 struct pch_dma *pd = to_pd(pd_chan->chan.device); in pdc_get_status2()
312 DMA_STATUS_BITS_PER_CH * (pd_chan->chan.chan_id - 8))); in pdc_get_status2()
315 static bool pdc_is_idle(struct pch_dma_chan *pd_chan) in pdc_is_idle() argument
319 if (pd_chan->chan.chan_id < 8) in pdc_is_idle()
320 sts = pdc_get_status0(pd_chan); in pdc_is_idle()
322 sts = pdc_get_status2(pd_chan); in pdc_is_idle()
331 static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) in pdc_dostart() argument
333 if (!pdc_is_idle(pd_chan)) { in pdc_dostart()
334 dev_err(chan2dev(&pd_chan->chan), in pdc_dostart()
339 dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", in pdc_dostart()
340 pd_chan->chan.chan_id, desc->regs.dev_addr); in pdc_dostart()
341 dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", in pdc_dostart()
342 pd_chan->chan.chan_id, desc->regs.mem_addr); in pdc_dostart()
343 dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> size: %x\n", in pdc_dostart()
344 pd_chan->chan.chan_id, desc->regs.size); in pdc_dostart()
345 dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", in pdc_dostart()
346 pd_chan->chan.chan_id, desc->regs.next); in pdc_dostart()
349 channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); in pdc_dostart()
350 channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); in pdc_dostart()
351 channel_writel(pd_chan, SIZE, desc->regs.size); in pdc_dostart()
352 channel_writel(pd_chan, NEXT, desc->regs.next); in pdc_dostart()
353 pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); in pdc_dostart()
355 channel_writel(pd_chan, NEXT, desc->txd.phys); in pdc_dostart()
356 pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); in pdc_dostart()
360 static void pdc_chain_complete(struct pch_dma_chan *pd_chan, in pdc_chain_complete() argument
367 list_splice_init(&desc->tx_list, &pd_chan->free_list); in pdc_chain_complete()
368 list_move(&desc->desc_node, &pd_chan->free_list); in pdc_chain_complete()
374 static void pdc_complete_all(struct pch_dma_chan *pd_chan) in pdc_complete_all() argument
379 BUG_ON(!pdc_is_idle(pd_chan)); in pdc_complete_all()
381 if (!list_empty(&pd_chan->queue)) in pdc_complete_all()
382 pdc_dostart(pd_chan, pdc_first_queued(pd_chan)); in pdc_complete_all()
384 list_splice_init(&pd_chan->active_list, &list); in pdc_complete_all()
385 list_splice_init(&pd_chan->queue, &pd_chan->active_list); in pdc_complete_all()
388 pdc_chain_complete(pd_chan, desc); in pdc_complete_all()
391 static void pdc_handle_error(struct pch_dma_chan *pd_chan) in pdc_handle_error() argument
395 bad_desc = pdc_first_active(pd_chan); in pdc_handle_error()
398 list_splice_init(&pd_chan->queue, pd_chan->active_list.prev); in pdc_handle_error()
400 if (!list_empty(&pd_chan->active_list)) in pdc_handle_error()
401 pdc_dostart(pd_chan, pdc_first_active(pd_chan)); in pdc_handle_error()
403 dev_crit(chan2dev(&pd_chan->chan), "Bad descriptor submitted\n"); in pdc_handle_error()
404 dev_crit(chan2dev(&pd_chan->chan), "descriptor cookie: %d\n", in pdc_handle_error()
407 pdc_chain_complete(pd_chan, bad_desc); in pdc_handle_error()
410 static void pdc_advance_work(struct pch_dma_chan *pd_chan) in pdc_advance_work() argument
412 if (list_empty(&pd_chan->active_list) || in pdc_advance_work()
413 list_is_singular(&pd_chan->active_list)) { in pdc_advance_work()
414 pdc_complete_all(pd_chan); in pdc_advance_work()
416 pdc_chain_complete(pd_chan, pdc_first_active(pd_chan)); in pdc_advance_work()
417 pdc_dostart(pd_chan, pdc_first_active(pd_chan)); in pdc_advance_work()
424 struct pch_dma_chan *pd_chan = to_pd_chan(txd->chan); in pd_tx_submit() local
427 spin_lock(&pd_chan->lock); in pd_tx_submit()
430 if (list_empty(&pd_chan->active_list)) { in pd_tx_submit()
431 list_add_tail(&desc->desc_node, &pd_chan->active_list); in pd_tx_submit()
432 pdc_dostart(pd_chan, desc); in pd_tx_submit()
434 list_add_tail(&desc->desc_node, &pd_chan->queue); in pd_tx_submit()
437 spin_unlock(&pd_chan->lock); in pd_tx_submit()
460 static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) in pdc_desc_get() argument
466 spin_lock(&pd_chan->lock); in pdc_desc_get()
467 list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) { in pdc_desc_get()
474 dev_dbg(chan2dev(&pd_chan->chan), "desc %p not ACKed\n", desc); in pdc_desc_get()
476 spin_unlock(&pd_chan->lock); in pdc_desc_get()
477 dev_dbg(chan2dev(&pd_chan->chan), "scanned %d descriptors\n", i); in pdc_desc_get()
480 ret = pdc_alloc_desc(&pd_chan->chan, GFP_ATOMIC); in pdc_desc_get()
482 spin_lock(&pd_chan->lock); in pdc_desc_get()
483 pd_chan->descs_allocated++; in pdc_desc_get()
484 spin_unlock(&pd_chan->lock); in pdc_desc_get()
486 dev_err(chan2dev(&pd_chan->chan), in pdc_desc_get()
494 static void pdc_desc_put(struct pch_dma_chan *pd_chan, in pdc_desc_put() argument
498 spin_lock(&pd_chan->lock); in pdc_desc_put()
499 list_splice_init(&desc->tx_list, &pd_chan->free_list); in pdc_desc_put()
500 list_add(&desc->desc_node, &pd_chan->free_list); in pdc_desc_put()
501 spin_unlock(&pd_chan->lock); in pdc_desc_put()
507 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pd_alloc_chan_resources() local
512 if (!pdc_is_idle(pd_chan)) { in pd_alloc_chan_resources()
517 if (!list_empty(&pd_chan->free_list)) in pd_alloc_chan_resources()
518 return pd_chan->descs_allocated; in pd_alloc_chan_resources()
532 spin_lock_irq(&pd_chan->lock); in pd_alloc_chan_resources()
533 list_splice(&tmp_list, &pd_chan->free_list); in pd_alloc_chan_resources()
534 pd_chan->descs_allocated = i; in pd_alloc_chan_resources()
536 spin_unlock_irq(&pd_chan->lock); in pd_alloc_chan_resources()
540 return pd_chan->descs_allocated; in pd_alloc_chan_resources()
545 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pd_free_chan_resources() local
550 BUG_ON(!pdc_is_idle(pd_chan)); in pd_free_chan_resources()
551 BUG_ON(!list_empty(&pd_chan->active_list)); in pd_free_chan_resources()
552 BUG_ON(!list_empty(&pd_chan->queue)); in pd_free_chan_resources()
554 spin_lock_irq(&pd_chan->lock); in pd_free_chan_resources()
555 list_splice_init(&pd_chan->free_list, &tmp_list); in pd_free_chan_resources()
556 pd_chan->descs_allocated = 0; in pd_free_chan_resources()
557 spin_unlock_irq(&pd_chan->lock); in pd_free_chan_resources()
573 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pd_issue_pending() local
575 if (pdc_is_idle(pd_chan)) { in pd_issue_pending()
576 spin_lock(&pd_chan->lock); in pd_issue_pending()
577 pdc_advance_work(pd_chan); in pd_issue_pending()
578 spin_unlock(&pd_chan->lock); in pd_issue_pending()
587 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pd_prep_slave_sg() local
608 pd_chan->dir = direction; in pd_prep_slave_sg()
612 desc = pdc_desc_get(pd_chan); in pd_prep_slave_sg()
664 pdc_desc_put(pd_chan, first); in pd_prep_slave_sg()
670 struct pch_dma_chan *pd_chan = to_pd_chan(chan); in pd_device_terminate_all() local
674 spin_lock_irq(&pd_chan->lock); in pd_device_terminate_all()
676 pdc_set_mode(&pd_chan->chan, DMA_CTL0_DISABLE); in pd_device_terminate_all()
678 list_splice_init(&pd_chan->active_list, &list); in pd_device_terminate_all()
679 list_splice_init(&pd_chan->queue, &list); in pd_device_terminate_all()
682 pdc_chain_complete(pd_chan, desc); in pd_device_terminate_all()
684 spin_unlock_irq(&pd_chan->lock); in pd_device_terminate_all()
691 struct pch_dma_chan *pd_chan = (struct pch_dma_chan *)data; in pdc_tasklet() local
694 if (!pdc_is_idle(pd_chan)) { in pdc_tasklet()
695 dev_err(chan2dev(&pd_chan->chan), in pdc_tasklet()
700 spin_lock_irqsave(&pd_chan->lock, flags); in pdc_tasklet()
701 if (test_and_clear_bit(0, &pd_chan->err_status)) in pdc_tasklet()
702 pdc_handle_error(pd_chan); in pdc_tasklet()
704 pdc_advance_work(pd_chan); in pdc_tasklet()
705 spin_unlock_irqrestore(&pd_chan->lock, flags); in pdc_tasklet()
711 struct pch_dma_chan *pd_chan; in pd_irq() local
724 pd_chan = &pd->channels[i]; in pd_irq()
729 set_bit(0, &pd_chan->err_status); in pd_irq()
731 tasklet_schedule(&pd_chan->tasklet); in pd_irq()
737 set_bit(0, &pd_chan->err_status); in pd_irq()
739 tasklet_schedule(&pd_chan->tasklet); in pd_irq()
757 struct pch_dma_chan *pd_chan; in pch_dma_save_regs() local
767 pd_chan = to_pd_chan(chan); in pch_dma_save_regs()
769 pd->ch_regs[i].dev_addr = channel_readl(pd_chan, DEV_ADDR); in pch_dma_save_regs()
770 pd->ch_regs[i].mem_addr = channel_readl(pd_chan, MEM_ADDR); in pch_dma_save_regs()
771 pd->ch_regs[i].size = channel_readl(pd_chan, SIZE); in pch_dma_save_regs()
772 pd->ch_regs[i].next = channel_readl(pd_chan, NEXT); in pch_dma_save_regs()
780 struct pch_dma_chan *pd_chan; in pch_dma_restore_regs() local
790 pd_chan = to_pd_chan(chan); in pch_dma_restore_regs()
792 channel_writel(pd_chan, DEV_ADDR, pd->ch_regs[i].dev_addr); in pch_dma_restore_regs()
793 channel_writel(pd_chan, MEM_ADDR, pd->ch_regs[i].mem_addr); in pch_dma_restore_regs()
794 channel_writel(pd_chan, SIZE, pd->ch_regs[i].size); in pch_dma_restore_regs()
795 channel_writel(pd_chan, NEXT, pd->ch_regs[i].next); in pch_dma_restore_regs()
904 struct pch_dma_chan *pd_chan = &pd->channels[i]; in pch_dma_probe() local
906 pd_chan->chan.device = &pd->dma; in pch_dma_probe()
907 dma_cookie_init(&pd_chan->chan); in pch_dma_probe()
909 pd_chan->membase = &regs->desc[i]; in pch_dma_probe()
911 spin_lock_init(&pd_chan->lock); in pch_dma_probe()
913 INIT_LIST_HEAD(&pd_chan->active_list); in pch_dma_probe()
914 INIT_LIST_HEAD(&pd_chan->queue); in pch_dma_probe()
915 INIT_LIST_HEAD(&pd_chan->free_list); in pch_dma_probe()
917 tasklet_init(&pd_chan->tasklet, pdc_tasklet, in pch_dma_probe()
918 (unsigned long)pd_chan); in pch_dma_probe()
919 list_add_tail(&pd_chan->chan.device_node, &pd->dma.channels); in pch_dma_probe()
959 struct pch_dma_chan *pd_chan; in pch_dma_remove() local
969 pd_chan = to_pd_chan(chan); in pch_dma_remove()
971 tasklet_kill(&pd_chan->tasklet); in pch_dma_remove()