All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-02 12:22   ` Heiner Kallweit
       [not found]     ` <20608368-44e6-21f8-d970-5ade9990ce59-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:22   ` [PATCH 03/11] spi: fsl-espi: fix handling of word sizes other than 8 bit Heiner Kallweit
                     ` (17 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:22 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
based on DT property "mode". This property is not defined for ESPI,
see Documentation/devicetree/bindings/spi/fsl-spi.txt
Therefore remove the check.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 65bb70d..8281aea1 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -594,11 +594,6 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 	if (ret)
 		goto err_probe;
 
-	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
-		mpc8xxx_spi->rx_shift = 16;
-		mpc8xxx_spi->tx_shift = 24;
-	}
-
 	/* SPI controller initializations */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, 0);
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 03/11] spi: fsl-espi: fix handling of word sizes other than 8 bit
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:22   ` [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE Heiner Kallweit
@ 2016-10-02 12:22   ` Heiner Kallweit
  2016-10-02 12:23   ` [PATCH 04/11] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
                     ` (16 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:22 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

The code in fsl_espi_tx_buf_lsb and parts of fsl_espi_setup_transfer
look very weird and don't reflect the ESPI spec.
ESPI stores values with <= 8 bit word size right justified as 8 bit
value and values with > 8 bit word size right justified as 16 bit
value. Therefore no such shifting is needed.
Only case MSB-first with 8 bit word size is correctly handled,
and most likely nobody ever used this driver with a different config.

On ESPI only the case LSB-first with word size > 8 bit needs a
special handling. In this case a little endian 16 bit value has
to be written to the TX FIFO what requires a byte swap as the
host system is big endian.
The same applies to reading from the RX FIFO.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 84 ++++++++++++++++++++--------------------------
 1 file changed, 36 insertions(+), 48 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 8281aea1..4a7fe77 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -112,6 +112,32 @@ static inline void fsl_espi_write_reg8(struct mpc8xxx_spi *mspi, int offset,
 	iowrite8(val, mspi->reg_base + offset);
 }
 
+static void fsl_espi_memcpy_swab(void *to, const void *from,
+				 struct spi_message *m,
+				 struct spi_transfer *t)
+{
+	unsigned int len = t->len;
+
+	if (!(m->spi->mode & SPI_LSB_FIRST) || t->bits_per_word <= 8) {
+		memcpy(to, from, len);
+		return;
+	}
+
+	/* In case of LSB-first and bits_per_word > 8 byte-swap all words */
+	while (len)
+		if (len >= 4) {
+			*(u32 *)to = swahb32p(from);
+			to += 4;
+			from += 4;
+			len -= 4;
+		} else {
+			*(u16 *)to = swab16p(from);
+			to += 2;
+			from += 2;
+			len -= 2;
+		}
+}
+
 static void fsl_espi_copy_to_buf(struct spi_message *m,
 				 struct mpc8xxx_spi *mspi)
 {
@@ -120,7 +146,7 @@ static void fsl_espi_copy_to_buf(struct spi_message *m,
 
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (t->tx_buf)
-			memcpy(buf, t->tx_buf, t->len);
+			fsl_espi_memcpy_swab(buf, t->tx_buf, m, t);
 		else
 			memset(buf, 0, t->len);
 		buf += t->len;
@@ -135,7 +161,7 @@ static void fsl_espi_copy_from_buf(struct spi_message *m,
 
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (t->rx_buf)
-			memcpy(t->rx_buf, buf, t->len);
+			fsl_espi_memcpy_swab(t->rx_buf, buf, m, t);
 		buf += t->len;
 	}
 }
@@ -194,27 +220,6 @@ static void fsl_espi_change_mode(struct spi_device *spi)
 	local_irq_restore(flags);
 }
 
-static u32 fsl_espi_tx_buf_lsb(struct mpc8xxx_spi *mpc8xxx_spi)
-{
-	u32 data;
-	u16 data_h;
-	u16 data_l;
-	const u32 *tx = mpc8xxx_spi->tx;
-
-	if (!tx)
-		return 0;
-
-	data = *tx++ << mpc8xxx_spi->tx_shift;
-	data_l = data & 0xffff;
-	data_h = (data >> 16) & 0xffff;
-	swab16s(&data_l);
-	swab16s(&data_h);
-	data = data_h | data_l;
-
-	mpc8xxx_spi->tx = tx;
-	return data;
-}
-
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -224,23 +229,6 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 	u8 pm;
 	struct spi_mpc8xxx_cs *cs = spi->controller_state;
 
-	cs->rx_shift = 0;
-	cs->tx_shift = 0;
-	cs->get_rx = mpc8xxx_spi_rx_buf_u32;
-	cs->get_tx = mpc8xxx_spi_tx_buf_u32;
-	if (bits_per_word <= 8) {
-		cs->rx_shift = 8 - bits_per_word;
-	} else {
-		cs->rx_shift = 16 - bits_per_word;
-		if (spi->mode & SPI_LSB_FIRST)
-			cs->get_tx = fsl_espi_tx_buf_lsb;
-	}
-
-	mpc8xxx_spi->rx_shift = cs->rx_shift;
-	mpc8xxx_spi->tx_shift = cs->tx_shift;
-	mpc8xxx_spi->get_rx = cs->get_rx;
-	mpc8xxx_spi->get_tx = cs->get_tx;
-
 	/* mask out bits we are going to set */
 	cs->hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF));
 
@@ -271,7 +259,6 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
-	u32 word;
 	int ret;
 
 	mpc8xxx_spi->len = t->len;
@@ -290,8 +277,8 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
 
 	/* transmit word */
-	word = mpc8xxx_spi->get_tx(mpc8xxx_spi);
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, word);
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, *(u32 *)mpc8xxx_spi->tx);
+	mpc8xxx_spi->tx += 4;
 
 	/* Won't hang up forever, SPI bus sometimes got lost interrupts... */
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
@@ -468,8 +455,10 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 
 		mspi->len -= rx_nr_bytes;
 
