2022-08-22 09:57:44

by Vaishnav Achath

[permalink] [raw]
Subject: [PATCH 0/2] spi: spi-omap2-mcspi: Use EOW interrupt for transfer completion

When using MCSPI with DMA enabled in Master/Slave mode, real-time
performance issues were observed which were root caused to the
uncertain delays in the TX completion calculation mechanism in
k3-udma driver.

This series updates the omap2-mcspi driver to use End of Word(EOW)
interrupt to identify transaction completion and remove the usage
of DMA rx_completion and tx_completion for identifying transaction
completion.

Tested on J721E SK (for both Master and Slave Mode) for Full Duplex,
TX Only and RX Only mode transactions.Also tested with ILI9225 based
SPI TFT Display.

Vaishnav Achath (2):
dmaengine: ti: k3-udma: Respond TX done if DMA_PREP_INTERRUPT is not
requested
spi: spi-omap2-mcspi: Use EOW interrupt for completion when DMA
enabled

drivers/dma/ti/k3-udma.c | 5 +-
drivers/spi/spi-omap2-mcspi.c | 141 +++++++++-------------------------
2 files changed, 40 insertions(+), 106 deletions(-)

--
2.17.1


2022-08-22 10:32:36

by Vaishnav Achath

[permalink] [raw]
Subject: [PATCH 2/2] spi: spi-omap2-mcspi: Use EOW interrupt for completion when DMA enabled

In MCSPI controller EOW interrupt is triggered when the channel has
transmitted the set number of bytes in MCSPI_XFERLEVEL[31-16] WCNT,
this can be used to signal the completion of a TX/RX when the internal
FIFO is enabled, when DMA is enabled the internal FIFO is always enabled.
Waiting for the DMA completion adds unpredictable delays due to the
non-realtime completion calculation mechanism in k3-udma driver.

This commit removes the dma_tx_completion and dma_rx_completion and
relies on the MCSPI controller EOW interrupt to signal transaction
completion.This fixes the real-time performance issues in master and
slave mode when DMA was enabled which resulted from the DMA completion
calculation delays.

Since the MCSPI driver now uses internal mechanism to identify a transfer
completion we disable the TX and RX DMA completion callback and remove
DMA_PREP_INTERRUPT.

Signed-off-by: Vaishnav Achath <[email protected]>
---
drivers/spi/spi-omap2-mcspi.c | 141 +++++++++-------------------------
1 file changed, 36 insertions(+), 105 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index c48d02bb7013..8680465533e0 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -91,10 +91,6 @@
struct omap2_mcspi_dma {
struct dma_chan *dma_tx;
struct dma_chan *dma_rx;
-
- struct completion dma_tx_completion;
- struct completion dma_rx_completion;
-
char dma_rx_ch_name[14];
char dma_tx_ch_name[14];
};
@@ -116,7 +112,7 @@ struct omap2_mcspi_regs {
};

struct omap2_mcspi {
- struct completion txdone;
+ struct completion txrxdone;
struct spi_master *master;
/* Virtual base address of the controller */
void __iomem *base;
@@ -375,30 +371,6 @@ static int mcspi_wait_for_completion(struct omap2_mcspi *mcspi,
return 0;
}

-static void omap2_mcspi_rx_callback(void *data)
-{
- struct spi_device *spi = data;
- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
- struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
-
- /* We must disable the DMA RX request */
- omap2_mcspi_set_dma_req(spi, 1, 0);
-
- complete(&mcspi_dma->dma_rx_completion);
-}
-
-static void omap2_mcspi_tx_callback(void *data)
-{
- struct spi_device *spi = data;
- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
- struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
-
- /* We must disable the DMA TX request */
- omap2_mcspi_set_dma_req(spi, 0, 0);
-
- complete(&mcspi_dma->dma_tx_completion);
-}
-
static void omap2_mcspi_tx_dma(struct spi_device *spi,
struct spi_transfer *xfer,
struct dma_slave_config cfg)
@@ -413,12 +385,9 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);

tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
- xfer->tx_sg.nents,
- DMA_MEM_TO_DEV,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ xfer->tx_sg.nents, DMA_MEM_TO_DEV, DMA_CTRL_ACK);
+
if (tx) {
- tx->callback = omap2_mcspi_tx_callback;
- tx->callback_param = spi;
dmaengine_submit(tx);
} else {
/* FIXME: fall back to PIO? */
@@ -500,11 +469,9 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
}

tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, sg_out[0],
- out_mapped_nents[0], DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ out_mapped_nents[0], DMA_DEV_TO_MEM, DMA_CTRL_ACK);
+
if (tx) {
- tx->callback = omap2_mcspi_rx_callback;
- tx->callback_param = spi;
dmaengine_submit(tx);
} else {
/* FIXME: fall back to PIO? */
@@ -513,10 +480,10 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
dma_async_issue_pending(mcspi_dma->dma_rx);
omap2_mcspi_set_dma_req(spi, 1, 1);

- ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_rx_completion);
+ ret = mcspi_wait_for_completion(mcspi, &mcspi->txrxdone);
+ omap2_mcspi_set_dma_req(spi, 1, 0);
if (ret || mcspi->slave_aborted) {
dmaengine_terminate_sync(mcspi_dma->dma_rx);
- omap2_mcspi_set_dma_req(spi, 1, 0);
return 0;
}

@@ -587,8 +554,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
enum dma_slave_buswidth width;
unsigned es;
void __iomem *chstat_reg;
- void __iomem *irqstat_reg;
int wait_res;
+ int ret;

mcspi = spi_master_get_devdata(spi->master);
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -618,68 +585,36 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
tx = xfer->tx_buf;

mcspi->slave_aborted = false;
- reinit_completion(&mcspi_dma->dma_tx_completion);
- reinit_completion(&mcspi_dma->dma_rx_completion);
- reinit_completion(&mcspi->txdone);
- if (tx) {
- /* Enable EOW IRQ to know end of tx in slave mode */
- if (spi_controller_is_slave(spi->master))
- mcspi_write_reg(spi->master,
- OMAP2_MCSPI_IRQENABLE,
- OMAP2_MCSPI_IRQSTATUS_EOW);
+ reinit_completion(&mcspi->txrxdone);
+ mcspi_write_reg(spi->master, OMAP2_MCSPI_IRQENABLE, OMAP2_MCSPI_IRQSTATUS_EOW);
+ if (tx)
omap2_mcspi_tx_dma(spi, xfer, cfg);
- }

- if (rx != NULL)
+ if (rx)
count = omap2_mcspi_rx_dma(spi, xfer, cfg, es);

- if (tx != NULL) {
- int ret;
-
- ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_tx_completion);
- if (ret || mcspi->slave_aborted) {
- dmaengine_terminate_sync(mcspi_dma->dma_tx);
- omap2_mcspi_set_dma_req(spi, 0, 0);
- return 0;
- }
-
- if (spi_controller_is_slave(mcspi->master)) {
- ret = mcspi_wait_for_completion(mcspi, &mcspi->txdone);
- if (ret || mcspi->slave_aborted)
- return 0;
- }
+ ret = mcspi_wait_for_completion(mcspi, &mcspi->txrxdone);
+ omap2_mcspi_set_dma_req(spi, 0, 0);
+ if (ret || mcspi->slave_aborted)
+ return 0;

+ /* for TX_ONLY mode, be sure all words have shifted out */
+ if (tx && !rx) {
+ chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
if (mcspi->fifo_depth > 0) {
- irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
-
- if (mcspi_wait_for_reg_bit(irqstat_reg,
- OMAP2_MCSPI_IRQSTATUS_EOW) < 0)
- dev_err(&spi->dev, "EOW timed out\n");
-
- mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS,
- OMAP2_MCSPI_IRQSTATUS_EOW);
- }
-
- /* for TX_ONLY mode, be sure all words have shifted out */
- if (rx == NULL) {
- chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
- if (mcspi->fifo_depth > 0) {
- wait_res = mcspi_wait_for_reg_bit(chstat_reg,
- OMAP2_MCSPI_CHSTAT_TXFFE);
- if (wait_res < 0)
- dev_err(&spi->dev, "TXFFE timed out\n");
- } else {
- wait_res = mcspi_wait_for_reg_bit(chstat_reg,
- OMAP2_MCSPI_CHSTAT_TXS);
- if (wait_res < 0)
- dev_err(&spi->dev, "TXS timed out\n");
- }
- if (wait_res >= 0 &&
- (mcspi_wait_for_reg_bit(chstat_reg,
- OMAP2_MCSPI_CHSTAT_EOT) < 0))
- dev_err(&spi->dev, "EOT timed out\n");
+ wait_res = mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_TXFFE);
+ if (wait_res < 0)
+ dev_err(&spi->dev, "TXFFE timed out\n");
+ } else {
+ wait_res = mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_TXS);
+ if (wait_res < 0)
+ dev_err(&spi->dev, "TXS timed out\n");
}
+ if (wait_res >= 0 && (mcspi_wait_for_reg_bit(chstat_reg,
+ OMAP2_MCSPI_CHSTAT_EOT) < 0))
+ dev_err(&spi->dev, "EOT timed out\n");
}
+
return count;
}

