summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2019-10-23 11:31:38 -0400
committerVinod Koul <vkoul@kernel.org>2019-10-23 11:45:21 -0400
commitbacdcb6675e170bb2e8d3824da220e10274f42a7 (patch)
treecec456f7693c0ec24b38acc8a15fda8d45db7d9b
parent7667819385457b4aeb5fac94f67f52ab52cc10d5 (diff)
dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle
Yegor Yefremov <yegorslists@googlemail.com> reported that musb and ftdi uart can fail for the first open of the uart unless connected using a hub. This is because the first dma call done by musb_ep_program() must wait if cppi41 is PM runtime suspended. Otherwise musb_ep_program() continues with other non-dma packets before the DMA transfer is started causing at least ftdi uarts to fail to receive data. Let's fix the issue by waking up cppi41 with PM runtime calls added to cppi41_dma_prep_slave_sg() and return NULL if still idled. This way we have musb_ep_program() continue with PIO until cppi41 is awake. Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") Reported-by: Yegor Yefremov <yegorslists@googlemail.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Cc: stable@vger.kernel.org # v4.9+ Link: https://lore.kernel.org/r/20191023153138.23442-1-tony@atomide.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/dma/ti/cppi41.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/dma/ti/cppi41.c b/drivers/dma/ti/cppi41.c
index 2f946f55076c..8c2f7ebe998c 100644
--- a/drivers/dma/ti/cppi41.c
+++ b/drivers/dma/ti/cppi41.c
@@ -586,9 +586,22 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg(
586 enum dma_transfer_direction dir, unsigned long tx_flags, void *context) 586 enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
587{ 587{
588 struct cppi41_channel *c = to_cpp41_chan(chan); 588 struct cppi41_channel *c = to_cpp41_chan(chan);
589 struct dma_async_tx_descriptor *txd = NULL;
590 struct cppi41_dd *cdd = c->cdd;
589 struct cppi41_desc *d; 591 struct cppi41_desc *d;
590 struct scatterlist *sg; 592 struct scatterlist *sg;
591 unsigned int i; 593 unsigned int i;
594 int error;
595
596 error = pm_runtime_get(cdd->ddev.dev);
597 if (error < 0) {
598 pm_runtime_put_noidle(cdd->ddev.dev);
599
600 return NULL;
601 }
602
603 if (cdd->is_suspended)
604 goto err_out_not_ready;
592 605
593 d = c->desc; 606 d = c->desc;
594 for_each_sg(sgl, sg, sg_len, i) { 607 for_each_sg(sgl, sg, sg_len, i) {
@@ -611,7 +624,13 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg(
611 d++; 624 d++;
612 } 625 }
613 626
614 return &c->txd; 627 txd = &c->txd;
628
629err_out_not_ready:
630 pm_runtime_mark_last_busy(cdd->ddev.dev);
631 pm_runtime_put_autosuspend(cdd->ddev.dev);
632
633 return txd;
615} 634}
616 635
617static void cppi41_compute_td_desc(struct cppi41_desc *d) 636static void cppi41_compute_td_desc(struct cppi41_desc *d)