-		if (mspi->rx)
-			mspi->get_rx(rx_data, mspi);
+		if (mspi->rx) {
+			*(u32 *)mspi->rx = rx_data;
+			mspi->rx += 4;
+		}
 	}
 
 	if (!(events & SPIE_TNF)) {
@@ -487,9 +476,8 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 
 	mspi->count -= 1;
 	if (mspi->count) {
-		u32 word = mspi->get_tx(mspi);
-
-		fsl_espi_write_reg(mspi, ESPI_SPITF, word);
+		fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
+		mspi->tx += 4;
 	} else {
 		complete(&mspi->done);
 	}
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 04/11] spi: fsl-espi: fix and improve writing to TX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:22   ` [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE Heiner Kallweit
  2016-10-02 12:22   ` [PATCH 03/11] spi: fsl-espi: fix handling of word sizes other than 8 bit Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
       [not found]     ` <c246dbf2-c59e-f029-afa1-8a5c6f6dd24b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:23   ` [PATCH 05/11] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
                     ` (15 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This change addresses two issues:
- If the TX FIFO is full the ISR polls until there's free space again.
  An ISR should never wait for something.
- Currently the number of bytes to transfer is rounded up to the next
  multiple of 4. For most transfers therefore few bytes remain in the
  TX FIFO after end of transfer.
  This would cause the next transfer to fail and as a workaround the
  ESPI block is disabled / re-enabled in fsl_espi_change_mode.
  This seems to clear the FIFO's (although it's not mentioned in the
  spec).

With this change the TX FIFO is filled as much as possible initially
and whenever the ISR is called. Also the exact number of bytes is
transferred.
The spinlock protects against a potential race if the first interrupt
occurs whilst the TX FIFO is still being initially filled.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 68 ++++++++++++++++++++++++++++------------------
 drivers/spi/spi-fsl-lib.h  |  2 ++
 2 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 4a7fe77..9068861 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -54,6 +54,8 @@
 #define CSMODE_AFT(x)		((x) << 8)
 #define CSMODE_CG(x)		((x) << 3)
 
+#define FSL_ESPI_FIFO_SIZE	32
+
 /* Default mode/csmode for eSPI controller */
 #define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
@@ -200,6 +202,27 @@ static int fsl_espi_check_message(struct spi_message *m)
 	return 0;
 }
 
+static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 tx_fifo_avail;
+
+	/* if events is zero transfer has not started and tx fifo is empty */
+	tx_fifo_avail = events ? SPIE_TXCNT(events) :  FSL_ESPI_FIFO_SIZE;
+
+	while (tx_fifo_avail >= min(4U, mspi->tx_len) && mspi->tx_len)
+		if (mspi->tx_len >= 4) {
+			fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
+			mspi->tx += 4;
+			mspi->tx_len -= 4;
+			tx_fifo_avail -= 4;
+		} else {
+			fsl_espi_write_reg8(mspi, ESPI_SPITF, *(u8 *)mspi->tx);
+			mspi->tx += 1;
+			mspi->tx_len -= 1;
+			tx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_change_mode(struct spi_device *spi)
 {
 	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
@@ -262,7 +285,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	int ret;
 
 	mpc8xxx_spi->len = t->len;
-	mpc8xxx_spi->count = roundup(t->len, 4) / 4;
+	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
 	mpc8xxx_spi->rx = t->rx_buf;
@@ -276,21 +299,22 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	/* enable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
 
-	/* transmit word */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, *(u32 *)mpc8xxx_spi->tx);
-	mpc8xxx_spi->tx += 4;
+	/* Prevent filling the fifo from getting interrupted */
+	spin_lock_irq(&mpc8xxx_spi->lock);
+	fsl_espi_fill_tx_fifo(mpc8xxx_spi, 0);
+	spin_unlock_irq(&mpc8xxx_spi->lock);
 
 	/* Won't hang up forever, SPI bus sometimes got lost interrupts... */
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %d bytes)\n",
-			mpc8xxx_spi->count);
+			"Transaction hanging up (left %u bytes)\n",
+			mpc8xxx_spi->tx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->count > 0 ? -EMSGSIZE : 0;
+	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -461,26 +485,11 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		}
 	}
 
-	if (!(events & SPIE_TNF)) {
-		int ret;
-
-		/* spin until TX is done */
-		ret = spin_event_timeout(((events = fsl_espi_read_reg(
-				mspi, ESPI_SPIE)) & SPIE_TNF), 1000, 0);
-		if (!ret) {
-			dev_err(mspi->dev, "tired waiting for SPIE_TNF\n");
-			complete(&mspi->done);
-			return;
-		}
-	}
+	if (mspi->tx_len)
+		fsl_espi_fill_tx_fifo(mspi, events);
 
-	mspi->count -= 1;
-	if (mspi->count) {
-		fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
-		mspi->tx += 4;
-	} else {
+	if (!mspi->tx_len && !mspi->len)
 		complete(&mspi->done);
-	}
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
@@ -488,10 +497,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	struct mpc8xxx_spi *mspi = context_data;
 	u32 events;
 
+	spin_lock(&mspi->lock);
+
 	/* Get interrupt events(tx/rx) */
 	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
-	if (!events)
+	if (!events) {
+		spin_unlock_irq(&mspi->lock);
 		return IRQ_NONE;
+	}
 
 	dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events);
 
@@ -500,6 +513,8 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	/* Clear the events */
 	fsl_espi_write_reg(mspi, ESPI_SPIE, events);
 
+	spin_unlock(&mspi->lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -562,6 +577,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 	master->max_message_size = fsl_espi_max_message_size;
 
 	mpc8xxx_spi = spi_master_get_devdata(master);
+	spin_lock_init(&mpc8xxx_spi->lock);
 
 	mpc8xxx_spi->local_buf =
 		devm_kmalloc(dev, SPCOM_TRANLEN_MAX, GFP_KERNEL);
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 2925c80..24d8bc8 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -30,7 +30,9 @@ struct mpc8xxx_spi {
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
 	int len;
+	unsigned int tx_len;
 	u8 *local_buf;
+	spinlock_t lock;
 #endif
 
 	int subblock;
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 05/11] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 04/11] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
  2016-10-02 12:23   ` [PATCH 06/11] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
                     ` (14 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Now that we introduced element tx_len in struct mpc8xxx_spi let's
rename element len to rx_len as it actually is the number of bytes to
receive. In addition make it unsigned.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++-----------
 drivers/spi/spi-fsl-lib.h  |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 9068861..d9d9f7f 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -284,7 +284,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
 	int ret;
 
-	mpc8xxx_spi->len = t->len;
+	mpc8xxx_spi->rx_len = t->len;
 	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
@@ -445,28 +445,28 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		int ret;
 
 		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4, mspi->len)) {
+		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
 			ret = spin_event_timeout(
 				!(SPIE_RXCNT(events =
 				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4, mspi->len)),
+						min(4U, mspi->rx_len)),
 						10000, 0); /* 10 msec */
 			if (!ret)
 				dev_err(mspi->dev,
 					 "tired waiting for SPIE_RXCNT\n");
 		}
 
-		if (mspi->len >= 4) {
+		if (mspi->rx_len >= 4) {
 			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (mspi->len <= 0) {
+		} else if (!mspi->rx_len) {
 			dev_err(mspi->dev,
 				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
 				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4, mspi->len), SPIE_RXCNT(events));
+				min(4U, mspi->rx_len), SPIE_RXCNT(events));
 			rx_nr_bytes = 0;
 		} else {
-			rx_nr_bytes = mspi->len;
-			tmp = mspi->len;
+			rx_nr_bytes = mspi->rx_len;
+			tmp = mspi->rx_len;
 			rx_data = 0;
 			while (tmp--) {
 				rx_data_8 = fsl_espi_read_reg8(mspi,
@@ -474,10 +474,10 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 				rx_data |= (rx_data_8 << (tmp * 8));
 			}
 
-			rx_data <<= (4 - mspi->len) * 8;
+			rx_data <<= (4 - mspi->rx_len) * 8;
 		}
 
-		mspi->len -= rx_nr_bytes;
+		mspi->rx_len -= rx_nr_bytes;
 
 		if (mspi->rx) {
 			*(u32 *)mspi->rx = rx_data;
@@ -488,7 +488,7 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->len)
+	if (!mspi->tx_len && !mspi->rx_len)
 		complete(&mspi->done);
 }
 
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 24d8bc8..35a7a17 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -29,7 +29,7 @@ struct mpc8xxx_spi {
 	const void *tx;
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
-	int len;
+	unsigned int rx_len;
 	unsigned int tx_len;
 	u8 *local_buf;
 	spinlock_t lock;
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 06/11] spi: fsl-espi: simplify and inline function fsl_espi_change_mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 05/11] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
       [not found]     ` <0aeb49f0-dbfb-7acb-3829-cabafe4e7291-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:23   ` [PATCH 07/11] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
                     ` (13 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

The ESPI spec mentions no requirement to turn off the ESPI unit prior
to changing the mode. Most likely the ESPI unit is only turned off to
clear the FIFO's as before this patch series single bytes could
remain in the TX FIFO after transfer end.
Therefore remove disabling / re-enabling the ESPI unit.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 23 ++---------------------
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index d9d9f7f..c3e55c8 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -223,26 +223,6 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
-static void fsl_espi_change_mode(struct spi_device *spi)
-{
-	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
-	struct spi_mpc8xxx_cs *cs = spi->controller_state;
-	u32 tmp;
-	unsigned long flags;
-
-	/* Turn off IRQs locally to minimize time that SPI is disabled. */
-	local_irq_save(flags);
-
-	/* Turn off SPI unit prior changing mode */
-	tmp = fsl_espi_read_reg(mspi, ESPI_SPMODE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp & ~SPMODE_ENABLE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODEx(spi->chip_select),
-			      cs->hw_mode);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp);
-
-	local_irq_restore(flags);
-}
-
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -276,7 +256,8 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 
 	cs->hw_mode |= CSMODE_PM(pm);
 
-	fsl_espi_change_mode(spi);
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(spi->chip_select),
+			   cs->hw_mode);
 }
 
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 07/11] spi: fsl-espi: fix and improve reading from RX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 06/11] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
  2016-10-02 12:23   ` [PATCH 08/11] spi: fsl-espi: make better use of the " Heiner Kallweit
                     ` (12 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Currently the driver polls in the ISR for enough bytes in the RX FIFO.
An ISR should never do this.
Change it to read as much as possible whenever the ISR is called.
This also allows to significantly simplify the code.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 67 ++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 47 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index c3e55c8..5abbb62 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -223,6 +223,24 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
+static void fsl_espi_read_rx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 rx_fifo_avail = SPIE_RXCNT(events);
+
+	while (rx_fifo_avail >= min(4U, mspi->rx_len) && mspi->rx_len)
+		if (mspi->rx_len >= 4) {
+			*(u32 *)mspi->rx = fsl_espi_read_reg(mspi, ESPI_SPIRF);
+			mspi->rx += 4;
+			mspi->rx_len -= 4;
+			rx_fifo_avail -= 4;
+		} else {
+			*(u8 *)mspi->rx = fsl_espi_read_reg8(mspi, ESPI_SPIRF);
+			mspi->rx += 1;
+			mspi->rx_len -= 1;
+			rx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -418,53 +436,8 @@ static void fsl_espi_cleanup(struct spi_device *spi)
 
 static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 {
-	/* We need handle RX first */
-	if (events & SPIE_RNE) {
-		u32 rx_data, tmp;
-		u8 rx_data_8;
-		int rx_nr_bytes = 4;
-		int ret;
-
-		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
-			ret = spin_event_timeout(
-				!(SPIE_RXCNT(events =
-				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4U, mspi->rx_len)),
-						10000, 0); /* 10 msec */
-			if (!ret)
-				dev_err(mspi->dev,
-					 "tired waiting for SPIE_RXCNT\n");
-		}
-
-		if (mspi->rx_len >= 4) {
-			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (!mspi->rx_len) {
-			dev_err(mspi->dev,
-				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
-				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4U, mspi->rx_len), SPIE_RXCNT(events));
-			rx_nr_bytes = 0;
-		} else {
-			rx_nr_bytes = mspi->rx_len;
-			tmp = mspi->rx_len;
-			rx_data = 0;
-			while (tmp--) {
-				rx_data_8 = fsl_espi_read_reg8(mspi,
-							       ESPI_SPIRF);
-				rx_data |= (rx_data_8 << (tmp * 8));
-			}
-
-			rx_data <<= (4 - mspi->rx_len) * 8;
-		}
-
-		mspi->rx_len -= rx_nr_bytes;
-
-		if (mspi->rx) {
-			*(u32 *)mspi->rx = rx_data;
-			mspi->rx += 4;
-		}
-	}
+	if (mspi->rx_len)
+		fsl_espi_read_rx_fifo(mspi, events);
 
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 08/11] spi: fsl-espi: make better use of the RX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (5 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 07/11] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
       [not found]     ` <144b73b1-dff2-a5b6-9df1-837238f20008-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:23   ` [PATCH 09/11] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
                     ` (11 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

So far an interrupt is triggered whenever there's at least one byte
in the RX FIFO. This results in a unnecessarily high number of
interrupts.
Change this to generate an interrupt if
- RX FIFO is half full (except if all bytes to read fit into the
  RX FIFO anyway)
- end of transfer has been reached

This way the number of interrupts can be significantly reduced.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 5abbb62..10d06f2 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -55,9 +55,10 @@
 #define CSMODE_CG(x)		((x) << 3)
 
 #define FSL_ESPI_FIFO_SIZE	32
+#define FSL_ESPI_RXTHR		15
 
 /* Default mode/csmode for eSPI controller */
-#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
+#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(FSL_ESPI_RXTHR))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
 		| CSMODE_AFT(0) | CSMODE_CG(1))
 
@@ -281,6 +282,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
+	u32 mask;
 	int ret;
 
 	mpc8xxx_spi->rx_len = t->len;
@@ -295,8 +297,11 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM,
 		(SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1)));
 
-	/* enable rx ints */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
+	/* enable interrupts */
+	mask = SPIM_DON;
+	if (mpc8xxx_spi->rx_len > FSL_ESPI_FIFO_SIZE)
+		mask |= SPIM_RXT;
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, mask);
 
 	/* Prevent filling the fifo from getting interrupted */
 	spin_lock_irq(&mpc8xxx_spi->lock);
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 09/11] spi: fsl-espi: extend and improve transfer error handling
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (6 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 08/11] spi: fsl-espi: make better use of the " Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
       [not found]     ` <4ba19a7f-9f66-54c4-9119-e85671d608fb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-02 12:23   ` [PATCH 10/11] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
                     ` (10 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Extend and improve transfer error handling
- in case of timeout report also number of remaining rx bytes
- in case of timeout return ETIMEDOUT instead of EMSGSIZE
- add sanity checks after all bytes have been sent / read:
 - check that HW has flag SPIE_DON set
 - check that RX / TX FIFO are empty

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 10d06f2..cbfb6da 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -312,13 +312,13 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %u bytes)\n",
-			mpc8xxx_spi->tx_len);
+			"Transaction hanging up (left %u tx bytes, %u rx bytes)\n",
+			mpc8xxx_spi->tx_len, mpc8xxx_spi->rx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
+	return ret == 0 ? -ETIMEDOUT : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -447,8 +447,20 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->rx_len)
-		complete(&mspi->done);
+	if (mspi->tx_len || mspi->rx_len)
+		return;
+
+	/* we're done, but check for errors before returning */
+	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
+
+	if (!(events & SPIE_DON))
+		dev_err(mspi->dev,
+			"Transfer done but SPIE_DON isn't set!\n");
+
+	if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE)
+		dev_err(mspi->dev, "Transfer done but rx/tx fifo's aren't empty!\n");
+
+	complete(&mspi->done);
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 10/11] spi: fsl-espi: add support for RXSKIP mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (7 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 09/11] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
  2016-10-02 12:23   ` [PATCH 11/11] spi: fsl-espi: add support for dual read mode Heiner Kallweit
                     ` (9 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This patch adds support for ESPI RXSKIP mode. This mode is optimized
for flash reads:
- sends a number of bytes and then reads a number of bytes
- shifts out zeros automatically when reading
- optionally can be configured for dual read mode

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 56 ++++++++++++++++++++++++++++++++++++++++++----
 drivers/spi/spi-fsl-lib.h  |  1 +
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index cbfb6da..8cfcf41 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -150,7 +150,8 @@ static void fsl_espi_copy_to_buf(struct spi_message *m,
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (t->tx_buf)
 			fsl_espi_memcpy_swab(buf, t->tx_buf, m, t);
-		else
+		/* In RXSKIP mode controller shifts zeros automatically */
+		else if (!mspi->rxskip)
 			memset(buf, 0, t->len);
 		buf += t->len;
 	}
@@ -203,6 +204,42 @@ static int fsl_espi_check_message(struct spi_message *m)
 	return 0;
 }
 
