Skip to content

Commit 956e6c8

Browse files
author
Vinod Koul
committed
Merge branch 'fix/edma' into fixes
2 parents 1cc3334 + a482f4e commit 956e6c8

File tree

1 file changed

+25
-38
lines changed

1 file changed

+25
-38
lines changed

drivers/dma/edma.c

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12381238
struct edma_desc *edesc;
12391239
dma_addr_t src_addr, dst_addr;
12401240
enum dma_slave_buswidth dev_width;
1241+
bool use_intermediate = false;
12411242
u32 burst;
12421243
int i, ret, nslots;
12431244

@@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12791280
* but the synchronization is difficult to achieve with Cyclic and
12801281
* cannot be guaranteed, so we error out early.
12811282
*/
1282-
if (nslots > MAX_NR_SG)
1283-
return NULL;
1283+
if (nslots > MAX_NR_SG) {
1284+
/*
1285+
* If the burst and period sizes are the same, we can put
1286+
* the full buffer into a single period and activate
1287+
* intermediate interrupts. This will produce interrupts
1288+
* after each burst, which is also after each desired period.
1289+
*/
1290+
if (burst == period_len) {
1291+
period_len = buf_len;
1292+
nslots = 2;
1293+
use_intermediate = true;
1294+
} else {
1295+
return NULL;
1296+
}
1297+
}
12841298

12851299
edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
12861300
GFP_ATOMIC);
@@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
13581372
/*
13591373
* Enable period interrupt only if it is requested
13601374
*/
1361-
if (tx_flags & DMA_PREP_INTERRUPT)
1375+
if (tx_flags & DMA_PREP_INTERRUPT) {
13621376
edesc->pset[i].param.opt |= TCINTEN;
1377+
1378+
/* Also enable intermediate interrupts if necessary */
1379+
if (use_intermediate)
1380+
edesc->pset[i].param.opt |= ITCINTEN;
1381+
}
13631382
}
13641383

13651384
/* Place the cyclic channel to highest priority queue */
@@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
15701589
return IRQ_HANDLED;
15711590
}
15721591

1573-
static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
1574-
{
1575-
struct platform_device *tc_pdev;
1576-
int ret;
1577-
1578-
if (!IS_ENABLED(CONFIG_OF) || !tc)
1579-
return;
1580-
1581-
tc_pdev = of_find_device_by_node(tc->node);
1582-
if (!tc_pdev) {
1583-
pr_err("%s: TPTC device is not found\n", __func__);
1584-
return;
1585-
}
1586-
if (!pm_runtime_enabled(&tc_pdev->dev))
1587-
pm_runtime_enable(&tc_pdev->dev);
1588-
1589-
if (enable)
1590-
ret = pm_runtime_get_sync(&tc_pdev->dev);
1591-
else
1592-
ret = pm_runtime_put_sync(&tc_pdev->dev);
1593-
1594-
if (ret < 0)
1595-
pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__,
1596-
enable ? "get" : "put", dev_name(&tc_pdev->dev));
1597-
}
1598-
15991592
/* Alloc channel resources */
16001593
static int edma_alloc_chan_resources(struct dma_chan *chan)
16011594
{
@@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
16321625
EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id,
16331626
echan->hw_triggered ? "HW" : "SW");
16341627

1635-
edma_tc_set_pm_state(echan->tc, true);
1636-
16371628
return 0;
16381629

16391630
err_slot:
@@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan)
16701661
echan->alloced = false;
16711662
}
16721663

1673-
edma_tc_set_pm_state(echan->tc, false);
16741664
echan->tc = NULL;
16751665
echan->hw_triggered = false;
16761666

@@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev)
24172407
int i;
24182408

24192409
for (i = 0; i < ecc->num_channels; i++) {
2420-
if (echan[i].alloced) {
2410+
if (echan[i].alloced)
24212411
edma_setup_interrupt(&echan[i], false);
2422-
edma_tc_set_pm_state(echan[i].tc, false);
2423-
}
24242412
}
24252413

24262414
return 0;
@@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev)
24502438

24512439
/* Set up channel -> slot mapping for the entry slot */
24522440
edma_set_chmap(&echan[i], echan[i].slot[0]);
2453-
2454-
edma_tc_set_pm_state(echan[i].tc, true);
24552441
}
24562442
}
24572443

@@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = {
24752461

24762462
static int edma_tptc_probe(struct platform_device *pdev)
24772463
{
2478-
return 0;
2464+
pm_runtime_enable(&pdev->dev);
2465+
return pm_runtime_get_sync(&pdev->dev);
24792466
}
24802467

24812468
static struct platform_driver edma_tptc_driver = {

0 commit comments

Comments
 (0)