@@ -1010,9 +945,6 @@ static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi,
mcspi_dma->dma_rx = NULL;
}

- init_completion(&mcspi_dma->dma_rx_completion);
- init_completion(&mcspi_dma->dma_tx_completion);
-
no_dma:
return ret;
}
@@ -1102,8 +1034,10 @@ static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data)

/* Disable IRQ and wakeup slave xfer task */
mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQENABLE, 0);
- if (irqstat & OMAP2_MCSPI_IRQSTATUS_EOW)
- complete(&mcspi->txdone);
+ if (irqstat & OMAP2_MCSPI_IRQSTATUS_EOW) {
+ complete_all(&mcspi->txrxdone);
+ mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS, OMAP2_MCSPI_IRQSTATUS_EOW);
+ }

return IRQ_HANDLED;
}
@@ -1111,12 +1045,9 @@ static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data)
static int omap2_mcspi_slave_abort(struct spi_master *master)
{
struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
- struct omap2_mcspi_dma *mcspi_dma = mcspi->dma_channels;

mcspi->slave_aborted = true;
- complete(&mcspi_dma->dma_rx_completion);
- complete(&mcspi_dma->dma_tx_completion);
- complete(&mcspi->txdone);
+ complete_all(&mcspi->txrxdone);

return 0;
}
@@ -1516,7 +1447,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no irq resource found\n");
goto free_master;
}
- init_completion(&mcspi->txdone);
+ init_completion(&mcspi->txrxdone);
status = devm_request_irq(&pdev->dev, status,
omap2_mcspi_irq_handler, 0, pdev->name,
mcspi);
--
2.17.1

2022-08-22 13:18:38

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 2/2] spi: spi-omap2-mcspi: Use EOW interrupt for completion when DMA enabled