+static void fsl_espi_check_rxskip_mode(struct spi_message *m,
+				       struct mpc8xxx_spi *mspi)
+{
+	struct spi_transfer *t;
+	unsigned int i = 0, rxskip_len = 0;
+
+	mspi->rxskip = 0;
+
+	/*
+	 * prerequisites for rxskip mode:
+	 * - message has two transfers
+	 * - first transfer is a write and second is a read
+	 *
+	 * In addition enable rxskip mode only if length of write transfer
+	 * is <= FSL_ESPI_FIFO_SIZE. This allows to keep the current
+	 * low-level transfer implementation.
+	 * This constraint doesn't affect SPI NOR reads as typical use case
+	 * for rxskip mode as the read command has only few bytes.
+	 */
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (i == 0) {
+			if (!t->tx_buf || t->rx_buf ||
+			    t->len > FSL_ESPI_FIFO_SIZE)
+				return;
+			rxskip_len = t->len;
+		} else if (i == 1) {
+			if (t->tx_buf || !t->rx_buf)
+				return;
+		}
+		i++;
+	}
+
+	if (i == 2)
+		mspi->rxskip = rxskip_len;
+}
+
 static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 {
 	u32 tx_fifo_avail;
@@ -282,7 +319,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
-	u32 mask;
+	u32 mask, spcom;
 	int ret;
 
 	mpc8xxx_spi->rx_len = t->len;
@@ -294,8 +331,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	reinit_completion(&mpc8xxx_spi->done);
 
 	/* Set SPCOM[CS] and SPCOM[TRANLEN] field */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM,
-		(SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1)));
+	spcom = SPCOM_CS(spi->chip_select);
+	spcom |= SPCOM_TRANLEN(t->len - 1);
+
+	/* configure RXSKIP mode */
+	if (mpc8xxx_spi->rxskip) {
+		spcom |= SPCOM_RXSKIP(mpc8xxx_spi->rxskip);
+		mpc8xxx_spi->tx_len = mpc8xxx_spi->rxskip;
+		mpc8xxx_spi->rx_len = t->len - mpc8xxx_spi->rxskip;
+		mpc8xxx_spi->rx = t->rx_buf + mpc8xxx_spi->rxskip;
+	}
+
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, spcom);
 
 	/* enable interrupts */
 	mask = SPIM_DON;
@@ -327,6 +374,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 	struct spi_device *spi = m->spi;
 	int ret;
 
+	fsl_espi_check_rxskip_mode(m, mspi);
 	fsl_espi_copy_to_buf(m, mspi);
 	fsl_espi_setup_transfer(spi, trans);
 
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 35a7a17..8096fae 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -32,6 +32,7 @@ struct mpc8xxx_spi {
 	unsigned int rx_len;
 	unsigned int tx_len;
 	u8 *local_buf;
+	unsigned int rxskip;
 	spinlock_t lock;
 #endif
 
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 11/11] spi: fsl-espi: add support for dual read mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (8 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 10/11] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
@ 2016-10-02 12:23   ` Heiner Kallweit
  2016-10-27 19:24   ` [PATCH v2 01/09] spi: fsl-espi: improve check for SPI_QE_CPU_MODE Heiner Kallweit
                     ` (8 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-02 12:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This patch adds support for dual output read mode.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 8cfcf41..cf2a287 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -205,10 +205,11 @@ static int fsl_espi_check_message(struct spi_message *m)
 }
 
 static void fsl_espi_check_rxskip_mode(struct spi_message *m,
-				       struct mpc8xxx_spi *mspi)
+				       struct mpc8xxx_spi *mspi,
+				       struct spi_transfer *tr)
 {
 	struct spi_transfer *t;
-	unsigned int i = 0, rxskip_len = 0;
+	unsigned int i = 0, rxskip_len = 0, rx_nbits = SPI_NBITS_SINGLE;
 
 	mspi->rxskip = 0;
 
@@ -222,6 +223,9 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m,
 	 * low-level transfer implementation.
 	 * This constraint doesn't affect SPI NOR reads as typical use case
 	 * for rxskip mode as the read command has only few bytes.
+	 *
+	 * Store rx_nbits of the read transfer for later assessment
+	 * whether single or dual mode is requested.
 	 */
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (i == 0) {
@@ -232,12 +236,15 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m,
 		} else if (i == 1) {
 			if (t->tx_buf || !t->rx_buf)
 				return;
+			rx_nbits = t->rx_nbits;
 		}
 		i++;
 	}
 
-	if (i == 2)
+	if (i == 2) {
 		mspi->rxskip = rxskip_len;
+		tr->rx_nbits = rx_nbits;
+	}
 }
 
 static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
@@ -340,6 +347,8 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 		mpc8xxx_spi->tx_len = mpc8xxx_spi->rxskip;
 		mpc8xxx_spi->rx_len = t->len - mpc8xxx_spi->rxskip;
 		mpc8xxx_spi->rx = t->rx_buf + mpc8xxx_spi->rxskip;
+		if (t->rx_nbits == SPI_NBITS_DUAL)
+			spcom |= SPCOM_DO;
 	}
 
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, spcom);
@@ -374,7 +383,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 	struct spi_device *spi = m->spi;
 	int ret;
 
-	fsl_espi_check_rxskip_mode(m, mspi);
+	fsl_espi_check_rxskip_mode(m, mspi, trans);
 	fsl_espi_copy_to_buf(m, mspi);
 	fsl_espi_setup_transfer(spi, trans);
 
@@ -588,6 +597,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 
 	mpc8xxx_spi_probe(dev, mem, irq);
 
+	master->mode_bits |= SPI_RX_DUAL;
 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 	master->setup = fsl_espi_setup;
 	master->cleanup = fsl_espi_cleanup;
-- 
2.10.0


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE
       [not found]     ` <20608368-44e6-21f8-d970-5ade9990ce59-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-06 15:45       ` Mark Brown
       [not found]         ` <20161006154543.rxlrc3sumejozpcg-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Brown @ 2016-10-06 15:45 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 416 bytes --]

On Sun, Oct 02, 2016 at 02:22:48PM +0200, Heiner Kallweit wrote:
> SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
> based on DT property "mode". This property is not defined for ESPI,
> see Documentation/devicetree/bindings/spi/fsl-spi.txt
> Therefore remove the check.

Shouldn't we be warning if we encounter a DT that has this set since it
probably indicates that something went wrong?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE
       [not found]         ` <20161006154543.rxlrc3sumejozpcg-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
@ 2016-10-06 18:36           ` Heiner Kallweit
       [not found]             ` <bbe77580-1ac2-4071-5d7d-f786c54ad177-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-06 18:36 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Am 06.10.2016 um 17:45 schrieb Mark Brown:
> On Sun, Oct 02, 2016 at 02:22:48PM +0200, Heiner Kallweit wrote:
>> SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
>> based on DT property "mode". This property is not defined for ESPI,
>> see Documentation/devicetree/bindings/spi/fsl-spi.txt
>> Therefore remove the check.
> 
> Shouldn't we be warning if we encounter a DT that has this set since it
> probably indicates that something went wrong?
> 
The values of mpc8xxx_spi->rx_shift and mpc8xxx_spi->tx_shift were
overwritten in fsl_espi_setup_transfer anyway. Therefore the removed
code effectively was dead code.
As we just remove dead code and don't change the behavior of the driver
I see no need to introduce an additional check / warning.

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE
       [not found]             ` <bbe77580-1ac2-4071-5d7d-f786c54ad177-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-26 17:07               ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-26 17:07 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 792 bytes --]

