#define TIMESTAMP_AFTER BIT(3)
#define POST_CMD_DELAY BIT(4)
-enum spi_m_cmd_opcode {
- CMD_NONE,
- CMD_XFER,
- CMD_CS,
- CMD_CANCEL,
-};
-
struct spi_geni_master {
struct geni_se se;
struct device *dev;
unsigned int tx_rem_bytes;
unsigned int rx_rem_bytes;
const struct spi_transfer *cur_xfer;
- struct completion xfer_done;
+ struct completion cs_done;
+ struct completion cancel_done;
+ struct completion abort_done;
unsigned int oversampling;
spinlock_t lock;
- enum spi_m_cmd_opcode cur_mcmd;
int irq;
};
struct geni_se *se = &mas->se;
spin_lock_irq(&mas->lock);
- reinit_completion(&mas->xfer_done);
- mas->cur_mcmd = CMD_CANCEL;
- geni_se_cancel_m_cmd(se);
+ reinit_completion(&mas->cancel_done);
writel(0, se->base + SE_GENI_TX_WATERMARK_REG);
+ mas->cur_xfer = NULL;
+ mas->tx_rem_bytes = mas->rx_rem_bytes = 0;
+ geni_se_cancel_m_cmd(se);
spin_unlock_irq(&mas->lock);
- time_left = wait_for_completion_timeout(&mas->xfer_done, HZ);
+
+ time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
if (time_left)
return;
spin_lock_irq(&mas->lock);
- reinit_completion(&mas->xfer_done);
+ reinit_completion(&mas->abort_done);
geni_se_abort_m_cmd(se);
spin_unlock_irq(&mas->lock);
- time_left = wait_for_completion_timeout(&mas->xfer_done, HZ);
+
+ time_left = wait_for_completion_timeout(&mas->abort_done, HZ);
if (!time_left)
dev_err(mas->dev, "Failed to cancel/abort m_cmd\n");
}
set_flag = !set_flag;
spin_lock_irq(&mas->lock);
- reinit_completion(&mas->xfer_done);
- mas->cur_mcmd = CMD_CS;
+ reinit_completion(&mas->cs_done);
if (set_flag)
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);
else
geni_se_setup_m_cmd(se, SPI_CS_DEASSERT, 0);
spin_unlock_irq(&mas->lock);
- time_left = wait_for_completion_timeout(&mas->xfer_done, HZ);
+ time_left = wait_for_completion_timeout(&mas->cs_done, HZ);
if (!time_left)
handle_fifo_timeout(spi, NULL);
mas->rx_rem_bytes = xfer->len;
}
writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
- mas->cur_mcmd = CMD_XFER;
/*
* Lock around right before we start the transfer since our
geni_spi_handle_tx(mas);
if (m_irq & M_CMD_DONE_EN) {
- if (mas->cur_mcmd == CMD_XFER)
+ if (mas->cur_xfer) {
spi_finalize_current_transfer(spi);
- else if (mas->cur_mcmd == CMD_CS)
- complete(&mas->xfer_done);
- mas->cur_mcmd = CMD_NONE;
+ mas->cur_xfer = NULL;
+ } else {
+ complete(&mas->cs_done);
+ }
+
/*
* If this happens, then a CMD_DONE came before all the Tx
* buffer bytes were sent out. This is unusual, log this
mas->rx_rem_bytes, mas->cur_bits_per_word);
}
- if ((m_irq & M_CMD_CANCEL_EN) || (m_irq & M_CMD_ABORT_EN)) {
- mas->cur_mcmd = CMD_NONE;
- complete(&mas->xfer_done);
- }
+ if (m_irq & M_CMD_CANCEL_EN)
+ complete(&mas->cancel_done);
+ if (m_irq & M_CMD_ABORT_EN)
+ complete(&mas->abort_done);
/*
* It's safe or a good idea to Ack all of our our interrupts at the
spi->handle_err = handle_fifo_timeout;
spi->set_cs = spi_geni_set_cs;
- init_completion(&mas->xfer_done);
+ init_completion(&mas->cs_done);
+ init_completion(&mas->cancel_done);
+ init_completion(&mas->abort_done);
spin_lock_init(&mas->lock);
pm_runtime_enable(dev);