Hi Vaishnav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on broonie-spi/for-next linus/master v6.0-rc2 next-20220822]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Vaishnav-Achath/spi-spi-omap2-mcspi-Use-EOW-interrupt-for-transfer-completion/20220822-171807
base: https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
config: arc-randconfig-r043-20220821 (https://download.01.org/0day-ci/archive/20220822/[email protected]/config)
compiler: arc-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/492d819558f7cb9fb64d860042c6ca17a054c3f7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Vaishnav-Achath/spi-spi-omap2-mcspi-Use-EOW-interrupt-for-transfer-completion/20220822-171807
git checkout 492d819558f7cb9fb64d860042c6ca17a054c3f7
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

drivers/spi/spi-omap2-mcspi.c: In function 'omap2_mcspi_txrx_dma':
>> drivers/spi/spi-omap2-mcspi.c:549:34: warning: variable 'mcspi_dma' set but not used [-Wunused-but-set-variable]
549 | struct omap2_mcspi_dma *mcspi_dma;
| ^~~~~~~~~


vim +/mcspi_dma +549 drivers/spi/spi-omap2-mcspi.c

d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 543
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 544 static unsigned
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 545 omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 546 {
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 547 struct omap2_mcspi *mcspi;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 548 struct omap2_mcspi_cs *cs = spi->controller_state;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 @549 struct omap2_mcspi_dma *mcspi_dma;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 550 unsigned int count;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 551 u8 *rx;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 552 const u8 *tx;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 553 struct dma_slave_config cfg;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 554 enum dma_slave_buswidth width;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 555 unsigned es;
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 556 void __iomem *chstat_reg;
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 557 int wait_res;
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 558 int ret;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 559
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 560 mcspi = spi_master_get_devdata(spi->master);
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 561 mcspi_dma = &mcspi->dma_channels[spi->chip_select];
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 562
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 563 if (cs->word_len <= 8) {
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 564 width = DMA_SLAVE_BUSWIDTH_1_BYTE;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 565 es = 1;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 566 } else if (cs->word_len <= 16) {
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 567 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 568 es = 2;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 569 } else {
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 570 width = DMA_SLAVE_BUSWIDTH_4_BYTES;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 571 es = 4;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 572 }
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 573
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 574 count = xfer->len;
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 575
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 576 memset(&cfg, 0, sizeof(cfg));
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 577 cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 578 cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 579 cfg.src_addr_width = width;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 580 cfg.dst_addr_width = width;
baf8b9f8d260c5 drivers/spi/spi-omap2-mcspi.c Vignesh R 2019-01-15 581 cfg.src_maxburst = 1;
baf8b9f8d260c5 drivers/spi/spi-omap2-mcspi.c Vignesh R 2019-01-15 582 cfg.dst_maxburst = 1;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 583
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 584 rx = xfer->rx_buf;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 585 tx = xfer->tx_buf;
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 586
89e8b9cb846515 drivers/spi/spi-omap2-mcspi.c Vignesh R 2018-10-15 587 mcspi->slave_aborted = false;
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 588 reinit_completion(&mcspi->txrxdone);
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 589 mcspi_write_reg(spi->master, OMAP2_MCSPI_IRQENABLE, OMAP2_MCSPI_IRQSTATUS_EOW);
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 590 if (tx)
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 591 omap2_mcspi_tx_dma(spi, xfer, cfg);
d7b4394e780b02 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-09-11 592
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 593 if (rx)
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 594 count = omap2_mcspi_rx_dma(spi, xfer, cfg, es);
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 595
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 596 ret = mcspi_wait_for_completion(mcspi, &mcspi->txrxdone);
89e8b9cb846515 drivers/spi/spi-omap2-mcspi.c Vignesh R 2018-10-15 597 omap2_mcspi_set_dma_req(spi, 0, 0);
89e8b9cb846515 drivers/spi/spi-omap2-mcspi.c Vignesh R 2018-10-15 598 if (ret || mcspi->slave_aborted)
89e8b9cb846515 drivers/spi/spi-omap2-mcspi.c Vignesh R 2018-10-15 599 return 0;
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 600
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 601 /* for TX_ONLY mode, be sure all words have shifted out */
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 602 if (tx && !rx) {
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 603 chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 604 if (mcspi->fifo_depth > 0) {
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 605 wait_res = mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_TXFFE);
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 606 if (wait_res < 0)
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 607 dev_err(&spi->dev, "TXFFE timed out\n");
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 608 } else {
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 609 wait_res = mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_TXS);
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 610 if (wait_res < 0)
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 611 dev_err(&spi->dev, "TXS timed out\n");
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 612 }
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 613 if (wait_res >= 0 && (mcspi_wait_for_reg_bit(chstat_reg,
d33f473dcd8e69 drivers/spi/spi-omap2-mcspi.c Illia Smyrnov 2013-06-17 614 OMAP2_MCSPI_CHSTAT_EOT) < 0))
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 615 dev_err(&spi->dev, "EOT timed out\n");
e47a682ace0cd5 drivers/spi/spi-omap2-mcspi.c Shubhrajyoti D 2012-11-06 616 }
492d819558f7cb drivers/spi/spi-omap2-mcspi.c Vaishnav Achath 2022-08-22 617
ccdc7bf925731e drivers/spi/omap2_mcspi.c Samuel Ortiz 2007-07-17 618 return count;
ccdc7bf925731e drivers/spi/omap2_mcspi.c Samuel Ortiz 2007-07-17 619 }
ccdc7bf925731e drivers/spi/omap2_mcspi.c Samuel Ortiz 2007-07-17 620

--
0-DAY CI Kernel Test Service
https://01.org/lkp