On Thu, Oct 06, 2016 at 08:36:29PM +0200, Heiner Kallweit wrote:
> Am 06.10.2016 um 17:45 schrieb Mark Brown:

> > Shouldn't we be warning if we encounter a DT that has this set since it
> > probably indicates that something went wrong?

> The values of mpc8xxx_spi->rx_shift and mpc8xxx_spi->tx_shift were
> overwritten in fsl_espi_setup_transfer anyway. Therefore the removed
> code effectively was dead code.
> As we just remove dead code and don't change the behavior of the driver
> I see no need to introduce an additional check / warning.

There's still the potential to either uncover an existing bug that only
worked by accident or to catch some future bug that someone introduces.
The existing code may have problems but that doesn't mean it's not a
good idea to do a good job now.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 01/09] spi: fsl-espi: improve check for SPI_QE_CPU_MODE
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (9 preceding siblings ...)
  2016-10-02 12:23   ` [PATCH 11/11] spi: fsl-espi: add support for dual read mode Heiner Kallweit
@ 2016-10-27 19:24   ` Heiner Kallweit
       [not found]     ` <0b5e7849-88d6-2af5-a428-eeb0de0f2af2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-27 19:25   ` [PATCH v2 02/09] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
                     ` (7 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:24 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
based on DT property "mode". This property is not defined for ESPI,
see Documentation/devicetree/bindings/spi/fsl-spi.txt.
So print an error message and bail out if SPI_QE_CPU_MODE is set.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- print error message and bail out instead of removing the check
---
 drivers/spi/spi-fsl-espi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 4e8a99d..f04c246 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -583,8 +583,9 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 		goto err_probe;
 
 	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
-		mpc8xxx_spi->rx_shift = 16;
-		mpc8xxx_spi->tx_shift = 24;
+		dev_err(dev, "SPI_QE_CPU_MODE is not supported on ESPI!\n");
+		ret = -EINVAL;
+		goto err_probe;
 	}
 
 	/* SPI controller initializations */
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 02/09] spi: fsl-espi: fix and improve writing to TX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (10 preceding siblings ...)
  2016-10-27 19:24   ` [PATCH v2 01/09] spi: fsl-espi: improve check for SPI_QE_CPU_MODE Heiner Kallweit
@ 2016-10-27 19:25   ` Heiner Kallweit
  2016-10-27 19:26   ` [PATCH v2 03/09] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
                     ` (6 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:25 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This change addresses two issues:
- If the TX FIFO is full the ISR polls until there's free space again.
  An ISR should never wait for something.
- Currently the number of bytes to transfer is rounded up to the next
  multiple of 4. For most transfers therefore few bytes remain in the
  TX FIFO after end of transfer.
  This would cause the next transfer to fail and as a workaround the
  ESPI block is disabled / re-enabled in fsl_espi_change_mode.
  This seems to clear the FIFO's (although it's not mentioned in the
  spec).

With this change the TX FIFO is filled as much as possible initially
and whenever the ISR is called. Also the exact number of bytes is
transferred.
The spinlock protects against a potential race if the first interrupt
occurs whilst the TX FIFO is still being initially filled.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 68 ++++++++++++++++++++++++++++------------------
 drivers/spi/spi-fsl-lib.h  |  2 ++
 2 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index f04c246..95c1fbf 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -54,6 +54,8 @@
 #define CSMODE_AFT(x)		((x) << 8)
 #define CSMODE_CG(x)		((x) << 3)
 
+#define FSL_ESPI_FIFO_SIZE	32
+
 /* Default mode/csmode for eSPI controller */
 #define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
@@ -200,6 +202,27 @@ static int fsl_espi_check_message(struct spi_message *m)
 	return 0;
 }
 
+static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 tx_fifo_avail;
+
+	/* if events is zero transfer has not started and tx fifo is empty */
+	tx_fifo_avail = events ? SPIE_TXCNT(events) :  FSL_ESPI_FIFO_SIZE;
+
+	while (tx_fifo_avail >= min(4U, mspi->tx_len) && mspi->tx_len)
+		if (mspi->tx_len >= 4) {
+			fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
+			mspi->tx += 4;
+			mspi->tx_len -= 4;
+			tx_fifo_avail -= 4;
+		} else {
+			fsl_espi_write_reg8(mspi, ESPI_SPITF, *(u8 *)mspi->tx);
+			mspi->tx += 1;
+			mspi->tx_len -= 1;
+			tx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_change_mode(struct spi_device *spi)
 {
 	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
@@ -262,7 +285,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	int ret;
 
 	mpc8xxx_spi->len = t->len;
-	mpc8xxx_spi->count = roundup(t->len, 4) / 4;
+	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
 	mpc8xxx_spi->rx = t->rx_buf;
@@ -276,21 +299,22 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	/* enable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
 
-	/* transmit word */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, *(u32 *)mpc8xxx_spi->tx);
-	mpc8xxx_spi->tx += 4;
+	/* Prevent filling the fifo from getting interrupted */
+	spin_lock_irq(&mpc8xxx_spi->lock);
+	fsl_espi_fill_tx_fifo(mpc8xxx_spi, 0);
+	spin_unlock_irq(&mpc8xxx_spi->lock);
 
 	/* Won't hang up forever, SPI bus sometimes got lost interrupts... */
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %d bytes)\n",
-			mpc8xxx_spi->count);
+			"Transaction hanging up (left %u bytes)\n",
+			mpc8xxx_spi->tx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->count > 0 ? -EMSGSIZE : 0;
+	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -461,26 +485,11 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		}
 	}
 
-	if (!(events & SPIE_TNF)) {
-		int ret;
-
-		/* spin until TX is done */
-		ret = spin_event_timeout(((events = fsl_espi_read_reg(
-				mspi, ESPI_SPIE)) & SPIE_TNF), 1000, 0);
-		if (!ret) {
-			dev_err(mspi->dev, "tired waiting for SPIE_TNF\n");
-			complete(&mspi->done);
-			return;
-		}
-	}
+	if (mspi->tx_len)
+		fsl_espi_fill_tx_fifo(mspi, events);
 
-	mspi->count -= 1;
-	if (mspi->count) {
-		fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
-		mspi->tx += 4;
-	} else {
+	if (!mspi->tx_len && !mspi->len)
 		complete(&mspi->done);
-	}
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
@@ -488,10 +497,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	struct mpc8xxx_spi *mspi = context_data;
 	u32 events;
 
+	spin_lock(&mspi->lock);
+
 	/* Get interrupt events(tx/rx) */
 	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
-	if (!events)
+	if (!events) {
+		spin_unlock_irq(&mspi->lock);
 		return IRQ_NONE;
+	}
 
 	dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events);
 
@@ -500,6 +513,8 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	/* Clear the events */
 	fsl_espi_write_reg(mspi, ESPI_SPIE, events);
 
+	spin_unlock(&mspi->lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -562,6 +577,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 	master->max_message_size = fsl_espi_max_message_size;
 
 	mpc8xxx_spi = spi_master_get_devdata(master);
+	spin_lock_init(&mpc8xxx_spi->lock);
 
 	mpc8xxx_spi->local_buf =
 		devm_kmalloc(dev, SPCOM_TRANLEN_MAX, GFP_KERNEL);
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 2925c80..24d8bc8 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -30,7 +30,9 @@ struct mpc8xxx_spi {
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
 	int len;
+	unsigned int tx_len;
 	u8 *local_buf;
+	spinlock_t lock;
 #endif
 
 	int subblock;
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 03/09] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (11 preceding siblings ...)
  2016-10-27 19:25   ` [PATCH v2 02/09] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
@ 2016-10-27 19:26   ` Heiner Kallweit
       [not found]     ` <611500a3-d254-f04c-ce20-6905a649bcda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-27 19:26   ` [PATCH v2 04/09] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
                     ` (5 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:26 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Now that we introduced element tx_len in struct mpc8xxx_spi let's
rename element len to rx_len as it actually is the number of bytes to
receive. In addition make it unsigned.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++-----------
 drivers/spi/spi-fsl-lib.h  |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 95c1fbf..5a7449f 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -284,7 +284,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
 	int ret;
 
-	mpc8xxx_spi->len = t->len;
+	mpc8xxx_spi->rx_len = t->len;
 	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
@@ -445,28 +445,28 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		int ret;
 
 		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4, mspi->len)) {
+		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
 			ret = spin_event_timeout(
 				!(SPIE_RXCNT(events =
 				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4, mspi->len)),
+						min(4U, mspi->rx_len)),
 						10000, 0); /* 10 msec */
 			if (!ret)
 				dev_err(mspi->dev,
 					 "tired waiting for SPIE_RXCNT\n");
 		}
 
