Loading drivers/dma/edma.c +25 −38 Original line number Diff line number Diff line Loading @@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( struct edma_desc *edesc; dma_addr_t src_addr, dst_addr; enum dma_slave_buswidth dev_width; bool use_intermediate = false; u32 burst; int i, ret, nslots; Loading Loading @@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( * but the synchronization is difficult to achieve with Cyclic and * cannot be guaranteed, so we error out early. */ if (nslots > MAX_NR_SG) if (nslots > MAX_NR_SG) { /* * If the burst and period sizes are the same, we can put * the full buffer into a single period and activate * intermediate interrupts. This will produce interrupts * after each burst, which is also after each desired period. */ if (burst == period_len) { period_len = buf_len; nslots = 2; use_intermediate = true; } else { return NULL; } } edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), GFP_ATOMIC); Loading Loading @@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( /* * Enable period interrupt only if it is requested */ if (tx_flags & DMA_PREP_INTERRUPT) if (tx_flags & DMA_PREP_INTERRUPT) { edesc->pset[i].param.opt |= TCINTEN; /* Also enable intermediate interrupts if necessary */ if (use_intermediate) edesc->pset[i].param.opt |= ITCINTEN; } } /* Place the cyclic channel to highest priority queue */ Loading Loading @@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable) { struct platform_device *tc_pdev; int ret; if (!IS_ENABLED(CONFIG_OF) || !tc) return; tc_pdev = of_find_device_by_node(tc->node); if (!tc_pdev) { pr_err("%s: TPTC device is not found\n", __func__); return; } if (!pm_runtime_enabled(&tc_pdev->dev)) pm_runtime_enable(&tc_pdev->dev); if (enable) ret = pm_runtime_get_sync(&tc_pdev->dev); else ret = pm_runtime_put_sync(&tc_pdev->dev); if (ret < 0) pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__, enable ? "get" : "put", dev_name(&tc_pdev->dev)); } /* Alloc channel resources */ static int edma_alloc_chan_resources(struct dma_chan *chan) { Loading Loading @@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan) EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id, echan->hw_triggered ? "HW" : "SW"); edma_tc_set_pm_state(echan->tc, true); return 0; err_slot: Loading Loading @@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan) echan->alloced = false; } edma_tc_set_pm_state(echan->tc, false); echan->tc = NULL; echan->hw_triggered = false; Loading Loading @@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev) int i; for (i = 0; i < ecc->num_channels; i++) { if (echan[i].alloced) { if (echan[i].alloced) edma_setup_interrupt(&echan[i], false); edma_tc_set_pm_state(echan[i].tc, false); } } return 0; Loading Loading @@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev) /* Set up channel -> slot mapping for the entry slot */ edma_set_chmap(&echan[i], echan[i].slot[0]); edma_tc_set_pm_state(echan[i].tc, true); } } Loading @@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = { static int edma_tptc_probe(struct platform_device *pdev) { return 0; pm_runtime_enable(&pdev->dev); return pm_runtime_get_sync(&pdev->dev); } static struct platform_driver edma_tptc_driver = { Loading Loading
drivers/dma/edma.c +25 −38 Original line number Diff line number Diff line Loading @@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( struct edma_desc *edesc; dma_addr_t src_addr, dst_addr; enum dma_slave_buswidth dev_width; bool use_intermediate = false; u32 burst; int i, ret, nslots; Loading Loading @@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( * but the synchronization is difficult to achieve with Cyclic and * cannot be guaranteed, so we error out early. */ if (nslots > MAX_NR_SG) if (nslots > MAX_NR_SG) { /* * If the burst and period sizes are the same, we can put * the full buffer into a single period and activate * intermediate interrupts. This will produce interrupts * after each burst, which is also after each desired period. */ if (burst == period_len) { period_len = buf_len; nslots = 2; use_intermediate = true; } else { return NULL; } } edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), GFP_ATOMIC); Loading Loading @@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( /* * Enable period interrupt only if it is requested */ if (tx_flags & DMA_PREP_INTERRUPT) if (tx_flags & DMA_PREP_INTERRUPT) { edesc->pset[i].param.opt |= TCINTEN; /* Also enable intermediate interrupts if necessary */ if (use_intermediate) edesc->pset[i].param.opt |= ITCINTEN; } } /* Place the cyclic channel to highest priority queue */ Loading Loading @@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable) { struct platform_device *tc_pdev; int ret; if (!IS_ENABLED(CONFIG_OF) || !tc) return; tc_pdev = of_find_device_by_node(tc->node); if (!tc_pdev) { pr_err("%s: TPTC device is not found\n", __func__); return; } if (!pm_runtime_enabled(&tc_pdev->dev)) pm_runtime_enable(&tc_pdev->dev); if (enable) ret = pm_runtime_get_sync(&tc_pdev->dev); else ret = pm_runtime_put_sync(&tc_pdev->dev); if (ret < 0) pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__, enable ? "get" : "put", dev_name(&tc_pdev->dev)); } /* Alloc channel resources */ static int edma_alloc_chan_resources(struct dma_chan *chan) { Loading Loading @@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan) EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id, echan->hw_triggered ? "HW" : "SW"); edma_tc_set_pm_state(echan->tc, true); return 0; err_slot: Loading Loading @@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan) echan->alloced = false; } edma_tc_set_pm_state(echan->tc, false); echan->tc = NULL; echan->hw_triggered = false; Loading Loading @@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev) int i; for (i = 0; i < ecc->num_channels; i++) { if (echan[i].alloced) { if (echan[i].alloced) edma_setup_interrupt(&echan[i], false); edma_tc_set_pm_state(echan[i].tc, false); } } return 0; Loading Loading @@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev) /* Set up channel -> slot mapping for the entry slot */ edma_set_chmap(&echan[i], echan[i].slot[0]); edma_tc_set_pm_state(echan[i].tc, true); } } Loading @@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = { static int edma_tptc_probe(struct platform_device *pdev) { return 0; pm_runtime_enable(&pdev->dev); return pm_runtime_get_sync(&pdev->dev); } static struct platform_driver edma_tptc_driver = { Loading