Skip to content

Commit c2a6042

Browse files
chleroybroonie
authored andcommitted
soc: fsl: qmc: Only set completion interrupt when needed
When no post-completion processing is expected, don't waste time handling useless interrupts. Only set QMC_BD_[R/T]X_I when a completion function is passed in, and perform seamless completion on submit for interruptless buffers. Acked-by: Herve Codina <herve.codina@bootlin.com> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Link: https://patch.msgid.link/40b41b53a26e77a50b3a5f68fcecc6f9a40a84b4.1758209158.git.christophe.leroy@csgroup.eu Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent f83ec76 commit c2a6042

1 file changed

Lines changed: 33 additions & 11 deletions

File tree

drivers/soc/fsl/qe/qmc.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,16 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
461461

462462
ctrl = qmc_read16(&bd->cbd_sc);
463463
if (ctrl & (QMC_BD_TX_R | QMC_BD_TX_UB)) {
464-
/* We are full ... */
465-
ret = -EBUSY;
466-
goto end;
464+
if (!(ctrl & (QMC_BD_TX_R | QMC_BD_TX_I)) && bd == chan->txbd_done) {
465+
if (ctrl & QMC_BD_TX_W)
466+
chan->txbd_done = chan->txbds;
467+
else
468+
chan->txbd_done++;
469+
} else {
470+
/* We are full ... */
471+
ret = -EBUSY;
472+
goto end;
473+
}
467474
}
468475

469476
qmc_write16(&bd->cbd_datlen, length);
@@ -475,6 +482,10 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
475482

476483
/* Activate the descriptor */
477484
ctrl |= (QMC_BD_TX_R | QMC_BD_TX_UB);
485+
if (complete)
486+
ctrl |= QMC_BD_TX_I;
487+
else
488+
ctrl &= ~QMC_BD_TX_I;
478489
wmb(); /* Be sure to flush the descriptor before control update */
479490
qmc_write16(&bd->cbd_sc, ctrl);
480491

@@ -569,9 +580,16 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
569580

570581
ctrl = qmc_read16(&bd->cbd_sc);
571582
if (ctrl & (QMC_BD_RX_E | QMC_BD_RX_UB)) {
572-
/* We are full ... */
573-
ret = -EBUSY;
574-
goto end;
583+
if (!(ctrl & (QMC_BD_RX_E | QMC_BD_RX_I)) && bd == chan->rxbd_done) {
584+
if (ctrl & QMC_BD_RX_W)
585+
chan->rxbd_done = chan->rxbds;
586+
else
587+
chan->rxbd_done++;
588+
} else {
589+
/* We are full ... */
590+
ret = -EBUSY;
591+
goto end;
592+
}
575593
}
576594

577595
qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */
@@ -587,6 +605,10 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
587605

588606
/* Activate the descriptor */
589607
ctrl |= (QMC_BD_RX_E | QMC_BD_RX_UB);
608+
if (complete)
609+
ctrl |= QMC_BD_RX_I;
610+
else
611+
ctrl &= ~QMC_BD_RX_I;
590612
wmb(); /* Be sure to flush data before descriptor activation */
591613
qmc_write16(&bd->cbd_sc, ctrl);
592614

@@ -1482,19 +1504,19 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan)
14821504

14831505
/* Init Rx BDs and set Wrap bit on last descriptor */
14841506
BUILD_BUG_ON(QMC_NB_RXBDS == 0);
1485-
val = QMC_BD_RX_I;
14861507
for (i = 0; i < QMC_NB_RXBDS; i++) {
14871508
bd = chan->rxbds + i;
1488-
qmc_write16(&bd->cbd_sc, val);
1509+
qmc_write16(&bd->cbd_sc, 0);
14891510
}
14901511
bd = chan->rxbds + QMC_NB_RXBDS - 1;
1491-
qmc_write16(&bd->cbd_sc, val | QMC_BD_RX_W);
1512+
qmc_write16(&bd->cbd_sc, QMC_BD_RX_W);
14921513

14931514
/* Init Tx BDs and set Wrap bit on last descriptor */
14941515
BUILD_BUG_ON(QMC_NB_TXBDS == 0);
1495-
val = QMC_BD_TX_I;
14961516
if (chan->mode == QMC_HDLC)
1497-
val |= QMC_BD_TX_L | QMC_BD_TX_TC;
1517+
val = QMC_BD_TX_L | QMC_BD_TX_TC;
1518+
else
1519+
val = 0;
14981520
for (i = 0; i < QMC_NB_TXBDS; i++) {
14991521
bd = chan->txbds + i;
15001522
qmc_write16(&bd->cbd_sc, val);

0 commit comments

Comments
 (0)