-		if (mspi->len >= 4) {
+		if (mspi->rx_len >= 4) {
 			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (mspi->len <= 0) {
+		} else if (!mspi->rx_len) {
 			dev_err(mspi->dev,
 				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
 				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4, mspi->len), SPIE_RXCNT(events));
+				min(4U, mspi->rx_len), SPIE_RXCNT(events));
 			rx_nr_bytes = 0;
 		} else {
-			rx_nr_bytes = mspi->len;
-			tmp = mspi->len;
+			rx_nr_bytes = mspi->rx_len;
+			tmp = mspi->rx_len;
 			rx_data = 0;
 			while (tmp--) {
 				rx_data_8 = fsl_espi_read_reg8(mspi,
@@ -474,10 +474,10 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 				rx_data |= (rx_data_8 << (tmp * 8));
 			}
 
-			rx_data <<= (4 - mspi->len) * 8;
+			rx_data <<= (4 - mspi->rx_len) * 8;
 		}
 
-		mspi->len -= rx_nr_bytes;
+		mspi->rx_len -= rx_nr_bytes;
 
 		if (rx_nr_bytes && mspi->rx) {
 			*(u32 *)mspi->rx = rx_data;
@@ -488,7 +488,7 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->len)
+	if (!mspi->tx_len && !mspi->rx_len)
 		complete(&mspi->done);
 }
 
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 24d8bc8..35a7a17 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -29,7 +29,7 @@ struct mpc8xxx_spi {
 	const void *tx;
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
-	int len;
+	unsigned int rx_len;
 	unsigned int tx_len;
 	u8 *local_buf;
 	spinlock_t lock;
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 04/09] spi: fsl-espi: simplify and inline function fsl_espi_change_mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (12 preceding siblings ...)
  2016-10-27 19:26   ` [PATCH v2 03/09] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
@ 2016-10-27 19:26   ` Heiner Kallweit
  2016-10-27 19:27   ` [PATCH v2 05/09] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
                     ` (4 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:26 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

The ESPI spec mentions no requirement to turn off the ESPI unit prior
to changing the mode. Most likely the ESPI unit is only turned off to
clear the FIFO's as before this patch series single bytes could
remain in the TX FIFO after transfer end.
Therefore remove disabling / re-enabling the ESPI unit.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 23 ++---------------------
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 5a7449f..d550685 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -223,26 +223,6 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
-static void fsl_espi_change_mode(struct spi_device *spi)
-{
-	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
-	struct spi_mpc8xxx_cs *cs = spi->controller_state;
-	u32 tmp;
-	unsigned long flags;
-
-	/* Turn off IRQs locally to minimize time that SPI is disabled. */
-	local_irq_save(flags);
-
-	/* Turn off SPI unit prior changing mode */
-	tmp = fsl_espi_read_reg(mspi, ESPI_SPMODE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp & ~SPMODE_ENABLE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODEx(spi->chip_select),
-			      cs->hw_mode);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp);
-
-	local_irq_restore(flags);
-}
-
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -276,7 +256,8 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 
 	cs->hw_mode |= CSMODE_PM(pm);
 
-	fsl_espi_change_mode(spi);
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(spi->chip_select),
+			   cs->hw_mode);
 }
 
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 05/09] spi: fsl-espi: fix and improve reading from RX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (13 preceding siblings ...)
  2016-10-27 19:26   ` [PATCH v2 04/09] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
@ 2016-10-27 19:27   ` Heiner Kallweit
       [not found]     ` <6ae20ab9-4068-9be7-654d-12424de35716-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-27 19:27   ` [PATCH v2 06/09] spi: fsl-espi: make better use of the RX FIFO Heiner Kallweit
                     ` (3 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Currently the driver polls in the ISR for enough bytes in the RX FIFO.
An ISR should never do this.
Change it to read as much as possible whenever the ISR is called.
This also allows to significantly simplify the code.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 67 ++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 47 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index d550685..ca14575 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -223,6 +223,24 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
+static void fsl_espi_read_rx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 rx_fifo_avail = SPIE_RXCNT(events);
+
+	while (rx_fifo_avail >= min(4U, mspi->rx_len) && mspi->rx_len)
+		if (mspi->rx_len >= 4) {
+			*(u32 *)mspi->rx = fsl_espi_read_reg(mspi, ESPI_SPIRF);
+			mspi->rx += 4;
+			mspi->rx_len -= 4;
+			rx_fifo_avail -= 4;
+		} else {
+			*(u8 *)mspi->rx = fsl_espi_read_reg8(mspi, ESPI_SPIRF);
+			mspi->rx += 1;
+			mspi->rx_len -= 1;
+			rx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -418,53 +436,8 @@ static void fsl_espi_cleanup(struct spi_device *spi)
 
 static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 {
-	/* We need handle RX first */
-	if (events & SPIE_RNE) {
-		u32 rx_data, tmp;
-		u8 rx_data_8;
-		int rx_nr_bytes = 4;
-		int ret;
-
-		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
-			ret = spin_event_timeout(
-				!(SPIE_RXCNT(events =
-				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4U, mspi->rx_len)),
-						10000, 0); /* 10 msec */
-			if (!ret)
-				dev_err(mspi->dev,
-					 "tired waiting for SPIE_RXCNT\n");
-		}
-
-		if (mspi->rx_len >= 4) {
-			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (!mspi->rx_len) {
-			dev_err(mspi->dev,
-				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
-				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4U, mspi->rx_len), SPIE_RXCNT(events));
-			rx_nr_bytes = 0;
-		} else {
-			rx_nr_bytes = mspi->rx_len;
-			tmp = mspi->rx_len;
-			rx_data = 0;
-			while (tmp--) {
-				rx_data_8 = fsl_espi_read_reg8(mspi,
-							       ESPI_SPIRF);
-				rx_data |= (rx_data_8 << (tmp * 8));
-			}
-
-			rx_data <<= (4 - mspi->rx_len) * 8;
-		}
-
-		mspi->rx_len -= rx_nr_bytes;
-
-		if (rx_nr_bytes && mspi->rx) {
-			*(u32 *)mspi->rx = rx_data;
-			mspi->rx += 4;
-		}
-	}
+	if (mspi->rx_len)
+		fsl_espi_read_rx_fifo(mspi, events);
 
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 06/09] spi: fsl-espi: make better use of the RX FIFO
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (14 preceding siblings ...)
  2016-10-27 19:27   ` [PATCH v2 05/09] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
@ 2016-10-27 19:27   ` Heiner Kallweit
  2016-10-27 19:28   ` [PATCH v2 07/09] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
                     ` (2 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

So far an interrupt is triggered whenever there's at least one byte
in the RX FIFO. This results in a unnecessarily high number of
interrupts.
Change this to generate an interrupt if
- RX FIFO is half full (except if all bytes to read fit into the
  RX FIFO anyway)
- end of transfer has been reached

This way the number of interrupts can be significantly reduced.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index ca14575..06fb185 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -55,9 +55,10 @@
 #define CSMODE_CG(x)		((x) << 3)
 
 #define FSL_ESPI_FIFO_SIZE	32
+#define FSL_ESPI_RXTHR		15
 
 /* Default mode/csmode for eSPI controller */
-#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
+#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(FSL_ESPI_RXTHR))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
 		| CSMODE_AFT(0) | CSMODE_CG(1))
 
@@ -281,6 +282,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
+	u32 mask;
 	int ret;
 
 	mpc8xxx_spi->rx_len = t->len;
@@ -295,8 +297,11 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM,
 		(SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1)));
 
-	/* enable rx ints */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
+	/* enable interrupts */
+	mask = SPIM_DON;
+	if (mpc8xxx_spi->rx_len > FSL_ESPI_FIFO_SIZE)
+		mask |= SPIM_RXT;
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, mask);
 
 	/* Prevent filling the fifo from getting interrupted */
 	spin_lock_irq(&mpc8xxx_spi->lock);
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 07/09] spi: fsl-espi: extend and improve transfer error handling
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (15 preceding siblings ...)
  2016-10-27 19:27   ` [PATCH v2 06/09] spi: fsl-espi: make better use of the RX FIFO Heiner Kallweit
@ 2016-10-27 19:28   ` Heiner Kallweit
  2016-10-27 19:28   ` [PATCH v2 08/09] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
  2016-10-27 19:29   ` [PATCH v2 09/09] spi: fsl-espi: add support for dual read mode Heiner Kallweit
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:28 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

Extend and improve transfer error handling
- in case of timeout report also number of remaining rx bytes
- in case of timeout return ETIMEDOUT instead of EMSGSIZE
- add sanity checks after all bytes have been sent / read:
 - check that HW has flag SPIE_DON set
 - check that RX / TX FIFO are empty

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 06fb185..2f95b19 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -312,13 +312,13 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %u bytes)\n",
-			mpc8xxx_spi->tx_len);
+			"Transaction hanging up (left %u tx bytes, %u rx bytes)\n",
+			mpc8xxx_spi->tx_len, mpc8xxx_spi->rx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
+	return ret == 0 ? -ETIMEDOUT : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -447,8 +447,20 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->rx_len)
-		complete(&mspi->done);
+	if (mspi->tx_len || mspi->rx_len)
+		return;
+
+	/* we're done, but check for errors before returning */
+	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
+
+	if (!(events & SPIE_DON))
+		dev_err(mspi->dev,
+			"Transfer done but SPIE_DON isn't set!\n");
+
+	if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE)
+		dev_err(mspi->dev, "Transfer done but rx/tx fifo's aren't empty!\n");
+
+	complete(&mspi->done);
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 08/09] spi: fsl-espi: add support for RXSKIP mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (16 preceding siblings ...)
  2016-10-27 19:28   ` [PATCH v2 07/09] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
@ 2016-10-27 19:28   ` Heiner Kallweit
  2016-10-27 19:29   ` [PATCH v2 09/09] spi: fsl-espi: add support for dual read mode Heiner Kallweit
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:28 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This patch adds support for ESPI RXSKIP mode. This mode is optimized
for flash reads:
- sends a number of bytes and then reads a number of bytes
- shifts out zeros automatically when reading
- optionally can be configured for dual read mode

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
---
 drivers/spi/spi-fsl-espi.c | 56 ++++++++++++++++++++++++++++++++++++++++++----
 drivers/spi/spi-fsl-lib.h  |  1 +
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 2f95b19..e32dc30 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -150,7 +150,8 @@ static void fsl_espi_copy_to_buf(struct spi_message *m,
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (t->tx_buf)
 			fsl_espi_memcpy_swab(buf, t->tx_buf, m, t);
-		else
+		/* In RXSKIP mode controller shifts zeros automatically */
+		else if (!mspi->rxskip)
 			memset(buf, 0, t->len);
 		buf += t->len;
 	}
@@ -203,6 +204,42 @@ static int fsl_espi_check_message(struct spi_message *m)
 	return 0;
 }
 
