[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200615040557.2011-5-mark.tomlinson@alliedtelesis.co.nz>
Date: Mon, 15 Jun 2020 16:05:56 +1200
From: Mark Tomlinson <mark.tomlinson@...iedtelesis.co.nz>
To: broonie@...nel.org, kdasu.kdev@...il.com
Cc: linux-kernel@...r.kernel.org, linux-spi@...r.kernel.org,
Mark Tomlinson <mark.tomlinson@...iedtelesis.co.nz>
Subject: [PATCH 4/5] spi: bcm-qspi: Make multiple data blocks interrupt-driven
When needing to send/receive data in small chunks, make this interrupt
driven rather than waiting for a completion event for each small section
of data.
Reviewed-by: Callum Sinclair <callum.sinclair@...iedtelesis.co.nz>
Reviewed-by: Chris Packham <chris.packham@...iedtelesis.co.nz>
Signed-off-by: Mark Tomlinson <mark.tomlinson@...iedtelesis.co.nz>
---
drivers/spi/spi-bcm-qspi.c | 44 ++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index ce30ebf27f06..0cc51bcda300 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -200,12 +200,14 @@ struct bcm_qspi_dev_id {
struct qspi_trans {
struct spi_transfer *trans;
int byte;
+ int slots;
bool mspi_last_trans;
};
struct bcm_qspi {
struct platform_device *pdev;
struct spi_master *master;
+ struct spi_device *spi_dev;
struct clk *clk;
u32 base_clk;
u32 max_speed_hz;
@@ -731,12 +733,14 @@ static inline u16 read_rxram_slot_u16(struct bcm_qspi *qspi, int slot)
((bcm_qspi_read(qspi, MSPI, msb_offset) & 0xff) << 8);
}
-static void read_from_hw(struct bcm_qspi *qspi, int slots)
+static void read_from_hw(struct bcm_qspi *qspi)
{
struct qspi_trans tp;
- int slot;
+ int slot, slots;
bcm_qspi_disable_bspi(qspi);
+ tp = qspi->trans_pos;
+ slots = tp.slots;
if (slots > MSPI_NUM_CDRAM) {
/* should never happen */
@@ -744,8 +748,6 @@ static void read_from_hw(struct bcm_qspi *qspi, int slots)
return;
}
- tp = qspi->trans_pos;
-
for (slot = 0; slot < slots; slot++) {
if (tp.trans->rx_buf) {
if (tp.trans->bits_per_word <= 8) {
@@ -803,11 +805,12 @@ static inline void write_cdram_slot(struct bcm_qspi *qspi, int slot, u32 val)
}
/* Return number of slots written */
-static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
+static int write_to_hw(struct bcm_qspi *qspi)
{
struct qspi_trans tp;
int slot = 0, tstatus = 0;
u32 mspi_cdram = 0;
+ struct spi_device *spi = qspi->spi_dev;
bcm_qspi_disable_bspi(qspi);
tp = qspi->trans_pos;
@@ -846,6 +849,9 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
slot++;
}
+ /* save slot number for read_from_hw() */
+ qspi->trans_pos.slots = slot;
+
if (!slot) {
dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__);
goto done;
@@ -960,24 +966,21 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
struct spi_transfer *trans)
{
struct bcm_qspi *qspi = spi_master_get_devdata(master);
- int slots;
- unsigned long timeo = msecs_to_jiffies(100);
+ unsigned long timeo = msecs_to_jiffies(1000);
if (!spi->cs_gpiod)
bcm_qspi_chip_select(qspi, spi->chip_select);
qspi->trans_pos.trans = trans;
qspi->trans_pos.byte = 0;
+ qspi->spi_dev = spi;
- while (qspi->trans_pos.byte < trans->len) {
- reinit_completion(&qspi->mspi_done);
+ reinit_completion(&qspi->mspi_done);
- slots = write_to_hw(qspi, spi);
- if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
- dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
- return -ETIMEDOUT;
- }
+ write_to_hw(qspi);
- read_from_hw(qspi, slots);
+ if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
+ dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
+ return -ETIMEDOUT;
}
bcm_qspi_enable_bspi(qspi);
@@ -1092,7 +1095,16 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
if (qspi->soc_intc)
soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_DONE);
- complete(&qspi->mspi_done);
+
+ read_from_hw(qspi);
+
+ if (qspi->trans_pos.trans) {
+ write_to_hw(qspi);
+ } else {
+ complete(&qspi->mspi_done);
+ spi_finalize_current_transfer(qspi->master);
+ }
+
return IRQ_HANDLED;
}
--
2.27.0
Powered by blists - more mailing lists