+static void fsl_espi_check_rxskip_mode(struct spi_message *m,
+				       struct mpc8xxx_spi *mspi)
+{
+	struct spi_transfer *t;
+	unsigned int i = 0, rxskip_len = 0;
+
+	mspi->rxskip = 0;
+
+	/*
+	 * prerequisites for rxskip mode:
+	 * - message has two transfers
+	 * - first transfer is a write and second is a read
+	 *
+	 * In addition enable rxskip mode only if length of write transfer
+	 * is <= FSL_ESPI_FIFO_SIZE. This allows to keep the current
+	 * low-level transfer implementation.
+	 * This constraint doesn't affect SPI NOR reads as typical use case
+	 * for rxskip mode as the read command has only few bytes.
+	 */
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (i == 0) {
+			if (!t->tx_buf || t->rx_buf ||
+			    t->len > FSL_ESPI_FIFO_SIZE)
+				return;
+			rxskip_len = t->len;
+		} else if (i == 1) {
+			if (t->tx_buf || !t->rx_buf)
+				return;
+		}
+		i++;
+	}
+
+	if (i == 2)
+		mspi->rxskip = rxskip_len;
+}
+
 static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 {
 	u32 tx_fifo_avail;
@@ -282,7 +319,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
-	u32 mask;
+	u32 mask, spcom;
 	int ret;
 
 	mpc8xxx_spi->rx_len = t->len;
@@ -294,8 +331,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	reinit_completion(&mpc8xxx_spi->done);
 
 	/* Set SPCOM[CS] and SPCOM[TRANLEN] field */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM,
-		(SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1)));
+	spcom = SPCOM_CS(spi->chip_select);
+	spcom |= SPCOM_TRANLEN(t->len - 1);
+
+	/* configure RXSKIP mode */
+	if (mpc8xxx_spi->rxskip) {
+		spcom |= SPCOM_RXSKIP(mpc8xxx_spi->rxskip);
+		mpc8xxx_spi->tx_len = mpc8xxx_spi->rxskip;
+		mpc8xxx_spi->rx_len = t->len - mpc8xxx_spi->rxskip;
+		mpc8xxx_spi->rx = t->rx_buf + mpc8xxx_spi->rxskip;
+	}
+
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, spcom);
 
 	/* enable interrupts */
 	mask = SPIM_DON;
@@ -327,6 +374,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 	struct spi_device *spi = m->spi;
 	int ret;
 
+	fsl_espi_check_rxskip_mode(m, mspi);
 	fsl_espi_copy_to_buf(m, mspi);
 	fsl_espi_setup_transfer(spi, trans);
 
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 35a7a17..8096fae 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -32,6 +32,7 @@ struct mpc8xxx_spi {
 	unsigned int rx_len;
 	unsigned int tx_len;
 	u8 *local_buf;
+	unsigned int rxskip;
 	spinlock_t lock;
 #endif
 
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 09/09] spi: fsl-espi: add support for dual read mode
       [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (17 preceding siblings ...)
  2016-10-27 19:28   ` [PATCH v2 08/09] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
@ 2016-10-27 19:29   ` Heiner Kallweit
  18 siblings, 0 replies; 30+ messages in thread
From: Heiner Kallweit @ 2016-10-27 19:29 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

This patch adds support for dual output read mode.

It was successfully tested on a P1014-based device
with a S25FL128S spi nor flash.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
v2:
- rebased
- extended commit message
---
 drivers/spi/spi-fsl-espi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index e32dc30..5753b1e 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -205,10 +205,11 @@ static int fsl_espi_check_message(struct spi_message *m)
 }
 
 static void fsl_espi_check_rxskip_mode(struct spi_message *m,
-				       struct mpc8xxx_spi *mspi)
+				       struct mpc8xxx_spi *mspi,
+				       struct spi_transfer *tr)
 {
 	struct spi_transfer *t;
-	unsigned int i = 0, rxskip_len = 0;
+	unsigned int i = 0, rxskip_len = 0, rx_nbits = SPI_NBITS_SINGLE;
 
 	mspi->rxskip = 0;
 
@@ -222,6 +223,9 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m,
 	 * low-level transfer implementation.
 	 * This constraint doesn't affect SPI NOR reads as typical use case
 	 * for rxskip mode as the read command has only few bytes.
+	 *
+	 * Store rx_nbits of the read transfer for later assessment
+	 * whether single or dual mode is requested.
 	 */
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (i == 0) {
@@ -232,12 +236,15 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m,
 		} else if (i == 1) {
 			if (t->tx_buf || !t->rx_buf)
 				return;
+			rx_nbits = t->rx_nbits;
 		}
 		i++;
 	}
 
-	if (i == 2)
+	if (i == 2) {
 		mspi->rxskip = rxskip_len;
+		tr->rx_nbits = rx_nbits;
+	}
 }
 
 static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
@@ -340,6 +347,8 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 		mpc8xxx_spi->tx_len = mpc8xxx_spi->rxskip;
 		mpc8xxx_spi->rx_len = t->len - mpc8xxx_spi->rxskip;
 		mpc8xxx_spi->rx = t->rx_buf + mpc8xxx_spi->rxskip;
+		if (t->rx_nbits == SPI_NBITS_DUAL)
+			spcom |= SPCOM_DO;
 	}
 
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, spcom);
@@ -374,7 +383,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 	struct spi_device *spi = m->spi;
 	int ret;
 
-	fsl_espi_check_rxskip_mode(m, mspi);
+	fsl_espi_check_rxskip_mode(m, mspi, trans);
 	fsl_espi_copy_to_buf(m, mspi);
 	fsl_espi_setup_transfer(spi, trans);
 
@@ -588,6 +597,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 
 	mpc8xxx_spi_probe(dev, mem, irq);
 
+	master->mode_bits |= SPI_RX_DUAL;
 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 	master->setup = fsl_espi_setup;
 	master->cleanup = fsl_espi_cleanup;
-- 
2.10.1


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 01/09] spi: fsl-espi: improve check for SPI_QE_CPU_MODE
       [not found]     ` <0b5e7849-88d6-2af5-a428-eeb0de0f2af2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:34       ` Mark Brown
  2016-10-28 18:53       ` Applied "spi: fsl-espi: improve check for SPI_QE_CPU_MODE" to the spi tree Mark Brown
  1 sibling, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:34 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA

On Thu, Oct 27, 2016 at 09:24:01PM +0200, Heiner Kallweit wrote:
> SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
> based on DT property "mode". This property is not defined for ESPI,
> see Documentation/devicetree/bindings/spi/fsl-spi.txt.
> So print an error message and bail out if SPI_QE_CPU_MODE is set.

Please don't send new patches in reply to old ones, it makes it harder
to follow what's going on.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: fix and improve reading from RX FIFO" to the spi tree
       [not found]     ` <6ae20ab9-4068-9be7-654d-12424de35716-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:51       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:51 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: fix and improve reading from RX FIFO

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From f05689a662d47896da742f5338eab183ed692c1c Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:27:35 +0200
Subject: [PATCH] spi: fsl-espi: fix and improve reading from RX FIFO

Currently the driver polls in the ISR for enough bytes in the RX FIFO.
An ISR should never do this.
Change it to read as much as possible whenever the ISR is called.
This also allows to significantly simplify the code.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 67 ++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 47 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 239f0362df61..2f95b19e67f7 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -224,6 +224,24 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
+static void fsl_espi_read_rx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 rx_fifo_avail = SPIE_RXCNT(events);
+
+	while (rx_fifo_avail >= min(4U, mspi->rx_len) && mspi->rx_len)
+		if (mspi->rx_len >= 4) {
+			*(u32 *)mspi->rx = fsl_espi_read_reg(mspi, ESPI_SPIRF);
+			mspi->rx += 4;
+			mspi->rx_len -= 4;
+			rx_fifo_avail -= 4;
+		} else {
+			*(u8 *)mspi->rx = fsl_espi_read_reg8(mspi, ESPI_SPIRF);
+			mspi->rx += 1;
+			mspi->rx_len -= 1;
+			rx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -423,53 +441,8 @@ static void fsl_espi_cleanup(struct spi_device *spi)
 
 static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 {
-	/* We need handle RX first */
-	if (events & SPIE_RNE) {
-		u32 rx_data, tmp;
-		u8 rx_data_8;
-		int rx_nr_bytes = 4;
-		int ret;
-
-		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
-			ret = spin_event_timeout(
-				!(SPIE_RXCNT(events =
-				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4U, mspi->rx_len)),
-						10000, 0); /* 10 msec */
-			if (!ret)
-				dev_err(mspi->dev,
-					 "tired waiting for SPIE_RXCNT\n");
-		}
-
-		if (mspi->rx_len >= 4) {
-			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (!mspi->rx_len) {
-			dev_err(mspi->dev,
-				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
-				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4U, mspi->rx_len), SPIE_RXCNT(events));
-			rx_nr_bytes = 0;
-		} else {
-			rx_nr_bytes = mspi->rx_len;
-			tmp = mspi->rx_len;
-			rx_data = 0;
-			while (tmp--) {
-				rx_data_8 = fsl_espi_read_reg8(mspi,
-							       ESPI_SPIRF);
-				rx_data |= (rx_data_8 << (tmp * 8));
-			}
-
-			rx_data <<= (4 - mspi->rx_len) * 8;
-		}
-
-		mspi->rx_len -= rx_nr_bytes;
-
-		if (rx_nr_bytes && mspi->rx) {
-			*(u32 *)mspi->rx = rx_data;
-			mspi->rx += 4;
-		}
-	}
+	if (mspi->rx_len)
+		fsl_espi_read_rx_fifo(mspi, events);
 
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: make better use of the RX FIFO" to the spi tree
       [not found]     ` <144b73b1-dff2-a5b6-9df1-837238f20008-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:51       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:51 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: make better use of the RX FIFO

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From e508cea45bc31de87b35180a9ba5ef9572ffde3f Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:27:56 +0200
Subject: [PATCH] spi: fsl-espi: make better use of the RX FIFO

So far an interrupt is triggered whenever there's at least one byte
in the RX FIFO. This results in a unnecessarily high number of
interrupts.
Change this to generate an interrupt if
- RX FIFO is half full (except if all bytes to read fit into the
  RX FIFO anyway)
- end of transfer has been reached

This way the number of interrupts can be significantly reduced.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index a9593f9691ec..239f0362df61 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -55,9 +55,10 @@
 #define CSMODE_CG(x)		((x) << 3)
 
 #define FSL_ESPI_FIFO_SIZE	32
+#define FSL_ESPI_RXTHR		15
 
 /* Default mode/csmode for eSPI controller */
-#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
+#define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(FSL_ESPI_RXTHR))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
 		| CSMODE_AFT(0) | CSMODE_CG(1))
 
@@ -263,6 +264,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
+	u32 mask;
 	int ret;
 
 	mpc8xxx_spi->rx_len = t->len;
@@ -277,8 +279,11 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM,
 		(SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1)));
 
-	/* enable rx ints */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
+	/* enable interrupts */
+	mask = SPIM_DON;
+	if (mpc8xxx_spi->rx_len > FSL_ESPI_FIFO_SIZE)
+		mask |= SPIM_RXT;
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, mask);
 
 	/* Prevent filling the fifo from getting interrupted */
 	spin_lock_irq(&mpc8xxx_spi->lock);
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: extend and improve transfer error handling" to the spi tree
       [not found]     ` <4ba19a7f-9f66-54c4-9119-e85671d608fb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:52       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:52 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: extend and improve transfer error handling

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From db1b049fad8b12062edffade8272d604b4019eb7 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:28:02 +0200
Subject: [PATCH] spi: fsl-espi: extend and improve transfer error handling

Extend and improve transfer error handling
- in case of timeout report also number of remaining rx bytes
- in case of timeout return ETIMEDOUT instead of EMSGSIZE
- add sanity checks after all bytes have been sent / read:
 - check that HW has flag SPIE_DON set
 - check that RX / TX FIFO are empty

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index d5506852e63c..a9593f9691ec 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -289,13 +289,13 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %u bytes)\n",
-			mpc8xxx_spi->tx_len);
+			"Transaction hanging up (left %u tx bytes, %u rx bytes)\n",
+			mpc8xxx_spi->tx_len, mpc8xxx_spi->rx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
+	return ret == 0 ? -ETIMEDOUT : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -469,8 +469,20 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->rx_len)
-		complete(&mspi->done);
+	if (mspi->tx_len || mspi->rx_len)
+		return;
+
+	/* we're done, but check for errors before returning */
+	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
+
+	if (!(events & SPIE_DON))
+		dev_err(mspi->dev,
+			"Transfer done but SPIE_DON isn't set!\n");
+
+	if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE)
+		dev_err(mspi->dev, "Transfer done but rx/tx fifo's aren't empty!\n");
+
+	complete(&mspi->done);
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: simplify and inline function fsl_espi_change_mode" to the spi tree
       [not found]     ` <0aeb49f0-dbfb-7acb-3829-cabafe4e7291-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:52       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:52 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: simplify and inline function fsl_espi_change_mode

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From b3bec5f95f73520feb05b90244522f24546e96aa Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:26:46 +0200
Subject: [PATCH] spi: fsl-espi: simplify and inline function
 fsl_espi_change_mode

The ESPI spec mentions no requirement to turn off the ESPI unit prior
to changing the mode. Most likely the ESPI unit is only turned off to
clear the FIFO's as before this patch series single bytes could
remain in the TX FIFO after transfer end.
Therefore remove disabling / re-enabling the ESPI unit.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 23 ++---------------------
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 5a7449f3b3b8..d5506852e63c 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -223,26 +223,6 @@ static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
 		}
 }
 
-static void fsl_espi_change_mode(struct spi_device *spi)
-{
-	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
-	struct spi_mpc8xxx_cs *cs = spi->controller_state;
-	u32 tmp;
-	unsigned long flags;
-
-	/* Turn off IRQs locally to minimize time that SPI is disabled. */
-	local_irq_save(flags);
-
-	/* Turn off SPI unit prior changing mode */
-	tmp = fsl_espi_read_reg(mspi, ESPI_SPMODE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp & ~SPMODE_ENABLE);
-	fsl_espi_write_reg(mspi, ESPI_SPMODEx(spi->chip_select),
-			      cs->hw_mode);
-	fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp);
-
-	local_irq_restore(flags);
-}
-
 static void fsl_espi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -276,7 +256,8 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
 
 	cs->hw_mode |= CSMODE_PM(pm);
 
-	fsl_espi_change_mode(spi);
+	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(spi->chip_select),
+			   cs->hw_mode);
 }
 
 static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned" to the spi tree
       [not found]     ` <611500a3-d254-f04c-ce20-6905a649bcda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:53       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:53 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From f895e27f591228704954cc8927d9c61b3f3da90f Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:26:08 +0200
Subject: [PATCH] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and
 make it unsigned

Now that we introduced element tx_len in struct mpc8xxx_spi let's
rename element len to rx_len as it actually is the number of bytes to
receive. In addition make it unsigned.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 22 +++++++++++-----------
 drivers/spi/spi-fsl-lib.h  |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 95c1fbfe1cbe..5a7449f3b3b8 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -284,7 +284,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
 	int ret;
 
-	mpc8xxx_spi->len = t->len;
+	mpc8xxx_spi->rx_len = t->len;
 	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
@@ -445,28 +445,28 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		int ret;
 
 		/* Spin until RX is done */
-		if (SPIE_RXCNT(events) < min(4, mspi->len)) {
+		if (SPIE_RXCNT(events) < min(4U, mspi->rx_len)) {
 			ret = spin_event_timeout(
 				!(SPIE_RXCNT(events =
 				fsl_espi_read_reg(mspi, ESPI_SPIE)) <
-						min(4, mspi->len)),
+						min(4U, mspi->rx_len)),
 						10000, 0); /* 10 msec */
 			if (!ret)
 				dev_err(mspi->dev,
 					 "tired waiting for SPIE_RXCNT\n");
 		}
 
-		if (mspi->len >= 4) {
+		if (mspi->rx_len >= 4) {
 			rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF);
-		} else if (mspi->len <= 0) {
+		} else if (!mspi->rx_len) {
 			dev_err(mspi->dev,
 				"unexpected RX(SPIE_RNE) interrupt occurred,\n"
 				"(local rxlen %d bytes, reg rxlen %d bytes)\n",
-				min(4, mspi->len), SPIE_RXCNT(events));
+				min(4U, mspi->rx_len), SPIE_RXCNT(events));
 			rx_nr_bytes = 0;
 		} else {
-			rx_nr_bytes = mspi->len;
-			tmp = mspi->len;
+			rx_nr_bytes = mspi->rx_len;
+			tmp = mspi->rx_len;
 			rx_data = 0;
 			while (tmp--) {
 				rx_data_8 = fsl_espi_read_reg8(mspi,
@@ -474,10 +474,10 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 				rx_data |= (rx_data_8 << (tmp * 8));
 			}
 
-			rx_data <<= (4 - mspi->len) * 8;
+			rx_data <<= (4 - mspi->rx_len) * 8;
 		}
 
-		mspi->len -= rx_nr_bytes;
+		mspi->rx_len -= rx_nr_bytes;
 
 		if (rx_nr_bytes && mspi->rx) {
 			*(u32 *)mspi->rx = rx_data;
@@ -488,7 +488,7 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 	if (mspi->tx_len)
 		fsl_espi_fill_tx_fifo(mspi, events);
 
-	if (!mspi->tx_len && !mspi->len)
+	if (!mspi->tx_len && !mspi->rx_len)
 		complete(&mspi->done);
 }
 
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 24d8bc84a111..35a7a1730d0c 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -29,7 +29,7 @@ struct mpc8xxx_spi {
 	const void *tx;
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
-	int len;
+	unsigned int rx_len;
 	unsigned int tx_len;
 	u8 *local_buf;
 	spinlock_t lock;
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: fix and improve writing to TX FIFO" to the spi tree
       [not found]     ` <c246dbf2-c59e-f029-afa1-8a5c6f6dd24b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-10-28 18:53       ` Mark Brown
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:53 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: fix and improve writing to TX FIFO

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 54731265966db742dda09008bd9bbe12ae11e93e Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:25:58 +0200
Subject: [PATCH] spi: fsl-espi: fix and improve writing to TX FIFO

This change addresses two issues:
- If the TX FIFO is full the ISR polls until there's free space again.
  An ISR should never wait for something.
- Currently the number of bytes to transfer is rounded up to the next
  multiple of 4. For most transfers therefore few bytes remain in the
  TX FIFO after end of transfer.
  This would cause the next transfer to fail and as a workaround the
  ESPI block is disabled / re-enabled in fsl_espi_change_mode.
  This seems to clear the FIFO's (although it's not mentioned in the
  spec).

With this change the TX FIFO is filled as much as possible initially
and whenever the ISR is called. Also the exact number of bytes is
transferred.
The spinlock protects against a potential race if the first interrupt
occurs whilst the TX FIFO is still being initially filled.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 68 ++++++++++++++++++++++++++++------------------
 drivers/spi/spi-fsl-lib.h  |  2 ++
 2 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index f04c2464e854..95c1fbfe1cbe 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -54,6 +54,8 @@
 #define CSMODE_AFT(x)		((x) << 8)
 #define CSMODE_CG(x)		((x) << 3)
 
+#define FSL_ESPI_FIFO_SIZE	32
+
 /* Default mode/csmode for eSPI controller */
 #define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3))
 #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \
@@ -200,6 +202,27 @@ static int fsl_espi_check_message(struct spi_message *m)
 	return 0;
 }
 
+static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events)
+{
+	u32 tx_fifo_avail;
+
+	/* if events is zero transfer has not started and tx fifo is empty */
+	tx_fifo_avail = events ? SPIE_TXCNT(events) :  FSL_ESPI_FIFO_SIZE;
+
+	while (tx_fifo_avail >= min(4U, mspi->tx_len) && mspi->tx_len)
+		if (mspi->tx_len >= 4) {
+			fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
+			mspi->tx += 4;
+			mspi->tx_len -= 4;
+			tx_fifo_avail -= 4;
+		} else {
+			fsl_espi_write_reg8(mspi, ESPI_SPITF, *(u8 *)mspi->tx);
+			mspi->tx += 1;
+			mspi->tx_len -= 1;
+			tx_fifo_avail -= 1;
+		}
+}
+
 static void fsl_espi_change_mode(struct spi_device *spi)
 {
 	struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
@@ -262,7 +285,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	int ret;
 
 	mpc8xxx_spi->len = t->len;
-	mpc8xxx_spi->count = roundup(t->len, 4) / 4;
+	mpc8xxx_spi->tx_len = t->len;
 
 	mpc8xxx_spi->tx = t->tx_buf;
 	mpc8xxx_spi->rx = t->rx_buf;
@@ -276,21 +299,22 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	/* enable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE);
 
-	/* transmit word */
-	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, *(u32 *)mpc8xxx_spi->tx);
-	mpc8xxx_spi->tx += 4;
+	/* Prevent filling the fifo from getting interrupted */
+	spin_lock_irq(&mpc8xxx_spi->lock);
+	fsl_espi_fill_tx_fifo(mpc8xxx_spi, 0);
+	spin_unlock_irq(&mpc8xxx_spi->lock);
 
 	/* Won't hang up forever, SPI bus sometimes got lost interrupts... */
 	ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ);
 	if (ret == 0)
 		dev_err(mpc8xxx_spi->dev,
-			"Transaction hanging up (left %d bytes)\n",
-			mpc8xxx_spi->count);
+			"Transaction hanging up (left %u bytes)\n",
+			mpc8xxx_spi->tx_len);
 
 	/* disable rx ints */
 	fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0);
 
-	return mpc8xxx_spi->count > 0 ? -EMSGSIZE : 0;
+	return mpc8xxx_spi->tx_len > 0 ? -EMSGSIZE : 0;
 }
 
 static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
@@ -461,26 +485,11 @@ static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 		}
 	}
 
-	if (!(events & SPIE_TNF)) {
-		int ret;
-
-		/* spin until TX is done */
-		ret = spin_event_timeout(((events = fsl_espi_read_reg(
-				mspi, ESPI_SPIE)) & SPIE_TNF), 1000, 0);
-		if (!ret) {
-			dev_err(mspi->dev, "tired waiting for SPIE_TNF\n");
-			complete(&mspi->done);
-			return;
-		}
-	}
+	if (mspi->tx_len)
+		fsl_espi_fill_tx_fifo(mspi, events);
 
-	mspi->count -= 1;
-	if (mspi->count) {
-		fsl_espi_write_reg(mspi, ESPI_SPITF, *(u32 *)mspi->tx);
-		mspi->tx += 4;
-	} else {
+	if (!mspi->tx_len && !mspi->len)
 		complete(&mspi->done);
-	}
 }
 
 static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
@@ -488,10 +497,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	struct mpc8xxx_spi *mspi = context_data;
 	u32 events;
 
+	spin_lock(&mspi->lock);
+
 	/* Get interrupt events(tx/rx) */
 	events = fsl_espi_read_reg(mspi, ESPI_SPIE);
-	if (!events)
+	if (!events) {
+		spin_unlock_irq(&mspi->lock);
 		return IRQ_NONE;
+	}
 
 	dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events);
 
@@ -500,6 +513,8 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
 	/* Clear the events */
 	fsl_espi_write_reg(mspi, ESPI_SPIE, events);
 
+	spin_unlock(&mspi->lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -562,6 +577,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 	master->max_message_size = fsl_espi_max_message_size;
 
 	mpc8xxx_spi = spi_master_get_devdata(master);
+	spin_lock_init(&mpc8xxx_spi->lock);
 
 	mpc8xxx_spi->local_buf =
 		devm_kmalloc(dev, SPCOM_TRANLEN_MAX, GFP_KERNEL);
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h
index 2925c8089fd9..24d8bc84a111 100644
--- a/drivers/spi/spi-fsl-lib.h
+++ b/drivers/spi/spi-fsl-lib.h
@@ -30,7 +30,9 @@ struct mpc8xxx_spi {
 	void *rx;
 #if IS_ENABLED(CONFIG_SPI_FSL_ESPI)
 	int len;
+	unsigned int tx_len;
 	u8 *local_buf;
+	spinlock_t lock;
 #endif
 
 	int subblock;
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Applied "spi: fsl-espi: improve check for SPI_QE_CPU_MODE" to the spi tree
       [not found]     ` <0b5e7849-88d6-2af5-a428-eeb0de0f2af2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-10-28 18:34       ` Mark Brown
@ 2016-10-28 18:53       ` Mark Brown
  1 sibling, 0 replies; 30+ messages in thread
From: Mark Brown @ 2016-10-28 18:53 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Mark Brown, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA

The patch

   spi: fsl-espi: improve check for SPI_QE_CPU_MODE

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From e9e128a69af2b5fd2a4e01a59cc7e479ce9b8813 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Thu, 27 Oct 2016 21:24:01 +0200
Subject: [PATCH] spi: fsl-espi: improve check for SPI_QE_CPU_MODE

SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
based on DT property "mode". This property is not defined for ESPI,
see Documentation/devicetree/bindings/spi/fsl-spi.txt.
So print an error message and bail out if SPI_QE_CPU_MODE is set.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 4e8a99d0cb63..f04c2464e854 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -583,8 +583,9 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
 		goto err_probe;
 
 	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
-		mpc8xxx_spi->rx_shift = 16;
-		mpc8xxx_spi->tx_shift = 24;
+		dev_err(dev, "SPI_QE_CPU_MODE is not supported on ESPI!\n");
+		ret = -EINVAL;
+		goto err_probe;
 	}
 
 	/* SPI controller initializations */
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2016-10-28 18:53 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5b98be38-17a2-79a2-14da-fb2bb6f8820f@gmail.com>
     [not found] ` <5b98be38-17a2-79a2-14da-fb2bb6f8820f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-02 12:22   ` [PATCH 02/11] spi: fsl-espi: remove unneeded check for SPI_QE_CPU_MODE Heiner Kallweit
     [not found]     ` <20608368-44e6-21f8-d970-5ade9990ce59-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-06 15:45       ` Mark Brown
     [not found]         ` <20161006154543.rxlrc3sumejozpcg-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-10-06 18:36           ` Heiner Kallweit
     [not found]             ` <bbe77580-1ac2-4071-5d7d-f786c54ad177-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-26 17:07               ` Mark Brown
2016-10-02 12:22   ` [PATCH 03/11] spi: fsl-espi: fix handling of word sizes other than 8 bit Heiner Kallweit
2016-10-02 12:23   ` [PATCH 04/11] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
     [not found]     ` <c246dbf2-c59e-f029-afa1-8a5c6f6dd24b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:53       ` Applied "spi: fsl-espi: fix and improve writing to TX FIFO" to the spi tree Mark Brown
2016-10-02 12:23   ` [PATCH 05/11] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
2016-10-02 12:23   ` [PATCH 06/11] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
     [not found]     ` <0aeb49f0-dbfb-7acb-3829-cabafe4e7291-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:52       ` Applied "spi: fsl-espi: simplify and inline function fsl_espi_change_mode" to the spi tree Mark Brown
2016-10-02 12:23   ` [PATCH 07/11] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
2016-10-02 12:23   ` [PATCH 08/11] spi: fsl-espi: make better use of the " Heiner Kallweit
     [not found]     ` <144b73b1-dff2-a5b6-9df1-837238f20008-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:51       ` Applied "spi: fsl-espi: make better use of the RX FIFO" to the spi tree Mark Brown
2016-10-02 12:23   ` [PATCH 09/11] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
     [not found]     ` <4ba19a7f-9f66-54c4-9119-e85671d608fb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:52       ` Applied "spi: fsl-espi: extend and improve transfer error handling" to the spi tree Mark Brown
2016-10-02 12:23   ` [PATCH 10/11] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
2016-10-02 12:23   ` [PATCH 11/11] spi: fsl-espi: add support for dual read mode Heiner Kallweit
2016-10-27 19:24   ` [PATCH v2 01/09] spi: fsl-espi: improve check for SPI_QE_CPU_MODE Heiner Kallweit
     [not found]     ` <0b5e7849-88d6-2af5-a428-eeb0de0f2af2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:34       ` Mark Brown
2016-10-28 18:53       ` Applied "spi: fsl-espi: improve check for SPI_QE_CPU_MODE" to the spi tree Mark Brown
2016-10-27 19:25   ` [PATCH v2 02/09] spi: fsl-espi: fix and improve writing to TX FIFO Heiner Kallweit
2016-10-27 19:26   ` [PATCH v2 03/09] spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned Heiner Kallweit
     [not found]     ` <611500a3-d254-f04c-ce20-6905a649bcda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:53       ` Applied "spi: fsl-espi: Rename len in struct mpc8xxx_spi to rx_len and make it unsigned" to the spi tree Mark Brown
2016-10-27 19:26   ` [PATCH v2 04/09] spi: fsl-espi: simplify and inline function fsl_espi_change_mode Heiner Kallweit
2016-10-27 19:27   ` [PATCH v2 05/09] spi: fsl-espi: fix and improve reading from RX FIFO Heiner Kallweit
     [not found]     ` <6ae20ab9-4068-9be7-654d-12424de35716-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-28 18:51       ` Applied "spi: fsl-espi: fix and improve reading from RX FIFO" to the spi tree Mark Brown
2016-10-27 19:27   ` [PATCH v2 06/09] spi: fsl-espi: make better use of the RX FIFO Heiner Kallweit
2016-10-27 19:28   ` [PATCH v2 07/09] spi: fsl-espi: extend and improve transfer error handling Heiner Kallweit
2016-10-27 19:28   ` [PATCH v2 08/09] spi: fsl-espi: add support for RXSKIP mode Heiner Kallweit
2016-10-27 19:29   ` [PATCH v2 09/09] spi: fsl-espi: add support for dual read mode Heiner Kallweit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.