All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/14] spi: rspi: Add support for RZ/A1H, DT, and Quad/Dual on QSPI
@ 2014-01-24  8:43 ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel

	Hi Mark,

This patch series
  1. refactors the Renesas RSPI/QSPI driver,
  2. adds support for RSPI in the r7s72100 aka RZ/A1H SoC,
  3. adds support for DT binding,
  4. adds support for Quad/Dual SPI Transfers on QSPI in the r8a7790/r8a7791
     aka R-Car H2/M2 SoCs.

SoC and board integration patches will be posted in a separate series.

It was tested on the r7s72100-based Genmai reference board using loopback
mode, and on the r8a7791-based Koelsch reference board using the Spansion
s25fl512s SPI FLASH.

Quad Write Transfers were not tested, as this needs support in the m25p80
driver first. Also, it's of limited use, as FLASH programming is slow.

Overview:
    [   01/14] spi: rspi: Remove unused mesg parameter from
    			  {send,receive}_pio()
    [   02/14] spi: rspi: Use core message handling
    [   03/14] spi: rspi: Abstract 8/16-bit Data Register access
    [   04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers
    [   05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI
    [   06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
    [   07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio()
    [v3 08/14] spi: rspi: Add support for more than one interrupt
    [   09/14] spi: rspi: Add support for RSPI on RZ/A1H
    [v3 10/14] spi: rspi: Add support for loopback mode
    [v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
    [v2 12/14] spi: rspi: Use NULL as the clock ID
    [v4 13/14] spi: rspi: Add DT support
    [   14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI

The series contains new work, and remaining/rebased/updated patches from the
following series that had been posted before:
    [PATCH v2 0/8] spi: rspi: Add support for RZ/A1H
    [PATCH v3 0/9] Renesas RSPI/QSPI DT support

Patches [03/14] and [09/14] completely replace the old handling using
platform data in
    [4/8 V2] spi: rspi: Add support for 8-bit Data Register access
    [5/8 V2] spi: rspi: Add support for no TX only mode
    [6/8 V2] spi: rspi: Add support for missing SPCR2 register
by a new "rspi-rz" platform device name binding.

Please review, thanks!

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


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

* [PATCH 0/14] spi: rspi: Add support for RZ/A1H, DT, and Quad/Dual on QSPI
@ 2014-01-24  8:43 ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel

	Hi Mark,

This patch series
  1. refactors the Renesas RSPI/QSPI driver,
  2. adds support for RSPI in the r7s72100 aka RZ/A1H SoC,
  3. adds support for DT binding,
  4. adds support for Quad/Dual SPI Transfers on QSPI in the r8a7790/r8a7791
     aka R-Car H2/M2 SoCs.

SoC and board integration patches will be posted in a separate series.

It was tested on the r7s72100-based Genmai reference board using loopback
mode, and on the r8a7791-based Koelsch reference board using the Spansion
s25fl512s SPI FLASH.

Quad Write Transfers were not tested, as this needs support in the m25p80
driver first. Also, it's of limited use, as FLASH programming is slow.

Overview:
    [   01/14] spi: rspi: Remove unused mesg parameter from
    			  {send,receive}_pio()
    [   02/14] spi: rspi: Use core message handling
    [   03/14] spi: rspi: Abstract 8/16-bit Data Register access
    [   04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers
    [   05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI
    [   06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
    [   07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio()
    [v3 08/14] spi: rspi: Add support for more than one interrupt
    [   09/14] spi: rspi: Add support for RSPI on RZ/A1H
    [v3 10/14] spi: rspi: Add support for loopback mode
    [v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
    [v2 12/14] spi: rspi: Use NULL as the clock ID
    [v4 13/14] spi: rspi: Add DT support
    [   14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI

The series contains new work, and remaining/rebased/updated patches from the
following series that had been posted before:
    [PATCH v2 0/8] spi: rspi: Add support for RZ/A1H
    [PATCH v3 0/9] Renesas RSPI/QSPI DT support

Patches [03/14] and [09/14] completely replace the old handling using
platform data in
    [4/8 V2] spi: rspi: Add support for 8-bit Data Register access
    [5/8 V2] spi: rspi: Add support for no TX only mode
    [6/8 V2] spi: rspi: Add support for missing SPCR2 register
by a new "rspi-rz" platform device name binding.

Please review, thanks!

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


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

* [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio()
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 28987d9fcfe5..ccd5cf201d04 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -228,11 +228,8 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
 struct spi_ops {
 	int (*set_config_register)(const struct rspi_data *rspi,
 				   int access_size);
-	int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			struct spi_transfer *t);
-	int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			   struct spi_transfer *t);
-
+	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
+	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 };
 
 /*
@@ -358,8 +355,7 @@ static void rspi_negate_ssl(const struct rspi_data *rspi)
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
 }
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	const u8 *data = t->tx_buf;
@@ -384,8 +380,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	const u8 *data = t->tx_buf;
@@ -418,7 +413,7 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t)
+#define send_pio(spi, t) spi->ops->send_pio(spi, t)
 
 static void rspi_dma_complete(void *arg)
 {
@@ -551,8 +546,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
-static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
+static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	u8 *data;
@@ -598,8 +592,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 }
 
-static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
+static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	u8 *data;
@@ -630,7 +623,7 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t)
+#define receive_pio(spi, t) spi->ops->receive_pio(spi, t)
 
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
@@ -771,7 +764,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_send_dma(rspi, t);
 				else
-					ret = send_pio(rspi, mesg, t);
+					ret = send_pio(rspi, t);
 				if (ret < 0)
 					goto error;
 			}
@@ -779,7 +772,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_receive_dma(rspi, t);
 				else
-					ret = receive_pio(rspi, mesg, t);
+					ret = receive_pio(rspi, t);
 				if (ret < 0)
 					goto error;
 			}
-- 
1.7.9.5


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

* [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio()
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 28987d9fcfe5..ccd5cf201d04 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -228,11 +228,8 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
 struct spi_ops {
 	int (*set_config_register)(const struct rspi_data *rspi,
 				   int access_size);
-	int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			struct spi_transfer *t);
-	int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			   struct spi_transfer *t);
-
+	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
+	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 };
 
 /*
@@ -358,8 +355,7 @@ static void rspi_negate_ssl(const struct rspi_data *rspi)
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
 }
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	const u8 *data = t->tx_buf;
@@ -384,8 +380,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	const u8 *data = t->tx_buf;
@@ -418,7 +413,7 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t)
+#define send_pio(spi, t) spi->ops->send_pio(spi, t)
 
 static void rspi_dma_complete(void *arg)
 {
@@ -551,8 +546,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
-static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
+static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	u8 *data;
@@ -598,8 +592,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 }
 
-static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
+static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
 	u8 *data;
@@ -630,7 +623,7 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 }
 
-#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t)
+#define receive_pio(spi, t) spi->ops->receive_pio(spi, t)
 
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
@@ -771,7 +764,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_send_dma(rspi, t);
 				else
-					ret = send_pio(rspi, mesg, t);
+					ret = send_pio(rspi, t);
 				if (ret < 0)
 					goto error;
 			}
@@ -779,7 +772,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_receive_dma(rspi, t);
 				else
-					ret = receive_pio(rspi, mesg, t);
+					ret = receive_pio(rspi, t);
 				if (ret < 0)
 					goto error;
 			}
-- 
1.7.9.5


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

* [PATCH 02/14] spi: rspi: Use core message handling
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Let the generic SPI core handle SPI messages, calling into our
rspi_transfer_one() method.

rspi_assert_ssl() and rspi_negate_ssl() are absorbed into
rspi_prepare_message() and rspi_unprepare_message(), as they actually
enable/disable the whole SPI function, instead of just (de)asserting the
chip select line.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  111 +++++++++++++++---------------------------------
 1 file changed, 34 insertions(+), 77 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index ccd5cf201d04..0e4d169c90d7 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -25,8 +25,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -181,10 +179,7 @@ struct rspi_data {
 	void __iomem *addr;
 	u32 max_speed_hz;
 	struct spi_master *master;
-	struct list_head queue;
-	struct work_struct ws;
 	wait_queue_head_t wait;
-	spinlock_t lock;
 	struct clk *clk;
 	u8 spsr;
 	u16 spcmd;
@@ -345,16 +340,6 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	return 0;
 }
 
-static void rspi_assert_ssl(const struct rspi_data *rspi)
-{
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
-}
-
-static void rspi_negate_ssl(const struct rspi_data *rspi)
-{
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
-}
-
 static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
@@ -739,56 +724,27 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-static void rspi_work(struct work_struct *work)
+static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
 {
-	struct rspi_data *rspi = container_of(work, struct rspi_data, ws);
-	struct spi_message *mesg;
-	struct spi_transfer *t;
-	unsigned long flags;
-	int ret;
-
-	while (1) {
-		spin_lock_irqsave(&rspi->lock, flags);
-		if (list_empty(&rspi->queue)) {
-			spin_unlock_irqrestore(&rspi->lock, flags);
-			break;
-		}
-		mesg = list_entry(rspi->queue.next, struct spi_message, queue);
-		list_del_init(&mesg->queue);
-		spin_unlock_irqrestore(&rspi->lock, flags);
-
-		rspi_assert_ssl(rspi);
-
-		list_for_each_entry(t, &mesg->transfers, transfer_list) {
-			if (t->tx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_send_dma(rspi, t);
-				else
-					ret = send_pio(rspi, t);
-				if (ret < 0)
-					goto error;
-			}
-			if (t->rx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_receive_dma(rspi, t);
-				else
-					ret = receive_pio(rspi, t);
-				if (ret < 0)
-					goto error;
-			}
-			mesg->actual_length += t->len;
-		}
-		rspi_negate_ssl(rspi);
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret = 0;
 
-		mesg->status = 0;
-		mesg->complete(mesg->context);
+	if (xfer->tx_buf) {
+		if (rspi_is_dma(rspi, xfer))
+			ret = rspi_send_dma(rspi, xfer);
+		else
+			ret = send_pio(rspi, xfer);
+		if (ret < 0)
+			return ret;
 	}
-
-	return;
-
-error:
-	mesg->status = ret;
-	mesg->complete(mesg->context);
+	if (xfer->rx_buf) {
+		if (rspi_is_dma(rspi, xfer))
+			ret = rspi_receive_dma(rspi, xfer);
+		else
+			ret = receive_pio(rspi, xfer);
+	}
+	return ret;
 }
 
 static int rspi_setup(struct spi_device *spi)
@@ -808,24 +764,26 @@ static int rspi_setup(struct spi_device *spi)
 	return 0;
 }
 
-static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg)
+static void rspi_cleanup(struct spi_device *spi)
 {
-	struct rspi_data *rspi = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	mesg->actual_length = 0;
-	mesg->status = -EINPROGRESS;
+}
 
-	spin_lock_irqsave(&rspi->lock, flags);
-	list_add_tail(&mesg->queue, &rspi->queue);
-	schedule_work(&rspi->ws);
-	spin_unlock_irqrestore(&rspi->lock, flags);
+static int rspi_prepare_message(struct spi_master *master,
+				struct spi_message *message)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
 
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
 	return 0;
 }
 
-static void rspi_cleanup(struct spi_device *spi)
+static int rspi_unprepare_message(struct spi_master *master,
+				  struct spi_message *message)
 {
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+	return 0;
 }
 
 static irqreturn_t rspi_irq(int irq, void *_sr)
@@ -972,9 +930,6 @@ static int rspi_probe(struct platform_device *pdev)
 	}
 	clk_enable(rspi->clk);
 
-	INIT_LIST_HEAD(&rspi->queue);
-	spin_lock_init(&rspi->lock);
-	INIT_WORK(&rspi->ws, rspi_work);
 	init_waitqueue_head(&rspi->wait);
 
 	if (rspi_pd && rspi_pd->num_chipselect)
@@ -984,8 +939,10 @@ static int rspi_probe(struct platform_device *pdev)
 
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
-	master->transfer = rspi_transfer;
+	master->transfer_one = rspi_transfer_one;
 	master->cleanup = rspi_cleanup;
+	master->prepare_message = rspi_prepare_message;
+	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
 	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-- 
1.7.9.5


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

* [PATCH 02/14] spi: rspi: Use core message handling
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Let the generic SPI core handle SPI messages, calling into our
rspi_transfer_one() method.

rspi_assert_ssl() and rspi_negate_ssl() are absorbed into
rspi_prepare_message() and rspi_unprepare_message(), as they actually
enable/disable the whole SPI function, instead of just (de)asserting the
chip select line.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  111 +++++++++++++++---------------------------------
 1 file changed, 34 insertions(+), 77 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index ccd5cf201d04..0e4d169c90d7 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -25,8 +25,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -181,10 +179,7 @@ struct rspi_data {
 	void __iomem *addr;
 	u32 max_speed_hz;
 	struct spi_master *master;
-	struct list_head queue;
-	struct work_struct ws;
 	wait_queue_head_t wait;
-	spinlock_t lock;
 	struct clk *clk;
 	u8 spsr;
 	u16 spcmd;
@@ -345,16 +340,6 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	return 0;
 }
 
-static void rspi_assert_ssl(const struct rspi_data *rspi)
-{
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
-}
-
-static void rspi_negate_ssl(const struct rspi_data *rspi)
-{
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
-}
-
 static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len;
@@ -739,56 +724,27 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-static void rspi_work(struct work_struct *work)
+static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
 {
-	struct rspi_data *rspi = container_of(work, struct rspi_data, ws);
-	struct spi_message *mesg;
-	struct spi_transfer *t;
-	unsigned long flags;
-	int ret;
-
-	while (1) {
-		spin_lock_irqsave(&rspi->lock, flags);
-		if (list_empty(&rspi->queue)) {
-			spin_unlock_irqrestore(&rspi->lock, flags);
-			break;
-		}
-		mesg = list_entry(rspi->queue.next, struct spi_message, queue);
-		list_del_init(&mesg->queue);
-		spin_unlock_irqrestore(&rspi->lock, flags);
-
-		rspi_assert_ssl(rspi);
-
-		list_for_each_entry(t, &mesg->transfers, transfer_list) {
-			if (t->tx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_send_dma(rspi, t);
-				else
-					ret = send_pio(rspi, t);
-				if (ret < 0)
-					goto error;
-			}
-			if (t->rx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_receive_dma(rspi, t);
-				else
-					ret = receive_pio(rspi, t);
-				if (ret < 0)
-					goto error;
-			}
-			mesg->actual_length += t->len;
-		}
-		rspi_negate_ssl(rspi);
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret = 0;
 
-		mesg->status = 0;
-		mesg->complete(mesg->context);
+	if (xfer->tx_buf) {
+		if (rspi_is_dma(rspi, xfer))
+			ret = rspi_send_dma(rspi, xfer);
+		else
+			ret = send_pio(rspi, xfer);
+		if (ret < 0)
+			return ret;
 	}
-
-	return;
-
-error:
-	mesg->status = ret;
-	mesg->complete(mesg->context);
+	if (xfer->rx_buf) {
+		if (rspi_is_dma(rspi, xfer))
+			ret = rspi_receive_dma(rspi, xfer);
+		else
+			ret = receive_pio(rspi, xfer);
+	}
+	return ret;
 }
 
 static int rspi_setup(struct spi_device *spi)
@@ -808,24 +764,26 @@ static int rspi_setup(struct spi_device *spi)
 	return 0;
 }
 
-static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg)
+static void rspi_cleanup(struct spi_device *spi)
 {
-	struct rspi_data *rspi = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	mesg->actual_length = 0;
-	mesg->status = -EINPROGRESS;
+}
 
-	spin_lock_irqsave(&rspi->lock, flags);
-	list_add_tail(&mesg->queue, &rspi->queue);
-	schedule_work(&rspi->ws);
-	spin_unlock_irqrestore(&rspi->lock, flags);
+static int rspi_prepare_message(struct spi_master *master,
+				struct spi_message *message)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
 
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
 	return 0;
 }
 
-static void rspi_cleanup(struct spi_device *spi)
+static int rspi_unprepare_message(struct spi_master *master,
+				  struct spi_message *message)
 {
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+	return 0;
 }
 
 static irqreturn_t rspi_irq(int irq, void *_sr)
@@ -972,9 +930,6 @@ static int rspi_probe(struct platform_device *pdev)
 	}
 	clk_enable(rspi->clk);
 
-	INIT_LIST_HEAD(&rspi->queue);
-	spin_lock_init(&rspi->lock);
-	INIT_WORK(&rspi->ws, rspi_work);
 	init_waitqueue_head(&rspi->wait);
 
 	if (rspi_pd && rspi_pd->num_chipselect)
@@ -984,8 +939,10 @@ static int rspi_probe(struct platform_device *pdev)
 
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
-	master->transfer = rspi_transfer;
+	master->transfer_one = rspi_transfer_one;
 	master->cleanup = rspi_cleanup;
+	master->prepare_message = rspi_prepare_message;
+	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
 	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-- 
1.7.9.5


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

* [PATCH 03/14] spi: rspi: Abstract 8/16-bit Data Register access
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add rspi_{write,read}_data(), to abstract 8-bit (QSPI, and RSPI on RZ/A1H)
versus 16-bit (RSPI) Data Register access.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   56 ++++++++++++++++++++++++++++++------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 0e4d169c90d7..a0bb3c28ae91 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -192,6 +192,7 @@ struct rspi_data {
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
+	unsigned byte_access:1;
 };
 
 static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -219,10 +220,25 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
 	return ioread16(rspi->addr + offset);
 }
 
+static void rspi_write_data(const struct rspi_data *rspi, u16 data)
+{
+	if (rspi->byte_access)
+		rspi_write8(rspi, data, RSPI_SPDR);
+	else /* 16 bit */
+		rspi_write16(rspi, data, RSPI_SPDR);
+}
+
+static u16 rspi_read_data(const struct rspi_data *rspi)
+{
+	if (rspi->byte_access)
+		return rspi_read8(rspi, RSPI_SPDR);
+	else /* 16 bit */
+		return rspi_read16(rspi, RSPI_SPDR);
+}
+
 /* optional functions */
 struct spi_ops {
-	int (*set_config_register)(const struct rspi_data *rspi,
-				   int access_size);
+	int (*set_config_register)(struct rspi_data *rspi, int access_size);
 	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 };
@@ -230,8 +246,7 @@ struct spi_ops {
 /*
  * functions for RSPI
  */
-static int rspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
@@ -242,8 +257,9 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set 16-bit word access, 1 frame */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 0;
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -266,8 +282,7 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 /*
  * functions for QSPI
  */
-static int qspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	u16 spcmd;
 	int spbr;
@@ -279,8 +294,9 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 1;
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -354,7 +370,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 
-		rspi_write16(rspi, *data, RSPI_SPDR);
+		rspi_write_data(rspi, *data);
 		data++;
 		remain--;
 	}
@@ -380,14 +396,14 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 				"%s: tx empty timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		rspi_write8(rspi, *data++, RSPI_SPDR);
+		rspi_write_data(rspi, *data++);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		rspi_read8(rspi, RSPI_SPDR);
+		rspi_read_data(rspi);
 
 		remain--;
 	}
@@ -525,7 +541,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
-		rspi_read16(rspi, RSPI_SPDR);	/* dummy read */
+		rspi_read_data(rspi);	/* dummy read */
 	if (spsr & SPSR_OVRF)
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
 			    RSPI_SPSR);
@@ -549,15 +565,14 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 		/* dummy write for generate clock */
-		rspi_write16(rspi, DUMMY_DATA, RSPI_SPDR);
+		rspi_write_data(rspi, DUMMY_DATA);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		/* SPDR allows 16 or 32-bit access only */
-		*data = (u8)rspi_read16(rspi, RSPI_SPDR);
+		*data = rspi_read_data(rspi);
 
 		data++;
 		remain--;
@@ -572,7 +587,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
-		rspi_read8(rspi, RSPI_SPDR);   /* dummy read */
+		rspi_read_data(rspi);   /* dummy read */
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 }
@@ -593,15 +608,14 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 		/* dummy write for generate clock */
-		rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR);
+		rspi_write_data(rspi, DUMMY_DATA);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		/* SPDR allows 8, 16 or 32-bit access */
-		*data++ = rspi_read8(rspi, RSPI_SPDR);
+		*data++ = rspi_read_data(rspi);
 		remain--;
 	}
 
-- 
1.7.9.5


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

* [PATCH 03/14] spi: rspi: Abstract 8/16-bit Data Register access
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add rspi_{write,read}_data(), to abstract 8-bit (QSPI, and RSPI on RZ/A1H)
versus 16-bit (RSPI) Data Register access.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   56 ++++++++++++++++++++++++++++++------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 0e4d169c90d7..a0bb3c28ae91 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -192,6 +192,7 @@ struct rspi_data {
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
+	unsigned byte_access:1;
 };
 
 static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -219,10 +220,25 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
 	return ioread16(rspi->addr + offset);
 }
 
+static void rspi_write_data(const struct rspi_data *rspi, u16 data)
+{
+	if (rspi->byte_access)
+		rspi_write8(rspi, data, RSPI_SPDR);
+	else /* 16 bit */
+		rspi_write16(rspi, data, RSPI_SPDR);
+}
+
+static u16 rspi_read_data(const struct rspi_data *rspi)
+{
+	if (rspi->byte_access)
+		return rspi_read8(rspi, RSPI_SPDR);
+	else /* 16 bit */
+		return rspi_read16(rspi, RSPI_SPDR);
+}
+
 /* optional functions */
 struct spi_ops {
-	int (*set_config_register)(const struct rspi_data *rspi,
-				   int access_size);
+	int (*set_config_register)(struct rspi_data *rspi, int access_size);
 	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
 };
@@ -230,8 +246,7 @@ struct spi_ops {
 /*
  * functions for RSPI
  */
-static int rspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
@@ -242,8 +257,9 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set 16-bit word access, 1 frame */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 0;
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -266,8 +282,7 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 /*
  * functions for QSPI
  */
-static int qspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	u16 spcmd;
 	int spbr;
@@ -279,8 +294,9 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 1;
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -354,7 +370,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 
-		rspi_write16(rspi, *data, RSPI_SPDR);
+		rspi_write_data(rspi, *data);
 		data++;
 		remain--;
 	}
@@ -380,14 +396,14 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 				"%s: tx empty timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		rspi_write8(rspi, *data++, RSPI_SPDR);
+		rspi_write_data(rspi, *data++);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		rspi_read8(rspi, RSPI_SPDR);
+		rspi_read_data(rspi);
 
 		remain--;
 	}
@@ -525,7 +541,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
-		rspi_read16(rspi, RSPI_SPDR);	/* dummy read */
+		rspi_read_data(rspi);	/* dummy read */
 	if (spsr & SPSR_OVRF)
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
 			    RSPI_SPSR);
@@ -549,15 +565,14 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 		/* dummy write for generate clock */
-		rspi_write16(rspi, DUMMY_DATA, RSPI_SPDR);
+		rspi_write_data(rspi, DUMMY_DATA);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		/* SPDR allows 16 or 32-bit access only */
-		*data = (u8)rspi_read16(rspi, RSPI_SPDR);
+		*data = rspi_read_data(rspi);
 
 		data++;
 		remain--;
@@ -572,7 +587,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
-		rspi_read8(rspi, RSPI_SPDR);   /* dummy read */
+		rspi_read_data(rspi);   /* dummy read */
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 }
@@ -593,15 +608,14 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 			return -ETIMEDOUT;
 		}
 		/* dummy write for generate clock */
-		rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR);
+		rspi_write_data(rspi, DUMMY_DATA);
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
 			dev_err(&rspi->master->dev,
 				"%s: receive timeout\n", __func__);
 			return -ETIMEDOUT;
 		}
-		/* SPDR allows 8, 16 or 32-bit access */
-		*data++ = rspi_read8(rspi, RSPI_SPDR);
+		*data++ = rspi_read_data(rspi);
 		remain--;
 	}
 
-- 
1.7.9.5


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

* [PATCH 04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add helpers rspi_data_{out,in,out_in}() to write, read, or write and
read data to/from the Data Register, taking care of waiting until data
or space is available in the buffers.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  117 +++++++++++++++++++++++-------------------------
 1 file changed, 56 insertions(+), 61 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index a0bb3c28ae91..4b27513e7204 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -356,22 +356,51 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	return 0;
 }
 
+static int rspi_data_out(struct rspi_data *rspi, u8 data)
+{
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
+		dev_err(&rspi->master->dev, "transmit timeout\n");
+		return -ETIMEDOUT;
+	}
+	rspi_write_data(rspi, data);
+	return 0;
+}
+
+static int rspi_data_in(struct rspi_data *rspi)
+{
+	u8 data;
+
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+		dev_err(&rspi->master->dev, "receive timeout\n");
+		return -ETIMEDOUT;
+	}
+	data = rspi_read_data(rspi);
+	return data;
+}
+
+static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
+{
+	int ret;
+
+	ret = rspi_data_out(rspi, data);
+	if (ret < 0)
+		return ret;
+
+	return rspi_data_in(rspi);
+}
+
 static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
+	int remain = t->len, ret;
 	const u8 *data = t->tx_buf;
+
 	while (remain > 0) {
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
 			    RSPI_SPCR);
 
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-
-		rspi_write_data(rspi, *data);
-		data++;
+		ret = rspi_data_out(rspi, *data++);
+		if (ret < 0)
+			return ret;
 		remain--;
 	}
 
@@ -383,28 +412,17 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 
 static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
+	int remain = t->len, ret;
 	const u8 *data = t->tx_buf;
 
 	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 
 	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_write_data(rspi, *data++);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_read_data(rspi);
-
+		/* dummy read */
+		ret = rspi_data_out_in(rspi, *data++);
+		if (ret < 0)
+			return ret;
 		remain--;
 	}
 
@@ -549,32 +567,20 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 
 static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
-	u8 *data;
+	int remain = t->len, ret;
+	u8 *data = t->rx_buf;
 
 	rspi_receive_init(rspi);
 
-	data = t->rx_buf;
 	while (remain > 0) {
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
 			    RSPI_SPCR);
 
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* dummy write for generate clock */
-		rspi_write_data(rspi, DUMMY_DATA);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		*data = rspi_read_data(rspi);
-
-		data++;
+		/* dummy write data for generate clock */
+		ret = rspi_data_out_in(rspi, DUMMY_DATA);
+		if (ret < 0)
+			return ret;
+		*data++ = ret;
 		remain--;
 	}
 
@@ -594,28 +600,17 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 
 static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
-	u8 *data;
+	int remain = t->len, ret;
+	u8 *data = t->rx_buf;
 
 	qspi_receive_init(rspi);
 
-	data = t->rx_buf;
 	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
 		/* dummy write for generate clock */
-		rspi_write_data(rspi, DUMMY_DATA);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		*data++ = rspi_read_data(rspi);
+		ret = rspi_data_out_in(rspi, DUMMY_DATA);
+		if (ret < 0)
+			return ret;
+		*data++ = ret;
 		remain--;
 	}
 
-- 
1.7.9.5


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

* [PATCH 04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add helpers rspi_data_{out,in,out_in}() to write, read, or write and
read data to/from the Data Register, taking care of waiting until data
or space is available in the buffers.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  117 +++++++++++++++++++++++-------------------------
 1 file changed, 56 insertions(+), 61 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index a0bb3c28ae91..4b27513e7204 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -356,22 +356,51 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	return 0;
 }
 
+static int rspi_data_out(struct rspi_data *rspi, u8 data)
+{
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
+		dev_err(&rspi->master->dev, "transmit timeout\n");
+		return -ETIMEDOUT;
+	}
+	rspi_write_data(rspi, data);
+	return 0;
+}
+
+static int rspi_data_in(struct rspi_data *rspi)
+{
+	u8 data;
+
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+		dev_err(&rspi->master->dev, "receive timeout\n");
+		return -ETIMEDOUT;
+	}
+	data = rspi_read_data(rspi);
+	return data;
+}
+
+static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
+{
+	int ret;
+
+	ret = rspi_data_out(rspi, data);
+	if (ret < 0)
+		return ret;
+
+	return rspi_data_in(rspi);
+}
+
 static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
+	int remain = t->len, ret;
 	const u8 *data = t->tx_buf;
+
 	while (remain > 0) {
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
 			    RSPI_SPCR);
 
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-
-		rspi_write_data(rspi, *data);
-		data++;
+		ret = rspi_data_out(rspi, *data++);
+		if (ret < 0)
+			return ret;
 		remain--;
 	}
 
@@ -383,28 +412,17 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 
 static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
+	int remain = t->len, ret;
 	const u8 *data = t->tx_buf;
 
 	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 
 	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_write_data(rspi, *data++);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_read_data(rspi);
-
+		/* dummy read */
+		ret = rspi_data_out_in(rspi, *data++);
+		if (ret < 0)
+			return ret;
 		remain--;
 	}
 
@@ -549,32 +567,20 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 
 static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
-	u8 *data;
+	int remain = t->len, ret;
+	u8 *data = t->rx_buf;
 
 	rspi_receive_init(rspi);
 
-	data = t->rx_buf;
 	while (remain > 0) {
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
 			    RSPI_SPCR);
 
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* dummy write for generate clock */
-		rspi_write_data(rspi, DUMMY_DATA);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		*data = rspi_read_data(rspi);
-
-		data++;
+		/* dummy write data for generate clock */
+		ret = rspi_data_out_in(rspi, DUMMY_DATA);
+		if (ret < 0)
+			return ret;
+		*data++ = ret;
 		remain--;
 	}
 
@@ -594,28 +600,17 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 
 static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
-	int remain = t->len;
-	u8 *data;
+	int remain = t->len, ret;
+	u8 *data = t->rx_buf;
 
 	qspi_receive_init(rspi);
 
-	data = t->rx_buf;
 	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
 		/* dummy write for generate clock */
-		rspi_write_data(rspi, DUMMY_DATA);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		*data++ = rspi_read_data(rspi);
+		ret = rspi_data_out_in(rspi, DUMMY_DATA);
+		if (ret < 0)
+			return ret;
+		*data++ = ret;
 		remain--;
 	}
 
-- 
1.7.9.5


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

* [PATCH 05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Split off qspi_transfer_one() (which doesn't support DMA yet) from
rspi_transfer_one().
Replace the abstraction of send_pio()/receive_pio() by the abstracrion of
transfer_one().

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 4b27513e7204..d837c5029308 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -239,8 +239,8 @@ static u16 rspi_read_data(const struct rspi_data *rspi)
 /* optional functions */
 struct spi_ops {
 	int (*set_config_register)(struct rspi_data *rspi, int access_size);
-	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
-	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
+	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
+			    struct spi_transfer *xfer);
 };
 
 /*
@@ -432,8 +432,6 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-#define send_pio(spi, t) spi->ops->send_pio(spi, t)
-
 static void rspi_dma_complete(void *arg)
 {
 	struct rspi_data *rspi = arg;
@@ -617,8 +615,6 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-#define receive_pio(spi, t) spi->ops->receive_pio(spi, t)
-
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	struct scatterlist sg, sg_dummy;
@@ -743,7 +739,7 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 		if (rspi_is_dma(rspi, xfer))
 			ret = rspi_send_dma(rspi, xfer);
 		else
-			ret = send_pio(rspi, xfer);
+			ret = rspi_send_pio(rspi, xfer);
 		if (ret < 0)
 			return ret;
 	}
@@ -751,8 +747,24 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 		if (rspi_is_dma(rspi, xfer))
 			ret = rspi_receive_dma(rspi, xfer);
 		else
-			ret = receive_pio(rspi, xfer);
+			ret = rspi_receive_pio(rspi, xfer);
+	}
+	return ret;
+}
+
+static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	if (xfer->tx_buf) {
+		ret = qspi_send_pio(rspi, xfer);
+		if (ret < 0)
+			return ret;
 	}
+	if (xfer->rx_buf)
+		ret = qspi_receive_pio(rspi, xfer);
 	return ret;
 }
 
@@ -948,7 +960,7 @@ static int rspi_probe(struct platform_device *pdev)
 
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
-	master->transfer_one = rspi_transfer_one;
+	master->transfer_one = ops->transfer_one;
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
@@ -990,14 +1002,12 @@ error1:
 
 static struct spi_ops rspi_ops = {
 	.set_config_register =		rspi_set_config_register,
-	.send_pio =			rspi_send_pio,
-	.receive_pio =			rspi_receive_pio,
+	.transfer_one =			rspi_transfer_one,
 };
 
 static struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
-	.send_pio =			qspi_send_pio,
-	.receive_pio =			qspi_receive_pio,
+	.transfer_one =			qspi_transfer_one,
 };
 
 static struct platform_device_id spi_driver_ids[] = {
-- 
1.7.9.5


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

* [PATCH 05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Split off qspi_transfer_one() (which doesn't support DMA yet) from
rspi_transfer_one().
Replace the abstraction of send_pio()/receive_pio() by the abstracrion of
transfer_one().

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 4b27513e7204..d837c5029308 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -239,8 +239,8 @@ static u16 rspi_read_data(const struct rspi_data *rspi)
 /* optional functions */
 struct spi_ops {
 	int (*set_config_register)(struct rspi_data *rspi, int access_size);
-	int (*send_pio)(struct rspi_data *rspi, struct spi_transfer *t);
-	int (*receive_pio)(struct rspi_data *rspi, struct spi_transfer *t);
+	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
+			    struct spi_transfer *xfer);
 };
 
 /*
@@ -432,8 +432,6 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-#define send_pio(spi, t) spi->ops->send_pio(spi, t)
-
 static void rspi_dma_complete(void *arg)
 {
 	struct rspi_data *rspi = arg;
@@ -617,8 +615,6 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
-#define receive_pio(spi, t) spi->ops->receive_pio(spi, t)
-
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	struct scatterlist sg, sg_dummy;
@@ -743,7 +739,7 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 		if (rspi_is_dma(rspi, xfer))
 			ret = rspi_send_dma(rspi, xfer);
 		else
-			ret = send_pio(rspi, xfer);
+			ret = rspi_send_pio(rspi, xfer);
 		if (ret < 0)
 			return ret;
 	}
@@ -751,8 +747,24 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 		if (rspi_is_dma(rspi, xfer))
 			ret = rspi_receive_dma(rspi, xfer);
 		else
-			ret = receive_pio(rspi, xfer);
+			ret = rspi_receive_pio(rspi, xfer);
+	}
+	return ret;
+}
+
+static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	if (xfer->tx_buf) {
+		ret = qspi_send_pio(rspi, xfer);
+		if (ret < 0)
+			return ret;
 	}
+	if (xfer->rx_buf)
+		ret = qspi_receive_pio(rspi, xfer);
 	return ret;
 }
 
@@ -948,7 +960,7 @@ static int rspi_probe(struct platform_device *pdev)
 
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
-	master->transfer_one = rspi_transfer_one;
+	master->transfer_one = ops->transfer_one;
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
@@ -990,14 +1002,12 @@ error1:
 
 static struct spi_ops rspi_ops = {
 	.set_config_register =		rspi_set_config_register,
-	.send_pio =			rspi_send_pio,
-	.receive_pio =			rspi_receive_pio,
+	.transfer_one =			rspi_transfer_one,
 };
 
 static struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
-	.send_pio =			qspi_send_pio,
-	.receive_pio =			qspi_receive_pio,
+	.transfer_one =			qspi_transfer_one,
 };
 
 static struct platform_device_id spi_driver_ids[] = {
-- 
1.7.9.5


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

* [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

rspi_send_pio() and rspi_receive_pio() are very similar:
  - the former only sends data, using TX Only Mode,
  - the latter sends and receives full duplex data to/from the hardware,
    but uses dummy transmit data.
Merge them into rspi_transfer_out_in(), now supporting full duplex if
needed.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  101 ++++++++++++++++++++++--------------------------
 1 file changed, 46 insertions(+), 55 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d837c5029308..cc90136d02c8 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -389,27 +389,6 @@ static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
 	return rspi_data_in(rspi);
 }
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	const u8 *data = t->tx_buf;
-
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
-			    RSPI_SPCR);
-
-		ret = rspi_data_out(rspi, *data++);
-		if (ret < 0)
-			return ret;
-		remain--;
-	}
-
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
-
-	return 0;
-}
-
 static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len, ret;
@@ -563,28 +542,6 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
-static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	u8 *data = t->rx_buf;
-
-	rspi_receive_init(rspi);
-
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
-			    RSPI_SPCR);
-
-		/* dummy write data for generate clock */
-		ret = rspi_data_out_in(rspi, DUMMY_DATA);
-		if (ret < 0)
-			return ret;
-		*data++ = ret;
-		remain--;
-	}
-
-	return 0;
-}
-
 static void qspi_receive_init(const struct rspi_data *rspi)
 {
 	u8 spsr;
@@ -729,27 +686,61 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
+static int rspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 spcr, data;
+
+	rspi_receive_init(rspi);
+
+	spcr = rspi_read8(rspi, RSPI_SPCR);
+	if (rx_buf)
+		spcr &= ~SPCR_TXMD;
+	else
+		spcr |= SPCR_TXMD;
+	rspi_write8(rspi, spcr, RSPI_SPCR);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf) {
+			ret = rspi_data_in(rspi);
+			if (ret < 0)
+				return ret;
+			*rx_buf++ = ret;
+		}
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
 static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 			     struct spi_transfer *xfer)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
-	int ret = 0;
+	int ret;
+
+	if (!rspi_is_dma(rspi, xfer))
+		return rspi_transfer_out_in(rspi, xfer);
 
 	if (xfer->tx_buf) {
-		if (rspi_is_dma(rspi, xfer))
-			ret = rspi_send_dma(rspi, xfer);
-		else
-			ret = rspi_send_pio(rspi, xfer);
+		ret = rspi_send_dma(rspi, xfer);
 		if (ret < 0)
 			return ret;
 	}
-	if (xfer->rx_buf) {
-		if (rspi_is_dma(rspi, xfer))
-			ret = rspi_receive_dma(rspi, xfer);
-		else
-			ret = rspi_receive_pio(rspi, xfer);
-	}
-	return ret;
+	if (xfer->rx_buf)
+		return rspi_receive_dma(rspi, xfer);
+
+	return 0;
 }
 
 static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
-- 
1.7.9.5


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

* [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

rspi_send_pio() and rspi_receive_pio() are very similar:
  - the former only sends data, using TX Only Mode,
  - the latter sends and receives full duplex data to/from the hardware,
    but uses dummy transmit data.
Merge them into rspi_transfer_out_in(), now supporting full duplex if
needed.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  101 ++++++++++++++++++++++--------------------------
 1 file changed, 46 insertions(+), 55 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d837c5029308..cc90136d02c8 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -389,27 +389,6 @@ static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
 	return rspi_data_in(rspi);
 }
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	const u8 *data = t->tx_buf;
-
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
-			    RSPI_SPCR);
-
-		ret = rspi_data_out(rspi, *data++);
-		if (ret < 0)
-			return ret;
-		remain--;
-	}
-
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
-
-	return 0;
-}
-
 static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
 {
 	int remain = t->len, ret;
@@ -563,28 +542,6 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
-static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	u8 *data = t->rx_buf;
-
-	rspi_receive_init(rspi);
-
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
-			    RSPI_SPCR);
-
-		/* dummy write data for generate clock */
-		ret = rspi_data_out_in(rspi, DUMMY_DATA);
-		if (ret < 0)
-			return ret;
-		*data++ = ret;
-		remain--;
-	}
-
-	return 0;
-}
-
 static void qspi_receive_init(const struct rspi_data *rspi)
 {
 	u8 spsr;
@@ -729,27 +686,61 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 }
 
+static int rspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 spcr, data;
+
+	rspi_receive_init(rspi);
+
+	spcr = rspi_read8(rspi, RSPI_SPCR);
+	if (rx_buf)
+		spcr &= ~SPCR_TXMD;
+	else
+		spcr |= SPCR_TXMD;
+	rspi_write8(rspi, spcr, RSPI_SPCR);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf) {
+			ret = rspi_data_in(rspi);
+			if (ret < 0)
+				return ret;
+			*rx_buf++ = ret;
+		}
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
 static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 			     struct spi_transfer *xfer)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
-	int ret = 0;
+	int ret;
+
+	if (!rspi_is_dma(rspi, xfer))
+		return rspi_transfer_out_in(rspi, xfer);
 
 	if (xfer->tx_buf) {
-		if (rspi_is_dma(rspi, xfer))
-			ret = rspi_send_dma(rspi, xfer);
-		else
-			ret = rspi_send_pio(rspi, xfer);
+		ret = rspi_send_dma(rspi, xfer);
 		if (ret < 0)
 			return ret;
 	}
-	if (xfer->rx_buf) {
-		if (rspi_is_dma(rspi, xfer))
-			ret = rspi_receive_dma(rspi, xfer);
-		else
-			ret = rspi_receive_pio(rspi, xfer);
-	}
-	return ret;
+	if (xfer->rx_buf)
+		return rspi_receive_dma(rspi, xfer);
+
+	return 0;
 }
 
 static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
-- 
1.7.9.5


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

* [PATCH 07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio()
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

qspi_send_pio() and qspi_receive_pio() are very similar: they both send
and receive full duplex data to/from the hardware, but ignore the data
stream in the unused direction.
Merge them into qspi_transfer_out_in(), now supporting real full duplex.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   79 +++++++++++++++++-------------------------------
 1 file changed, 28 insertions(+), 51 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index cc90136d02c8..5d39cd3eba62 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -389,28 +389,6 @@ static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
 	return rspi_data_in(rspi);
 }
 
-static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	const u8 *data = t->tx_buf;
-
-	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
-
-	while (remain > 0) {
-		/* dummy read */
-		ret = rspi_data_out_in(rspi, *data++);
-		if (ret < 0)
-			return ret;
-		remain--;
-	}
-
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
-
-	return 0;
-}
-
 static void rspi_dma_complete(void *arg)
 {
 	struct rspi_data *rspi = arg;
@@ -550,26 +528,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 	if (spsr & SPSR_SPRF)
 		rspi_read_data(rspi);   /* dummy read */
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
-}
-
-static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	u8 *data = t->rx_buf;
-
-	qspi_receive_init(rspi);
-
-	while (remain > 0) {
-		/* dummy write for generate clock */
-		ret = rspi_data_out_in(rspi, DUMMY_DATA);
-		if (ret < 0)
-			return ret;
-		*data++ = ret;
-		remain--;
-	}
-
-	return 0;
+	rspi_write8(rspi, 0, QSPI_SPBFCR);
 }
 
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
@@ -743,20 +702,38 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 	return 0;
 }
 
-static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
-			     struct spi_transfer *xfer)
+static int qspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
 {
-	struct rspi_data *rspi = spi_master_get_devdata(master);
-	int ret = 0;
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
 
-	if (xfer->tx_buf) {
-		ret = qspi_send_pio(rspi, xfer);
+	qspi_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
 		if (ret < 0)
 			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
 	}
-	if (xfer->rx_buf)
-		ret = qspi_receive_pio(rspi, xfer);
-	return ret;
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	return qspi_transfer_out_in(rspi, xfer);
 }
 
 static int rspi_setup(struct spi_device *spi)
-- 
1.7.9.5


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

* [PATCH 07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio()
@ 2014-01-24  8:43   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

qspi_send_pio() and qspi_receive_pio() are very similar: they both send
and receive full duplex data to/from the hardware, but ignore the data
stream in the unused direction.
Merge them into qspi_transfer_out_in(), now supporting real full duplex.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |   79 +++++++++++++++++-------------------------------
 1 file changed, 28 insertions(+), 51 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index cc90136d02c8..5d39cd3eba62 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -389,28 +389,6 @@ static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
 	return rspi_data_in(rspi);
 }
 
-static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	const u8 *data = t->tx_buf;
-
-	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
-
-	while (remain > 0) {
-		/* dummy read */
-		ret = rspi_data_out_in(rspi, *data++);
-		if (ret < 0)
-			return ret;
-		remain--;
-	}
-
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
-
-	return 0;
-}
-
 static void rspi_dma_complete(void *arg)
 {
 	struct rspi_data *rspi = arg;
@@ -550,26 +528,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 	if (spsr & SPSR_SPRF)
 		rspi_read_data(rspi);   /* dummy read */
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
-}
-
-static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t)
-{
-	int remain = t->len, ret;
-	u8 *data = t->rx_buf;
-
-	qspi_receive_init(rspi);
-
-	while (remain > 0) {
-		/* dummy write for generate clock */
-		ret = rspi_data_out_in(rspi, DUMMY_DATA);
-		if (ret < 0)
-			return ret;
-		*data++ = ret;
-		remain--;
-	}
-
-	return 0;
+	rspi_write8(rspi, 0, QSPI_SPBFCR);
 }
 
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
@@ -743,20 +702,38 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 	return 0;
 }
 
-static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
-			     struct spi_transfer *xfer)
+static int qspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
 {
-	struct rspi_data *rspi = spi_master_get_devdata(master);
-	int ret = 0;
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
 
-	if (xfer->tx_buf) {
-		ret = qspi_send_pio(rspi, xfer);
+	qspi_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
 		if (ret < 0)
 			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
 	}
-	if (xfer->rx_buf)
-		ret = qspi_receive_pio(rspi, xfer);
-	return ret;
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	return qspi_transfer_out_in(rspi, xfer);
 }
 
 static int rspi_setup(struct spi_device *spi)
-- 
1.7.9.5


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

* [PATCH v3 08/14] spi: rspi: Add support for more than one interrupt
  2014-01-24  8:43 ` Geert Uytterhoeven
  (?)
@ 2014-01-24  8:43     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for multiple interrupts, based on the SDK reference code.
This is needed for RZ/A1H, which supports 3 interrupts.

When using multiple interrupts, they must be called "rx" (SPRI) and "tx"
(SPTI). The error interrupt (SPEI) is not used, as it matters for slave
mode only.

When using a single interrupt, it may be called "mux". If it cannot be
found, the first interrupt in the device's resources will be used.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - s/irq[]/irqs[]/
  - s/numirq/num_irqs/
  - Use unsigned int for loop counters that cannot be negative
  - Merge the platform_get_irq() and devm_request_irq() loops
  - Do not update copyright header in further untouched rspi.h
v3:
  - Do not request the unused error interrupt
  - Add suffixes ":mux", ":rx" and ":tx" to the registered interrupt names
  - Use named interrupts

 drivers/spi/spi-rspi.c |  106 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 5d39cd3eba62..d2ade5e09f58 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1,7 +1,7 @@
 /*
  * SH RSPI driver
  *
- * Copyright (C) 2012  Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013  Renesas Solutions Corp.
  *
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -183,12 +183,12 @@ struct rspi_data {
 	struct clk *clk;
 	u8 spsr;
 	u16 spcmd;
+	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 
 	/* for dmaengine */
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_rx;
-	int irq;
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
@@ -440,7 +440,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg;
 	const void *buf = NULL;
 	struct dma_async_tx_descriptor *desc;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -478,7 +478,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -497,7 +497,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -536,7 +536,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg, sg_dummy;
 	void *dummy = NULL, *rx_buf = NULL;
 	struct dma_async_tx_descriptor *desc, *desc_dummy;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -594,7 +594,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		disable_irq(rspi->rx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -617,7 +619,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		enable_irq(rspi->rx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -775,7 +779,7 @@ static int rspi_unprepare_message(struct spi_master *master,
 	return 0;
 }
 
-static irqreturn_t rspi_irq(int irq, void *_sr)
+static irqreturn_t rspi_irq_mux(int irq, void *_sr)
 {
 	struct rspi_data *rspi = _sr;
 	u8 spsr;
@@ -797,6 +801,36 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
 	return ret;
 }
 
+static irqreturn_t rspi_irq_rx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPRF) {
+		rspi_disable_irq(rspi, SPCR_SPRIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
+static irqreturn_t rspi_irq_tx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPTEF) {
+		rspi_disable_irq(rspi, SPCR_SPTIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
 static int rspi_request_dma(struct rspi_data *rspi,
 				      struct platform_device *pdev)
 {
@@ -868,12 +902,25 @@ static int rspi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int rspi_request_irq(struct device *dev, unsigned int irq,
+			    irq_handler_t handler, const char *suffix,
+			    void *dev_id)
+{
+	const char *base = dev_name(dev);
+	size_t len = strlen(base) + strlen(suffix) + 2;
+	char *name = devm_kzalloc(dev, len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	snprintf(name, len, "%s:%s", base, suffix);
+	return devm_request_irq(dev, irq, handler, 0, name, dev_id);
+}
+
 static int rspi_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct spi_master *master;
 	struct rspi_data *rspi;
-	int ret, irq;
+	int ret;
 	char clk_name[16];
 	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
 	const struct spi_ops *ops;
@@ -886,12 +933,6 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "platform_get_irq error\n");
-		return -ENODEV;
-	}
-
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master = NULL) {
 		dev_err(&pdev->dev, "spi_alloc_master error.\n");
@@ -934,14 +975,41 @@ static int rspi_probe(struct platform_device *pdev)
 	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
-	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-			       dev_name(&pdev->dev), rspi);
+	ret = platform_get_irq_byname(pdev, "rx");
+	if (ret < 0) {
+		ret = platform_get_irq_byname(pdev, "mux");
+		if (ret < 0)
+			ret = platform_get_irq(pdev, 0);
+		if (ret >= 0)
+			rspi->rx_irq = rspi->tx_irq = ret;
+	} else {
+		rspi->rx_irq = ret;
+		ret = platform_get_irq_byname(pdev, "tx");
+		if (ret >= 0)
+			rspi->tx_irq = ret;
+	}
+	if (ret < 0) {
+		dev_err(&pdev->dev, "platform_get_irq error\n");
+		goto error2;
+	}
+
+	if (rspi->rx_irq = rspi->tx_irq) {
+		/* Single multiplexed interrupt */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
+				       "mux", rspi);
+	} else {
+		/* Multi-interrupt mode, only SPRI and SPTI are used */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
+				       "rx", rspi);
+		if (!ret)
+			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
+					       rspi_irq_tx, "tx", rspi);
+	}
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq error\n");
 		goto error2;
 	}
 
-	rspi->irq = irq;
 	ret = rspi_request_dma(rspi, pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
-- 
1.7.9.5


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

* [PATCH v3 08/14] spi: rspi: Add support for more than one interrupt
@ 2014-01-24  8:43     ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for multiple interrupts, based on the SDK reference code.
This is needed for RZ/A1H, which supports 3 interrupts.

When using multiple interrupts, they must be called "rx" (SPRI) and "tx"
(SPTI). The error interrupt (SPEI) is not used, as it matters for slave
mode only.

When using a single interrupt, it may be called "mux". If it cannot be
found, the first interrupt in the device's resources will be used.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - s/irq[]/irqs[]/
  - s/numirq/num_irqs/
  - Use unsigned int for loop counters that cannot be negative
  - Merge the platform_get_irq() and devm_request_irq() loops
  - Do not update copyright header in further untouched rspi.h
v3:
  - Do not request the unused error interrupt
  - Add suffixes ":mux", ":rx" and ":tx" to the registered interrupt names
  - Use named interrupts

 drivers/spi/spi-rspi.c |  106 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 5d39cd3eba62..d2ade5e09f58 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1,7 +1,7 @@
 /*
  * SH RSPI driver
  *
- * Copyright (C) 2012  Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013  Renesas Solutions Corp.
  *
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -183,12 +183,12 @@ struct rspi_data {
 	struct clk *clk;
 	u8 spsr;
 	u16 spcmd;
+	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 
 	/* for dmaengine */
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_rx;
-	int irq;
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
@@ -440,7 +440,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg;
 	const void *buf = NULL;
 	struct dma_async_tx_descriptor *desc;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -478,7 +478,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -497,7 +497,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -536,7 +536,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg, sg_dummy;
 	void *dummy = NULL, *rx_buf = NULL;
 	struct dma_async_tx_descriptor *desc, *desc_dummy;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -594,7 +594,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		disable_irq(rspi->rx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -617,7 +619,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		enable_irq(rspi->rx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -775,7 +779,7 @@ static int rspi_unprepare_message(struct spi_master *master,
 	return 0;
 }
 
-static irqreturn_t rspi_irq(int irq, void *_sr)
+static irqreturn_t rspi_irq_mux(int irq, void *_sr)
 {
 	struct rspi_data *rspi = _sr;
 	u8 spsr;
@@ -797,6 +801,36 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
 	return ret;
 }
 
+static irqreturn_t rspi_irq_rx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPRF) {
+		rspi_disable_irq(rspi, SPCR_SPRIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
+static irqreturn_t rspi_irq_tx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPTEF) {
+		rspi_disable_irq(rspi, SPCR_SPTIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
 static int rspi_request_dma(struct rspi_data *rspi,
 				      struct platform_device *pdev)
 {
@@ -868,12 +902,25 @@ static int rspi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int rspi_request_irq(struct device *dev, unsigned int irq,
+			    irq_handler_t handler, const char *suffix,
+			    void *dev_id)
+{
+	const char *base = dev_name(dev);
+	size_t len = strlen(base) + strlen(suffix) + 2;
+	char *name = devm_kzalloc(dev, len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	snprintf(name, len, "%s:%s", base, suffix);
+	return devm_request_irq(dev, irq, handler, 0, name, dev_id);
+}
+
 static int rspi_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct spi_master *master;
 	struct rspi_data *rspi;
-	int ret, irq;
+	int ret;
 	char clk_name[16];
 	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
 	const struct spi_ops *ops;
@@ -886,12 +933,6 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "platform_get_irq error\n");
-		return -ENODEV;
-	}
-
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master == NULL) {
 		dev_err(&pdev->dev, "spi_alloc_master error.\n");
@@ -934,14 +975,41 @@ static int rspi_probe(struct platform_device *pdev)
 	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
-	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-			       dev_name(&pdev->dev), rspi);
+	ret = platform_get_irq_byname(pdev, "rx");
+	if (ret < 0) {
+		ret = platform_get_irq_byname(pdev, "mux");
+		if (ret < 0)
+			ret = platform_get_irq(pdev, 0);
+		if (ret >= 0)
+			rspi->rx_irq = rspi->tx_irq = ret;
+	} else {
+		rspi->rx_irq = ret;
+		ret = platform_get_irq_byname(pdev, "tx");
+		if (ret >= 0)
+			rspi->tx_irq = ret;
+	}
+	if (ret < 0) {
+		dev_err(&pdev->dev, "platform_get_irq error\n");
+		goto error2;
+	}
+
+	if (rspi->rx_irq == rspi->tx_irq) {
+		/* Single multiplexed interrupt */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
+				       "mux", rspi);
+	} else {
+		/* Multi-interrupt mode, only SPRI and SPTI are used */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
+				       "rx", rspi);
+		if (!ret)
+			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
+					       rspi_irq_tx, "tx", rspi);
+	}
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq error\n");
 		goto error2;
 	}
 
-	rspi->irq = irq;
 	ret = rspi_request_dma(rspi, pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
-- 
1.7.9.5


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

* [PATCH v3 08/14] spi: rspi: Add support for more than one interrupt
@ 2014-01-24  8:43     ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>

Add support for multiple interrupts, based on the SDK reference code.
This is needed for RZ/A1H, which supports 3 interrupts.

When using multiple interrupts, they must be called "rx" (SPRI) and "tx"
(SPTI). The error interrupt (SPEI) is not used, as it matters for slave
mode only.

When using a single interrupt, it may be called "mux". If it cannot be
found, the first interrupt in the device's resources will be used.

Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
v2:
  - s/irq[]/irqs[]/
  - s/numirq/num_irqs/
  - Use unsigned int for loop counters that cannot be negative
  - Merge the platform_get_irq() and devm_request_irq() loops
  - Do not update copyright header in further untouched rspi.h
v3:
  - Do not request the unused error interrupt
  - Add suffixes ":mux", ":rx" and ":tx" to the registered interrupt names
  - Use named interrupts

 drivers/spi/spi-rspi.c |  106 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 5d39cd3eba62..d2ade5e09f58 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1,7 +1,7 @@
 /*
  * SH RSPI driver
  *
- * Copyright (C) 2012  Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013  Renesas Solutions Corp.
  *
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -183,12 +183,12 @@ struct rspi_data {
 	struct clk *clk;
 	u8 spsr;
 	u16 spcmd;
+	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 
 	/* for dmaengine */
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_rx;
-	int irq;
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
@@ -440,7 +440,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg;
 	const void *buf = NULL;
 	struct dma_async_tx_descriptor *desc;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -478,7 +478,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -497,7 +497,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -536,7 +536,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg, sg_dummy;
 	void *dummy = NULL, *rx_buf = NULL;
 	struct dma_async_tx_descriptor *desc, *desc_dummy;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 
 	if (rspi->dma_width_16bit) {
@@ -594,7 +594,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		disable_irq(rspi->rx_irq);
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -617,7 +619,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		enable_irq(rspi->rx_irq);
 
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -775,7 +779,7 @@ static int rspi_unprepare_message(struct spi_master *master,
 	return 0;
 }
 
-static irqreturn_t rspi_irq(int irq, void *_sr)
+static irqreturn_t rspi_irq_mux(int irq, void *_sr)
 {
 	struct rspi_data *rspi = _sr;
 	u8 spsr;
@@ -797,6 +801,36 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
 	return ret;
 }
 
+static irqreturn_t rspi_irq_rx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPRF) {
+		rspi_disable_irq(rspi, SPCR_SPRIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
+static irqreturn_t rspi_irq_tx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPTEF) {
+		rspi_disable_irq(rspi, SPCR_SPTIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
 static int rspi_request_dma(struct rspi_data *rspi,
 				      struct platform_device *pdev)
 {
@@ -868,12 +902,25 @@ static int rspi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int rspi_request_irq(struct device *dev, unsigned int irq,
+			    irq_handler_t handler, const char *suffix,
+			    void *dev_id)
+{
+	const char *base = dev_name(dev);
+	size_t len = strlen(base) + strlen(suffix) + 2;
+	char *name = devm_kzalloc(dev, len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	snprintf(name, len, "%s:%s", base, suffix);
+	return devm_request_irq(dev, irq, handler, 0, name, dev_id);
+}
+
 static int rspi_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct spi_master *master;
 	struct rspi_data *rspi;
-	int ret, irq;
+	int ret;
 	char clk_name[16];
 	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
 	const struct spi_ops *ops;
@@ -886,12 +933,6 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "platform_get_irq error\n");
-		return -ENODEV;
-	}
-
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master == NULL) {
 		dev_err(&pdev->dev, "spi_alloc_master error.\n");
@@ -934,14 +975,41 @@ static int rspi_probe(struct platform_device *pdev)
 	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
-	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-			       dev_name(&pdev->dev), rspi);
+	ret = platform_get_irq_byname(pdev, "rx");
+	if (ret < 0) {
+		ret = platform_get_irq_byname(pdev, "mux");
+		if (ret < 0)
+			ret = platform_get_irq(pdev, 0);
+		if (ret >= 0)
+			rspi->rx_irq = rspi->tx_irq = ret;
+	} else {
+		rspi->rx_irq = ret;
+		ret = platform_get_irq_byname(pdev, "tx");
+		if (ret >= 0)
+			rspi->tx_irq = ret;
+	}
+	if (ret < 0) {
+		dev_err(&pdev->dev, "platform_get_irq error\n");
+		goto error2;
+	}
+
+	if (rspi->rx_irq == rspi->tx_irq) {
+		/* Single multiplexed interrupt */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
+				       "mux", rspi);
+	} else {
+		/* Multi-interrupt mode, only SPRI and SPTI are used */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
+				       "rx", rspi);
+		if (!ret)
+			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
+					       rspi_irq_tx, "tx", rspi);
+	}
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq error\n");
 		goto error2;
 	}
 
-	rspi->irq = irq;
 	ret = rspi_request_dma(rspi, pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
-- 
1.7.9.5

--
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] 57+ messages in thread

* [PATCH 09/14] spi: rspi: Add support for RSPI on RZ/A1H
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:43 ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: linux-sh

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for the RSPI variant in the RZ/A1H (r7s72100) SoC.

Main differences with RSPI on SH are:
  - Lack of TX only mode, hence we always have to use full duplex
    transfers,
  - The Data Register must be accessed used 8-bit operations.

RSPI on RZ is matched using the new "rspi-rz" platform device name.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  101 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d2ade5e09f58..0c7556978d2e 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -47,7 +47,7 @@
 #define RSPI_SPCKD		0x0c	/* Clock Delay Register */
 #define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */
 #define RSPI_SPND		0x0e	/* Next-Access Delay Register */
-#define RSPI_SPCR2		0x0f	/* Control Register 2 */
+#define RSPI_SPCR2		0x0f	/* Control Register 2 (SH only) */
 #define RSPI_SPCMD0		0x10	/* Command Register 0 */
 #define RSPI_SPCMD1		0x12	/* Command Register 1 */
 #define RSPI_SPCMD2		0x14	/* Command Register 2 */
@@ -56,10 +56,12 @@
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
+
+/* RSPI on RZ only */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
 #define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */
 
-/*qspi only */
+/* QSPI only */
 #define QSPI_SPBFCR		0x18	/* Buffer Control Register */
 #define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */
 #define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */
@@ -102,7 +104,7 @@
 #define SPSR_PERF		0x08	/* Parity Error Flag */
 #define SPSR_MODF		0x04	/* Mode Fault Error Flag */
 #define SPSR_IDLNF		0x02	/* RSPI Idle Flag */
-#define SPSR_OVRF		0x01	/* Overrun Error Flag */
+#define SPSR_OVRF		0x01	/* Overrun Error Flag (RSPI only) */
 
 /* SPSCR - Sequence Control Register */
 #define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */
@@ -119,13 +121,13 @@
 #define SPDCR_SPLWORD		SPDCR_SPLW1
 #define SPDCR_SPLBYTE		SPDCR_SPLW0
 #define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */
-#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select */
+#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select (SH) */
 #define SPDCR_SLSEL1		0x08
 #define SPDCR_SLSEL0		0x04
-#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select */
+#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select (SH) */
 #define SPDCR_SPFC1		0x02
 #define SPDCR_SPFC0		0x01
-#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) */
+#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) (SH) */
 
 /* SPCKD - Clock Delay Register */
 #define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */
@@ -168,8 +170,8 @@
 #define SPCMD_CPHA		0x0001	/* Clock Phase Setting */
 
 /* SPBFCR - Buffer Control Register */
-#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset (qspi only) */
-#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset (qspi only) */
+#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset */
+#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */
 #define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
 #define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
 
@@ -244,7 +246,7 @@ struct spi_ops {
 };
 
 /*
- * functions for RSPI
+ * functions for RSPI on legacy SH
  */
 static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
@@ -280,6 +282,39 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 }
 
 /*
+ * functions for RSPI on RZ
+ */
+static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
+{
+	int spbr;
+
+	/* Sets output mode */
+	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+
+	/* Sets transfer bit rate */
+	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
+	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
+
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR);
+	rspi->byte_access = 1;
+
+	/* Sets RSPCK, SSL, next-access delay value */
+	rspi_write8(rspi, 0x00, RSPI_SPCKD);
+	rspi_write8(rspi, 0x00, RSPI_SSLND);
+	rspi_write8(rspi, 0x00, RSPI_SPND);
+
+	/* Sets SPCMD */
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+
+	/* Sets RSPI mode */
+	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+
+	return 0;
+}
+
+/*
  * functions for QSPI
  */
 static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
@@ -520,6 +555,13 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
+static void rspi_rz_receive_init(const struct rspi_data *rspi)
+{
+	rspi_receive_init(rspi);
+	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR);
+	rspi_write8(rspi, 0, RSPI_SPBFCR);
+}
+
 static void qspi_receive_init(const struct rspi_data *rspi)
 {
 	u8 spsr;
@@ -706,6 +748,41 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 	return 0;
 }
 
+static int rspi_rz_transfer_out_in(struct rspi_data *rspi,
+				   struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
+
+	rspi_rz_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int rspi_rz_transfer_one(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	return rspi_rz_transfer_out_in(rspi, xfer);
+}
+
 static int qspi_transfer_out_in(struct rspi_data *rspi,
 				struct spi_transfer *xfer)
 {
@@ -1041,6 +1118,11 @@ static struct spi_ops rspi_ops = {
 	.transfer_one =			rspi_transfer_one,
 };
 
+static struct spi_ops rspi_rz_ops = {
+	.set_config_register =		rspi_rz_set_config_register,
+	.transfer_one =			rspi_rz_transfer_one,
+};
+
 static struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
 	.transfer_one =			qspi_transfer_one,
@@ -1048,6 +1130,7 @@ static struct spi_ops qspi_ops = {
 
 static struct platform_device_id spi_driver_ids[] = {
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
+	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops },
 	{ "qspi",	(kernel_ulong_t)&qspi_ops },
 	{},
 };
-- 
1.7.9.5


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

* [PATCH 09/14] spi: rspi: Add support for RSPI on RZ/A1H
@ 2014-01-24  8:43 ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for the RSPI variant in the RZ/A1H (r7s72100) SoC.

Main differences with RSPI on SH are:
  - Lack of TX only mode, hence we always have to use full duplex
    transfers,
  - The Data Register must be accessed used 8-bit operations.

RSPI on RZ is matched using the new "rspi-rz" platform device name.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  101 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d2ade5e09f58..0c7556978d2e 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -47,7 +47,7 @@
 #define RSPI_SPCKD		0x0c	/* Clock Delay Register */
 #define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */
 #define RSPI_SPND		0x0e	/* Next-Access Delay Register */
-#define RSPI_SPCR2		0x0f	/* Control Register 2 */
+#define RSPI_SPCR2		0x0f	/* Control Register 2 (SH only) */
 #define RSPI_SPCMD0		0x10	/* Command Register 0 */
 #define RSPI_SPCMD1		0x12	/* Command Register 1 */
 #define RSPI_SPCMD2		0x14	/* Command Register 2 */
@@ -56,10 +56,12 @@
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
+
+/* RSPI on RZ only */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
 #define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */
 
-/*qspi only */
+/* QSPI only */
 #define QSPI_SPBFCR		0x18	/* Buffer Control Register */
 #define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */
 #define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */
@@ -102,7 +104,7 @@
 #define SPSR_PERF		0x08	/* Parity Error Flag */
 #define SPSR_MODF		0x04	/* Mode Fault Error Flag */
 #define SPSR_IDLNF		0x02	/* RSPI Idle Flag */
-#define SPSR_OVRF		0x01	/* Overrun Error Flag */
+#define SPSR_OVRF		0x01	/* Overrun Error Flag (RSPI only) */
 
 /* SPSCR - Sequence Control Register */
 #define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */
@@ -119,13 +121,13 @@
 #define SPDCR_SPLWORD		SPDCR_SPLW1
 #define SPDCR_SPLBYTE		SPDCR_SPLW0
 #define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */
-#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select */
+#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select (SH) */
 #define SPDCR_SLSEL1		0x08
 #define SPDCR_SLSEL0		0x04
-#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select */
+#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select (SH) */
 #define SPDCR_SPFC1		0x02
 #define SPDCR_SPFC0		0x01
-#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) */
+#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) (SH) */
 
 /* SPCKD - Clock Delay Register */
 #define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */
@@ -168,8 +170,8 @@
 #define SPCMD_CPHA		0x0001	/* Clock Phase Setting */
 
 /* SPBFCR - Buffer Control Register */
-#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset (qspi only) */
-#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset (qspi only) */
+#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset */
+#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */
 #define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
 #define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
 
@@ -244,7 +246,7 @@ struct spi_ops {
 };
 
 /*
- * functions for RSPI
+ * functions for RSPI on legacy SH
  */
 static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
@@ -280,6 +282,39 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 }
 
 /*
+ * functions for RSPI on RZ
+ */
+static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
+{
+	int spbr;
+
+	/* Sets output mode */
+	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+
+	/* Sets transfer bit rate */
+	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
+	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
+
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR);
+	rspi->byte_access = 1;
+
+	/* Sets RSPCK, SSL, next-access delay value */
+	rspi_write8(rspi, 0x00, RSPI_SPCKD);
+	rspi_write8(rspi, 0x00, RSPI_SSLND);
+	rspi_write8(rspi, 0x00, RSPI_SPND);
+
+	/* Sets SPCMD */
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+
+	/* Sets RSPI mode */
+	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+
+	return 0;
+}
+
+/*
  * functions for QSPI
  */
 static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
@@ -520,6 +555,13 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 			    RSPI_SPSR);
 }
 
+static void rspi_rz_receive_init(const struct rspi_data *rspi)
+{
+	rspi_receive_init(rspi);
+	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR);
+	rspi_write8(rspi, 0, RSPI_SPBFCR);
+}
+
 static void qspi_receive_init(const struct rspi_data *rspi)
 {
 	u8 spsr;
@@ -706,6 +748,41 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 	return 0;
 }
 
+static int rspi_rz_transfer_out_in(struct rspi_data *rspi,
+				   struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
+
+	rspi_rz_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int rspi_rz_transfer_one(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	return rspi_rz_transfer_out_in(rspi, xfer);
+}
+
 static int qspi_transfer_out_in(struct rspi_data *rspi,
 				struct spi_transfer *xfer)
 {
@@ -1041,6 +1118,11 @@ static struct spi_ops rspi_ops = {
 	.transfer_one =			rspi_transfer_one,
 };
 
+static struct spi_ops rspi_rz_ops = {
+	.set_config_register =		rspi_rz_set_config_register,
+	.transfer_one =			rspi_rz_transfer_one,
+};
+
 static struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
 	.transfer_one =			qspi_transfer_one,
@@ -1048,6 +1130,7 @@ static struct spi_ops qspi_ops = {
 
 static struct platform_device_id spi_driver_ids[] = {
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
+	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops },
 	{ "qspi",	(kernel_ulong_t)&qspi_ops },
 	{},
 };
-- 
1.7.9.5


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

* [PATCH v3 10/14] spi: rspi: Add support for loopback mode
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for specifying loopback mode.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v3:
  - This became a lot simpler after merging the send_pio() and
    receive_pio() methods

 drivers/spi/spi-rspi.c |   22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 0c7556978d2e..28db8770aaf3 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -183,8 +183,9 @@ struct rspi_data {
 	struct spi_master *master;
 	wait_queue_head_t wait;
 	struct clk *clk;
-	u8 spsr;
 	u16 spcmd;
+	u8 spsr;
+	u8 sppcr;
 	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 
@@ -252,8 +253,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
@@ -288,8 +289,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
-	/* Sets output mode */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
@@ -322,8 +323,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 	u16 spcmd;
 	int spbr;
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
@@ -829,6 +830,11 @@ static int rspi_setup(struct spi_device *spi)
 	if (spi->mode & SPI_CPHA)
 		rspi->spcmd |= SPCMD_CPHA;
 
+	/* CMOS output mode and MOSI signal from previous transfer */
+	rspi->sppcr = 0;
+	if (spi->mode & SPI_LOOP)
+		rspi->sppcr |= SPPCR_SPLP;
+
 	set_config_register(rspi, 8);
 
 	return 0;
@@ -1050,7 +1056,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
-	master->mode_bits = SPI_CPHA | SPI_CPOL;
+	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
 
 	ret = platform_get_irq_byname(pdev, "rx");
 	if (ret < 0) {
-- 
1.7.9.5


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

* [PATCH v3 10/14] spi: rspi: Add support for loopback mode
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for specifying loopback mode.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v3:
  - This became a lot simpler after merging the send_pio() and
    receive_pio() methods

 drivers/spi/spi-rspi.c |   22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 0c7556978d2e..28db8770aaf3 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -183,8 +183,9 @@ struct rspi_data {
 	struct spi_master *master;
 	wait_queue_head_t wait;
 	struct clk *clk;
-	u8 spsr;
 	u16 spcmd;
+	u8 spsr;
+	u8 sppcr;
 	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 
@@ -252,8 +253,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
@@ -288,8 +289,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
 {
 	int spbr;
 
-	/* Sets output mode */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
@@ -322,8 +323,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 	u16 spcmd;
 	int spbr;
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
@@ -829,6 +830,11 @@ static int rspi_setup(struct spi_device *spi)
 	if (spi->mode & SPI_CPHA)
 		rspi->spcmd |= SPCMD_CPHA;
 
+	/* CMOS output mode and MOSI signal from previous transfer */
+	rspi->sppcr = 0;
+	if (spi->mode & SPI_LOOP)
+		rspi->sppcr |= SPPCR_SPLP;
+
 	set_config_register(rspi, 8);
 
 	return 0;
@@ -1050,7 +1056,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
-	master->mode_bits = SPI_CPHA | SPI_CPOL;
+	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
 
 	ret = platform_get_irq_byname(pdev, "rx");
 	if (ret < 0) {
-- 
1.7.9.5


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

* [PATCH v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
  2014-01-24  8:43 ` Geert Uytterhoeven
  (?)
@ 2014-01-24  8:44     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Get the driver ready for the migration to the common clock framework by
calling clk_prepare_enable() and clk_disable_unprepare().

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - No changes

 drivers/spi/spi-rspi.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 28db8770aaf3..a648b40c271b 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -980,7 +980,7 @@ static int rspi_remove(struct platform_device *pdev)
 	struct rspi_data *rspi = platform_get_drvdata(pdev);
 
 	rspi_release_dma(rspi);
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 
 	return 0;
 }
@@ -1041,7 +1041,12 @@ static int rspi_probe(struct platform_device *pdev)
 		ret = PTR_ERR(rspi->clk);
 		goto error1;
 	}
-	clk_enable(rspi->clk);
+
+	ret = clk_prepare_enable(rspi->clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to prepare/enable clock\n");
+		goto error1;
+	}
 
 	init_waitqueue_head(&rspi->wait);
 
@@ -1112,7 +1117,7 @@ static int rspi_probe(struct platform_device *pdev)
 error3:
 	rspi_release_dma(rspi);
 error2:
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 error1:
 	spi_master_put(master);
 
-- 
1.7.9.5


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

* [PATCH v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
@ 2014-01-24  8:44     ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Get the driver ready for the migration to the common clock framework by
calling clk_prepare_enable() and clk_disable_unprepare().

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - No changes

 drivers/spi/spi-rspi.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 28db8770aaf3..a648b40c271b 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -980,7 +980,7 @@ static int rspi_remove(struct platform_device *pdev)
 	struct rspi_data *rspi = platform_get_drvdata(pdev);
 
 	rspi_release_dma(rspi);
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 
 	return 0;
 }
@@ -1041,7 +1041,12 @@ static int rspi_probe(struct platform_device *pdev)
 		ret = PTR_ERR(rspi->clk);
 		goto error1;
 	}
-	clk_enable(rspi->clk);
+
+	ret = clk_prepare_enable(rspi->clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to prepare/enable clock\n");
+		goto error1;
+	}
 
 	init_waitqueue_head(&rspi->wait);
 
@@ -1112,7 +1117,7 @@ static int rspi_probe(struct platform_device *pdev)
 error3:
 	rspi_release_dma(rspi);
 error2:
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 error1:
 	spi_master_put(master);
 
-- 
1.7.9.5


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

* [PATCH v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
@ 2014-01-24  8:44     ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>

Get the driver ready for the migration to the common clock framework by
calling clk_prepare_enable() and clk_disable_unprepare().

Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
v2:
  - No changes

 drivers/spi/spi-rspi.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 28db8770aaf3..a648b40c271b 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -980,7 +980,7 @@ static int rspi_remove(struct platform_device *pdev)
 	struct rspi_data *rspi = platform_get_drvdata(pdev);
 
 	rspi_release_dma(rspi);
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 
 	return 0;
 }
@@ -1041,7 +1041,12 @@ static int rspi_probe(struct platform_device *pdev)
 		ret = PTR_ERR(rspi->clk);
 		goto error1;
 	}
-	clk_enable(rspi->clk);
+
+	ret = clk_prepare_enable(rspi->clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to prepare/enable clock\n");
+		goto error1;
+	}
 
 	init_waitqueue_head(&rspi->wait);
 
@@ -1112,7 +1117,7 @@ static int rspi_probe(struct platform_device *pdev)
 error3:
 	rspi_release_dma(rspi);
 error2:
-	clk_disable(rspi->clk);
+	clk_disable_unprepare(rspi->clk);
 error1:
 	spi_master_put(master);
 
-- 
1.7.9.5

--
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] 57+ messages in thread

* [PATCH v2 12/14] spi: rspi: Use NULL as the clock ID
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

There's only one RSPI/QSPI clock, so we can use NULL as the clock ID

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - No changes

 drivers/spi/spi-rspi.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index a648b40c271b..d79a7ed9b92e 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1004,7 +1004,6 @@ static int rspi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct rspi_data *rspi;
 	int ret;
-	char clk_name[16];
 	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
 	const struct spi_ops *ops;
 	const struct platform_device_id *id_entry = pdev->id_entry;
@@ -1034,8 +1033,7 @@ static int rspi_probe(struct platform_device *pdev)
 		goto error1;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
-	rspi->clk = devm_clk_get(&pdev->dev, clk_name);
+	rspi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(rspi->clk)) {
 		dev_err(&pdev->dev, "cannot get clock\n");
 		ret = PTR_ERR(rspi->clk);
-- 
1.7.9.5


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

* [PATCH v2 12/14] spi: rspi: Use NULL as the clock ID
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

There's only one RSPI/QSPI clock, so we can use NULL as the clock ID

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
v2:
  - No changes

 drivers/spi/spi-rspi.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index a648b40c271b..d79a7ed9b92e 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1004,7 +1004,6 @@ static int rspi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct rspi_data *rspi;
 	int ret;
-	char clk_name[16];
 	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
 	const struct spi_ops *ops;
 	const struct platform_device_id *id_entry = pdev->id_entry;
@@ -1034,8 +1033,7 @@ static int rspi_probe(struct platform_device *pdev)
 		goto error1;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
-	rspi->clk = devm_clk_get(&pdev->dev, clk_name);
+	rspi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(rspi->clk)) {
 		dev_err(&pdev->dev, "cannot get clock\n");
 		ret = PTR_ERR(rspi->clk);
-- 
1.7.9.5


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

* [PATCH v4 13/14] spi: rspi: Add DT support
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven, devicetree

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Cc: devicetree@vger.kernel.org
---
v2:
  - Clarify RSPI/QSPI
  - Add interrupt-parent
  - s/should/must/ for #address-cells and #size-cells
v3:
  - Add renesas,rspi-sh
  - Drop -rcar suffix for QSPI
  - Clarify num-cs
  - Implement DT support in driver
  - Changed one-line summary from "Documentation: dt: Add Renesas RSPI/QSPI
    bindings" to "spi: rspi: Add DT support"
v4:
  - Clarify SoCtype and interrupts
  - Add clock property
  - Add QSPI example
  - Add interrupt-names
  - Add link to Renesas pinctrl
  - Rename "renesas,rspi-sh" to "renesas,rspi", to match platform device
    naming
  - spi-rspi.c:
      - Remove Soc-specific matching from spi-rspi.c given the fallback is
	mandatory
      - Things became a lot simpler due to the replacement of platform_data
        fields by the "rspi-rz" platform device binding.
---
 Documentation/devicetree/bindings/spi/spi-rspi.txt |   58 +++++++++++
 drivers/spi/spi-rspi.c                             |  106 ++++++++++++++------
 2 files changed, 135 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-rspi.txt

diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt
new file mode 100644
index 000000000000..ed84299a9c61
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-rspi.txt
@@ -0,0 +1,58 @@
+Device tree configuration for Renesas RSPI/QSPI driver
+
+Required properties:
+- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
+		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
+		     For Renesas Serial Peripheral Interface on RZ/A1H:
+		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
+		     For Quad Serial Peripheral Interface on R-Car Gen2:
+		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
+		     Examples of valid soctypes are "sh7757" (SH),
+		     "r7s72100" (RZ/A1H), "r8a7790" (R-Car H2), and
+		     "r8a7791" (R-Car M2).
+- reg              : Address start and address range size of the device
+- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
+		     interrupt,
+		     3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
+		     separate interrupts.
+- interrupt-names  : Array of strings associated with the interrupt numbers:
+		     "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
+		     For RSPI cores using a single multiplexed interrupt, the
+		     name "mux" is optional.
+- interrupt-parent : The phandle for the interrupt controller that
+		     services interrupts for this device.
+- num-cs	   : Number of chip selects. Some RSPI cores have more than 1.
+- #address-cells   : Must be <1>
+- #size-cells      : Must be <0>
+
+Optional properties:
+- clocks:           : Must contain a reference to the functional clock.
+
+Pinctrl properties might be needed, too.  See
+Documentation/devicetree/bindings/pinctrl/renesas,*.
+
+Examples:
+
+	spi0: spi@e800c800 {
+		compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+		reg = <0xe800c800 0x24>;
+		interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 239 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "error", "rx", "tx";
+		interrupt-parent = <&gic>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	spi: spi@e6b10000 {
+		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+		reg = <0 0xe6b10000 0 0x2c>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d79a7ed9b92e..e56fcb5f7f99 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
 #include <linux/sh_dma.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/rspi.h>
@@ -985,6 +986,56 @@ static int rspi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct spi_ops rspi_ops = {
+	.set_config_register =		rspi_set_config_register,
+	.transfer_one =			rspi_transfer_one,
+};
+
+static const struct spi_ops rspi_rz_ops = {
+	.set_config_register =		rspi_rz_set_config_register,
+	.transfer_one =			rspi_rz_transfer_one,
+};
+
+static const struct spi_ops qspi_ops = {
+	.set_config_register =		qspi_set_config_register,
+	.transfer_one =			qspi_transfer_one,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id rspi_of_match[] = {
+	/* RSPI on legacy SH */
+	{ .compatible = "renesas,rspi", .data = &rspi_ops },
+	/* RSPI on RZ/A1H */
+	{ .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops },
+	/* QSPI on R-Car Gen2 */
+	{ .compatible = "renesas,qspi", .data = &qspi_ops },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, rspi_of_match);
+
+static int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	u32 num_cs;
+	int error;
+
+	/* Parse DT properties */
+	error = of_property_read_u32(dev->of_node, "num-cs", &num_cs);
+	if (error) {
+		dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error);
+		return error;
+	}
+
+	master->num_chipselect = num_cs;
+	return 0;
+}
+#else
+static inline int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_OF */
+
 static int rspi_request_irq(struct device *dev, unsigned int irq,
 			    irq_handler_t handler, const char *suffix,
 			    void *dev_id)
@@ -1004,16 +1055,9 @@ static int rspi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct rspi_data *rspi;
 	int ret;
-	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
+	const struct of_device_id *of_id;
+	const struct rspi_plat_data *rspi_pd;
 	const struct spi_ops *ops;
-	const struct platform_device_id *id_entry = pdev->id_entry;
-
-	ops = (struct spi_ops *)id_entry->driver_data;
-	/* ops parameter check */
-	if (!ops->set_config_register) {
-		dev_err(&pdev->dev, "there is no set_config_register\n");
-		return -ENODEV;
-	}
 
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master = NULL) {
@@ -1021,6 +1065,28 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	of_id = of_match_device(rspi_of_match, &pdev->dev);
+	if (of_id) {
+		ops = of_id->data;
+		ret = rspi_parse_dt(&pdev->dev, master);
+		if (ret)
+			goto error1;
+	} else {
+		ops = (struct spi_ops *)pdev->id_entry->driver_data;
+		rspi_pd = dev_get_platdata(&pdev->dev);
+		if (rspi_pd && rspi_pd->num_chipselect)
+			master->num_chipselect = rspi_pd->num_chipselect;
+		else
+			master->num_chipselect = 2; /* default */
+	};
+
+	/* ops parameter check */
+	if (!ops->set_config_register) {
+		dev_err(&pdev->dev, "there is no set_config_register\n");
+		ret = -ENODEV;
+		goto error1;
+	}
+
 	rspi = spi_master_get_devdata(master);
 	platform_set_drvdata(pdev, rspi);
 	rspi->ops = ops;
@@ -1048,11 +1114,6 @@ static int rspi_probe(struct platform_device *pdev)
 
 	init_waitqueue_head(&rspi->wait);
 
-	if (rspi_pd && rspi_pd->num_chipselect)
-		master->num_chipselect = rspi_pd->num_chipselect;
-	else
-		master->num_chipselect = 2; /* default */
-
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
 	master->transfer_one = ops->transfer_one;
@@ -1060,6 +1121,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
+	master->dev.of_node = pdev->dev.of_node;
 
 	ret = platform_get_irq_byname(pdev, "rx");
 	if (ret < 0) {
@@ -1122,21 +1184,6 @@ error1:
 	return ret;
 }
 
-static struct spi_ops rspi_ops = {
-	.set_config_register =		rspi_set_config_register,
-	.transfer_one =			rspi_transfer_one,
-};
-
-static struct spi_ops rspi_rz_ops = {
-	.set_config_register =		rspi_rz_set_config_register,
-	.transfer_one =			rspi_rz_transfer_one,
-};
-
-static struct spi_ops qspi_ops = {
-	.set_config_register =		qspi_set_config_register,
-	.transfer_one =			qspi_transfer_one,
-};
-
 static struct platform_device_id spi_driver_ids[] = {
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
 	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops },
@@ -1153,6 +1200,7 @@ static struct platform_driver rspi_driver = {
 	.driver		= {
 		.name = "renesas_spi",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(rspi_of_match),
 	},
 };
 module_platform_driver(rspi_driver);
-- 
1.7.9.5


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

* [PATCH v4 13/14] spi: rspi: Add DT support
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven, devicetree

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Cc: devicetree@vger.kernel.org
---
v2:
  - Clarify RSPI/QSPI
  - Add interrupt-parent
  - s/should/must/ for #address-cells and #size-cells
v3:
  - Add renesas,rspi-sh
  - Drop -rcar suffix for QSPI
  - Clarify num-cs
  - Implement DT support in driver
  - Changed one-line summary from "Documentation: dt: Add Renesas RSPI/QSPI
    bindings" to "spi: rspi: Add DT support"
v4:
  - Clarify SoCtype and interrupts
  - Add clock property
  - Add QSPI example
  - Add interrupt-names
  - Add link to Renesas pinctrl
  - Rename "renesas,rspi-sh" to "renesas,rspi", to match platform device
    naming
  - spi-rspi.c:
      - Remove Soc-specific matching from spi-rspi.c given the fallback is
	mandatory
      - Things became a lot simpler due to the replacement of platform_data
        fields by the "rspi-rz" platform device binding.
---
 Documentation/devicetree/bindings/spi/spi-rspi.txt |   58 +++++++++++
 drivers/spi/spi-rspi.c                             |  106 ++++++++++++++------
 2 files changed, 135 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-rspi.txt

diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt
new file mode 100644
index 000000000000..ed84299a9c61
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-rspi.txt
@@ -0,0 +1,58 @@
+Device tree configuration for Renesas RSPI/QSPI driver
+
+Required properties:
+- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
+		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
+		     For Renesas Serial Peripheral Interface on RZ/A1H:
+		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
+		     For Quad Serial Peripheral Interface on R-Car Gen2:
+		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
+		     Examples of valid soctypes are "sh7757" (SH),
+		     "r7s72100" (RZ/A1H), "r8a7790" (R-Car H2), and
+		     "r8a7791" (R-Car M2).
+- reg              : Address start and address range size of the device
+- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
+		     interrupt,
+		     3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
+		     separate interrupts.
+- interrupt-names  : Array of strings associated with the interrupt numbers:
+		     "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
+		     For RSPI cores using a single multiplexed interrupt, the
+		     name "mux" is optional.
+- interrupt-parent : The phandle for the interrupt controller that
+		     services interrupts for this device.
+- num-cs	   : Number of chip selects. Some RSPI cores have more than 1.
+- #address-cells   : Must be <1>
+- #size-cells      : Must be <0>
+
+Optional properties:
+- clocks:           : Must contain a reference to the functional clock.
+
+Pinctrl properties might be needed, too.  See
+Documentation/devicetree/bindings/pinctrl/renesas,*.
+
+Examples:
+
+	spi0: spi@e800c800 {
+		compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+		reg = <0xe800c800 0x24>;
+		interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 239 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "error", "rx", "tx";
+		interrupt-parent = <&gic>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	spi: spi@e6b10000 {
+		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+		reg = <0 0xe6b10000 0 0x2c>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index d79a7ed9b92e..e56fcb5f7f99 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
 #include <linux/sh_dma.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/rspi.h>
@@ -985,6 +986,56 @@ static int rspi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct spi_ops rspi_ops = {
+	.set_config_register =		rspi_set_config_register,
+	.transfer_one =			rspi_transfer_one,
+};
+
+static const struct spi_ops rspi_rz_ops = {
+	.set_config_register =		rspi_rz_set_config_register,
+	.transfer_one =			rspi_rz_transfer_one,
+};
+
+static const struct spi_ops qspi_ops = {
+	.set_config_register =		qspi_set_config_register,
+	.transfer_one =			qspi_transfer_one,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id rspi_of_match[] = {
+	/* RSPI on legacy SH */
+	{ .compatible = "renesas,rspi", .data = &rspi_ops },
+	/* RSPI on RZ/A1H */
+	{ .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops },
+	/* QSPI on R-Car Gen2 */
+	{ .compatible = "renesas,qspi", .data = &qspi_ops },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, rspi_of_match);
+
+static int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	u32 num_cs;
+	int error;
+
+	/* Parse DT properties */
+	error = of_property_read_u32(dev->of_node, "num-cs", &num_cs);
+	if (error) {
+		dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error);
+		return error;
+	}
+
+	master->num_chipselect = num_cs;
+	return 0;
+}
+#else
+static inline int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_OF */
+
 static int rspi_request_irq(struct device *dev, unsigned int irq,
 			    irq_handler_t handler, const char *suffix,
 			    void *dev_id)
@@ -1004,16 +1055,9 @@ static int rspi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct rspi_data *rspi;
 	int ret;
-	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
+	const struct of_device_id *of_id;
+	const struct rspi_plat_data *rspi_pd;
 	const struct spi_ops *ops;
-	const struct platform_device_id *id_entry = pdev->id_entry;
-
-	ops = (struct spi_ops *)id_entry->driver_data;
-	/* ops parameter check */
-	if (!ops->set_config_register) {
-		dev_err(&pdev->dev, "there is no set_config_register\n");
-		return -ENODEV;
-	}
 
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master == NULL) {
@@ -1021,6 +1065,28 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	of_id = of_match_device(rspi_of_match, &pdev->dev);
+	if (of_id) {
+		ops = of_id->data;
+		ret = rspi_parse_dt(&pdev->dev, master);
+		if (ret)
+			goto error1;
+	} else {
+		ops = (struct spi_ops *)pdev->id_entry->driver_data;
+		rspi_pd = dev_get_platdata(&pdev->dev);
+		if (rspi_pd && rspi_pd->num_chipselect)
+			master->num_chipselect = rspi_pd->num_chipselect;
+		else
+			master->num_chipselect = 2; /* default */
+	};
+
+	/* ops parameter check */
+	if (!ops->set_config_register) {
+		dev_err(&pdev->dev, "there is no set_config_register\n");
+		ret = -ENODEV;
+		goto error1;
+	}
+
 	rspi = spi_master_get_devdata(master);
 	platform_set_drvdata(pdev, rspi);
 	rspi->ops = ops;
@@ -1048,11 +1114,6 @@ static int rspi_probe(struct platform_device *pdev)
 
 	init_waitqueue_head(&rspi->wait);
 
-	if (rspi_pd && rspi_pd->num_chipselect)
-		master->num_chipselect = rspi_pd->num_chipselect;
-	else
-		master->num_chipselect = 2; /* default */
-
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
 	master->transfer_one = ops->transfer_one;
@@ -1060,6 +1121,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
 	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
+	master->dev.of_node = pdev->dev.of_node;
 
 	ret = platform_get_irq_byname(pdev, "rx");
 	if (ret < 0) {
@@ -1122,21 +1184,6 @@ error1:
 	return ret;
 }
 
-static struct spi_ops rspi_ops = {
-	.set_config_register =		rspi_set_config_register,
-	.transfer_one =			rspi_transfer_one,
-};
-
-static struct spi_ops rspi_rz_ops = {
-	.set_config_register =		rspi_rz_set_config_register,
-	.transfer_one =			rspi_rz_transfer_one,
-};
-
-static struct spi_ops qspi_ops = {
-	.set_config_register =		qspi_set_config_register,
-	.transfer_one =			qspi_transfer_one,
-};
-
 static struct platform_device_id spi_driver_ids[] = {
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
 	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops },
@@ -1153,6 +1200,7 @@ static struct platform_driver rspi_driver = {
 	.driver		= {
 		.name = "renesas_spi",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(rspi_of_match),
 	},
 };
 module_platform_driver(rspi_driver);
-- 
1.7.9.5


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

* [PATCH 14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for Quad and Dual SPI Transfers on the Renesas Quad Serial
Peripheral Interface, as found in R-Car Gen2 SoCs like R-Car H2 (r8a7790)
and R-Car M2 (r8a7791):
  - Add unidirectional transfer methods for Quad/Dual SPI Transfers.
  - Program the sequencer to handle SPI messages with multiple transfer
    modes when Quad or Dual transfers are enabled for an SPI slave.
    Up to 4 transfer modes per SPI message are supported by the hardware.
  - Advertise the availability of Quad and Dual SPI modes on QSPI.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  162 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 148 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index e56fcb5f7f99..34ad4bca8a41 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -2,6 +2,7 @@
  * SH RSPI driver
  *
  * Copyright (C) 2012, 2013  Renesas Solutions Corp.
+ * Copyright (C) 2014 Glider bvba
  *
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -57,6 +58,10 @@
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
+#define RSPI_SPCMD(i)		(RSPI_SPCMD0 + (i) * 2)
+#define RSPI_NUM_SPCMD		8
+#define RSPI_RZ_NUM_SPCMD	4
+#define QSPI_NUM_SPCMD		4
 
 /* RSPI on RZ only */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
@@ -69,6 +74,7 @@
 #define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */
 #define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */
 #define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */
+#define QSPI_SPBMUL(i)		(QSPI_SPBMUL0 + (i) * 4)
 
 /* SPCR - Control Register */
 #define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */
@@ -152,7 +158,7 @@
 #define SPCMD_LSBF		0x1000	/* LSB First */
 #define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
-#define SPCMD_SPB_8BIT		0x0000	/* qspi only */
+#define SPCMD_SPB_8BIT		0x0000	/* QSPI only */
 #define SPCMD_SPB_16BIT		0x0100
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_24BIT		0x0100
@@ -245,6 +251,7 @@ struct spi_ops {
 	int (*set_config_register)(struct rspi_data *rspi, int access_size);
 	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
 			    struct spi_transfer *xfer);
+	u16 mode_bits;
 };
 
 /*
@@ -274,8 +281,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 	rspi_write8(rspi, 0x00, RSPI_SPCR2);
 
 	/* Sets SPCMD */
-	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | rspi->spcmd,
-		     RSPI_SPCMD0);
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
 	/* Sets RSPI mode */
 	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
@@ -321,7 +328,6 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
  */
 static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
-	u16 spcmd;
 	int spbr;
 
 	/* Sets output mode, MOSI signal, and (optionally) loopback */
@@ -342,13 +348,13 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 
 	/* Data Length Setting */
 	if (access_size = 8)
-		spcmd = SPCMD_SPB_8BIT;
+		rspi->spcmd |= SPCMD_SPB_8BIT;
 	else if (access_size = 16)
-		spcmd = SPCMD_SPB_16BIT;
+		rspi->spcmd |= SPCMD_SPB_16BIT;
 	else
-		spcmd = SPCMD_SPB_32BIT;
+		rspi->spcmd |= SPCMD_SPB_32BIT;
 
-	spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | rspi->spcmd | SPCMD_SPNDEN;
+	rspi->spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SPNDEN;
 
 	/* Resets transfer data length */
 	rspi_write32(rspi, 0, QSPI_SPBMUL0);
@@ -359,9 +365,9 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 
 	/* Sets SPCMD */
-	rspi_write16(rspi, spcmd, RSPI_SPCMD0);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
-	/* Enables SPI function in a master mode */
+	/* Enables SPI function in master mode */
 	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 
 	return 0;
@@ -811,12 +817,55 @@ static int qspi_transfer_out_in(struct rspi_data *rspi,
 	return 0;
 }
 
+static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	const u8 *buf = xfer->tx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_out(rspi, *buf++);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	u8 *buf = xfer->rx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_in(rspi);
+		if (ret < 0)
+			return ret;
+		*buf++ = ret;
+	}
+
+	return 0;
+}
+
 static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 			     struct spi_transfer *xfer)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
 
-	return qspi_transfer_out_in(rspi, xfer);
+	if (xfer->tx_buf && xfer->tx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Write */
+		return qspi_transfer_out(rspi, xfer);
+	} else if (xfer->rx_buf && xfer->rx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Read */
+		return qspi_transfer_in(rspi, xfer);
+	} else {
+		/* Single SPI Transfer */
+		return qspi_transfer_out_in(rspi, xfer);
+	}
 }
 
 static int rspi_setup(struct spi_device *spi)
@@ -845,21 +894,101 @@ static void rspi_cleanup(struct spi_device *spi)
 {
 }
 
+static u16 qspi_transfer_mode(const struct spi_transfer *xfer)
+{
+	if (xfer->tx_buf)
+		switch (xfer->tx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL;
+		default:
+			return 0;
+		}
+	if (xfer->rx_buf)
+		switch (xfer->rx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD | SPCMD_SPRW;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL | SPCMD_SPRW;
+		default:
+			return 0;
+		}
+
+	return 0;
+}
+
+static int qspi_setup_sequencer(struct rspi_data *rspi,
+				const struct spi_message *msg)
+{
+	const struct spi_transfer *xfer;
+	unsigned int i = 0, len = 0;
+	u16 current_mode = 0xffff, mode;
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		mode = qspi_transfer_mode(xfer);
+		if (mode = current_mode) {
+			len += xfer->len;
+			continue;
+		}
+
+		/* Transfer mode change */
+		if (i) {
+			/* Set transfer data length of previous transfer */
+			rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		}
+
+		if (i >= QSPI_NUM_SPCMD) {
+			dev_err(&msg->spi->dev,
+				"Too many different transfer modes");
+			return -EINVAL;
+		}
+
+		/* Program transfer mode for this transfer */
+		rspi_write16(rspi, rspi->spcmd | mode, RSPI_SPCMD(i));
+		current_mode = mode;
+		len = xfer->len;
+		i++;
+	}
+	if (i) {
+		/* Set final transfer data length and sequence length */
+		rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		rspi_write8(rspi, i - 1, RSPI_SPSCR);
+	}
+
+	return 0;
+}
+
 static int rspi_prepare_message(struct spi_master *master,
-				struct spi_message *message)
+				struct spi_message *msg)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret;
 
+	if (msg->spi->mode &
+	    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) {
+		/* Setup sequencer for messages with multiple transfer modes */
+		ret = qspi_setup_sequencer(rspi, msg);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Enable SPI function in master mode */
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
 	return 0;
 }
 
 static int rspi_unprepare_message(struct spi_master *master,
-				  struct spi_message *message)
+				  struct spi_message *msg)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
 
+	/* Disable SPI function */
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+
+	/* Reset sequencer for Single SPI Transfers */
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+	rspi_write8(rspi, 0, RSPI_SPSCR);
 	return 0;
 }
 
@@ -989,16 +1118,21 @@ static int rspi_remove(struct platform_device *pdev)
 static const struct spi_ops rspi_ops = {
 	.set_config_register =		rspi_set_config_register,
 	.transfer_one =			rspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
 };
 
 static const struct spi_ops rspi_rz_ops = {
 	.set_config_register =		rspi_rz_set_config_register,
 	.transfer_one =			rspi_rz_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
 };
 
 static const struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
 	.transfer_one =			qspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP |
+					SPI_TX_DUAL | SPI_TX_QUAD |
+					SPI_RX_DUAL | SPI_RX_QUAD,
 };
 
 #ifdef CONFIG_OF
@@ -1120,7 +1254,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
-	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
+	master->mode_bits = ops->mode_bits;
 	master->dev.of_node = pdev->dev.of_node;
 
 	ret = platform_get_irq_byname(pdev, "rx");
-- 
1.7.9.5


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

* [PATCH 14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI
@ 2014-01-24  8:44   ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24  8:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Add support for Quad and Dual SPI Transfers on the Renesas Quad Serial
Peripheral Interface, as found in R-Car Gen2 SoCs like R-Car H2 (r8a7790)
and R-Car M2 (r8a7791):
  - Add unidirectional transfer methods for Quad/Dual SPI Transfers.
  - Program the sequencer to handle SPI messages with multiple transfer
    modes when Quad or Dual transfers are enabled for an SPI slave.
    Up to 4 transfer modes per SPI message are supported by the hardware.
  - Advertise the availability of Quad and Dual SPI modes on QSPI.

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi-rspi.c |  162 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 148 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index e56fcb5f7f99..34ad4bca8a41 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -2,6 +2,7 @@
  * SH RSPI driver
  *
  * Copyright (C) 2012, 2013  Renesas Solutions Corp.
+ * Copyright (C) 2014 Glider bvba
  *
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -57,6 +58,10 @@
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
+#define RSPI_SPCMD(i)		(RSPI_SPCMD0 + (i) * 2)
+#define RSPI_NUM_SPCMD		8
+#define RSPI_RZ_NUM_SPCMD	4
+#define QSPI_NUM_SPCMD		4
 
 /* RSPI on RZ only */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
@@ -69,6 +74,7 @@
 #define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */
 #define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */
 #define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */
+#define QSPI_SPBMUL(i)		(QSPI_SPBMUL0 + (i) * 4)
 
 /* SPCR - Control Register */
 #define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */
@@ -152,7 +158,7 @@
 #define SPCMD_LSBF		0x1000	/* LSB First */
 #define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
-#define SPCMD_SPB_8BIT		0x0000	/* qspi only */
+#define SPCMD_SPB_8BIT		0x0000	/* QSPI only */
 #define SPCMD_SPB_16BIT		0x0100
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_24BIT		0x0100
@@ -245,6 +251,7 @@ struct spi_ops {
 	int (*set_config_register)(struct rspi_data *rspi, int access_size);
 	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
 			    struct spi_transfer *xfer);
+	u16 mode_bits;
 };
 
 /*
@@ -274,8 +281,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 	rspi_write8(rspi, 0x00, RSPI_SPCR2);
 
 	/* Sets SPCMD */
-	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | rspi->spcmd,
-		     RSPI_SPCMD0);
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
 	/* Sets RSPI mode */
 	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
@@ -321,7 +328,6 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
  */
 static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
-	u16 spcmd;
 	int spbr;
 
 	/* Sets output mode, MOSI signal, and (optionally) loopback */
@@ -342,13 +348,13 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 
 	/* Data Length Setting */
 	if (access_size == 8)
-		spcmd = SPCMD_SPB_8BIT;
+		rspi->spcmd |= SPCMD_SPB_8BIT;
 	else if (access_size == 16)
-		spcmd = SPCMD_SPB_16BIT;
+		rspi->spcmd |= SPCMD_SPB_16BIT;
 	else
-		spcmd = SPCMD_SPB_32BIT;
+		rspi->spcmd |= SPCMD_SPB_32BIT;
 
-	spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | rspi->spcmd | SPCMD_SPNDEN;
+	rspi->spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SPNDEN;
 
 	/* Resets transfer data length */
 	rspi_write32(rspi, 0, QSPI_SPBMUL0);
@@ -359,9 +365,9 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 
 	/* Sets SPCMD */
-	rspi_write16(rspi, spcmd, RSPI_SPCMD0);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
-	/* Enables SPI function in a master mode */
+	/* Enables SPI function in master mode */
 	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 
 	return 0;
@@ -811,12 +817,55 @@ static int qspi_transfer_out_in(struct rspi_data *rspi,
 	return 0;
 }
 
+static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	const u8 *buf = xfer->tx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_out(rspi, *buf++);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	u8 *buf = xfer->rx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_in(rspi);
+		if (ret < 0)
+			return ret;
+		*buf++ = ret;
+	}
+
+	return 0;
+}
+
 static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
 			     struct spi_transfer *xfer)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
 
-	return qspi_transfer_out_in(rspi, xfer);
+	if (xfer->tx_buf && xfer->tx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Write */
+		return qspi_transfer_out(rspi, xfer);
+	} else if (xfer->rx_buf && xfer->rx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Read */
+		return qspi_transfer_in(rspi, xfer);
+	} else {
+		/* Single SPI Transfer */
+		return qspi_transfer_out_in(rspi, xfer);
+	}
 }
 
 static int rspi_setup(struct spi_device *spi)
@@ -845,21 +894,101 @@ static void rspi_cleanup(struct spi_device *spi)
 {
 }
 
+static u16 qspi_transfer_mode(const struct spi_transfer *xfer)
+{
+	if (xfer->tx_buf)
+		switch (xfer->tx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL;
+		default:
+			return 0;
+		}
+	if (xfer->rx_buf)
+		switch (xfer->rx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD | SPCMD_SPRW;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL | SPCMD_SPRW;
+		default:
+			return 0;
+		}
+
+	return 0;
+}
+
+static int qspi_setup_sequencer(struct rspi_data *rspi,
+				const struct spi_message *msg)
+{
+	const struct spi_transfer *xfer;
+	unsigned int i = 0, len = 0;
+	u16 current_mode = 0xffff, mode;
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		mode = qspi_transfer_mode(xfer);
+		if (mode == current_mode) {
+			len += xfer->len;
+			continue;
+		}
+
+		/* Transfer mode change */
+		if (i) {
+			/* Set transfer data length of previous transfer */
+			rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		}
+
+		if (i >= QSPI_NUM_SPCMD) {
+			dev_err(&msg->spi->dev,
+				"Too many different transfer modes");
+			return -EINVAL;
+		}
+
+		/* Program transfer mode for this transfer */
+		rspi_write16(rspi, rspi->spcmd | mode, RSPI_SPCMD(i));
+		current_mode = mode;
+		len = xfer->len;
+		i++;
+	}
+	if (i) {
+		/* Set final transfer data length and sequence length */
+		rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		rspi_write8(rspi, i - 1, RSPI_SPSCR);
+	}
+
+	return 0;
+}
+
 static int rspi_prepare_message(struct spi_master *master,
-				struct spi_message *message)
+				struct spi_message *msg)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret;
 
+	if (msg->spi->mode &
+	    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) {
+		/* Setup sequencer for messages with multiple transfer modes */
+		ret = qspi_setup_sequencer(rspi, msg);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Enable SPI function in master mode */
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
 	return 0;
 }
 
 static int rspi_unprepare_message(struct spi_master *master,
-				  struct spi_message *message)
+				  struct spi_message *msg)
 {
 	struct rspi_data *rspi = spi_master_get_devdata(master);
 
+	/* Disable SPI function */
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+
+	/* Reset sequencer for Single SPI Transfers */
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+	rspi_write8(rspi, 0, RSPI_SPSCR);
 	return 0;
 }
 
@@ -989,16 +1118,21 @@ static int rspi_remove(struct platform_device *pdev)
 static const struct spi_ops rspi_ops = {
 	.set_config_register =		rspi_set_config_register,
 	.transfer_one =			rspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
 };
 
 static const struct spi_ops rspi_rz_ops = {
 	.set_config_register =		rspi_rz_set_config_register,
 	.transfer_one =			rspi_rz_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
 };
 
 static const struct spi_ops qspi_ops = {
 	.set_config_register =		qspi_set_config_register,
 	.transfer_one =			qspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP |
+					SPI_TX_DUAL | SPI_TX_QUAD |
+					SPI_RX_DUAL | SPI_RX_QUAD,
 };
 
 #ifdef CONFIG_OF
@@ -1120,7 +1254,7 @@ static int rspi_probe(struct platform_device *pdev)
 	master->cleanup = rspi_cleanup;
 	master->prepare_message = rspi_prepare_message;
 	master->unprepare_message = rspi_unprepare_message;
-	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP;
+	master->mode_bits = ops->mode_bits;
 	master->dev.of_node = pdev->dev.of_node;
 
 	ret = platform_get_irq_byname(pdev, "rx");
-- 
1.7.9.5


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

* Re: [PATCH v4 13/14] spi: rspi: Add DT support
  2014-01-24  8:44   ` Geert Uytterhoeven
  (?)
@ 2014-01-24  9:33   ` Mark Rutland
       [not found]     ` <20140124093349.GK15586-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
  -1 siblings, 1 reply; 57+ messages in thread
From: Mark Rutland @ 2014-01-24  9:33 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Mark Brown, linux-spi, linux-sh, linux-kernel,
	Geert Uytterhoeven, devicetree

On Fri, Jan 24, 2014 at 08:44:03AM +0000, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> Cc: devicetree@vger.kernel.org
> ---
> v2:
>   - Clarify RSPI/QSPI
>   - Add interrupt-parent
>   - s/should/must/ for #address-cells and #size-cells
> v3:
>   - Add renesas,rspi-sh
>   - Drop -rcar suffix for QSPI
>   - Clarify num-cs
>   - Implement DT support in driver
>   - Changed one-line summary from "Documentation: dt: Add Renesas RSPI/QSPI
>     bindings" to "spi: rspi: Add DT support"
> v4:
>   - Clarify SoCtype and interrupts
>   - Add clock property
>   - Add QSPI example
>   - Add interrupt-names
>   - Add link to Renesas pinctrl
>   - Rename "renesas,rspi-sh" to "renesas,rspi", to match platform device
>     naming
>   - spi-rspi.c:
>       - Remove Soc-specific matching from spi-rspi.c given the fallback is
> 	mandatory
>       - Things became a lot simpler due to the replacement of platform_data
>         fields by the "rspi-rz" platform device binding.
> ---
>  Documentation/devicetree/bindings/spi/spi-rspi.txt |   58 +++++++++++
>  drivers/spi/spi-rspi.c                             |  106 ++++++++++++++------
>  2 files changed, 135 insertions(+), 29 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/spi-rspi.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt
> new file mode 100644
> index 000000000000..ed84299a9c61
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/spi-rspi.txt
> @@ -0,0 +1,58 @@
> +Device tree configuration for Renesas RSPI/QSPI driver
> +
> +Required properties:
> +- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
> +		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
> +		     For Renesas Serial Peripheral Interface on RZ/A1H:
> +		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
> +		     For Quad Serial Peripheral Interface on R-Car Gen2:
> +		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
> +		     Examples of valid soctypes are "sh7757" (SH),
> +		     "r7s72100" (RZ/A1H), "r8a7790" (R-Car H2), and
> +		     "r8a7791" (R-Car M2).
> +- reg              : Address start and address range size of the device
> +- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
> +		     interrupt,
> +		     3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
> +		     separate interrupts.
> +- interrupt-names  : Array of strings associated with the interrupt numbers:
> +		     "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
> +		     For RSPI cores using a single multiplexed interrupt, the
> +		     name "mux" is optional.


Rather than defining the set of interrupts twice, it would be nice to
have interrupts defined in terms of interrupt-names:

- interrupts: a list of interrupt-specifiers, one for each entry in
  interrupt-names. If interrupt-names is not present, an interrupt
  specifier for a single muxed interrupt.

- interrupt-names: A list of interrupt names. Should contain (if
  present):
  * "error" for SPEI
  * "rx" for SPRI
  * "tx" to SPTI
  * "mux" for a single muxed interrupt

Thanks,
Mark.

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

* Re: [PATCH v4 13/14] spi: rspi: Add DT support
  2014-01-24  9:33   ` Mark Rutland
       [not found]     ` <20140124093349.GK15586-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
@ 2014-01-24 13:05         ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24 13:05 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Fri, Jan 24, 2014 at 10:33 AM, Mark Rutland <mark.rutland@arm.com> wrote:
>> +- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
>> +                  interrupt,
>> +                  3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
>> +                  separate interrupts.
>> +- interrupt-names  : Array of strings associated with the interrupt numbers:
>> +                  "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
>> +                  For RSPI cores using a single multiplexed interrupt, the
>> +                  name "mux" is optional.
>
> Rather than defining the set of interrupts twice, it would be nice to
> have interrupts defined in terms of interrupt-names:
>
> - interrupts: a list of interrupt-specifiers, one for each entry in
>   interrupt-names. If interrupt-names is not present, an interrupt
>   specifier for a single muxed interrupt.
>
> - interrupt-names: A list of interrupt names. Should contain (if
>   present):
>   * "error" for SPEI
>   * "rx" for SPRI
>   * "tx" to SPTI
>   * "mux" for a single muxed interrupt

Yes, that sounds much better, thank you.
Will update.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 13/14] spi: rspi: Add DT support
@ 2014-01-24 13:05         ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24 13:05 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mark Brown, linux-spi, linux-sh, linux-kernel,
	Geert Uytterhoeven, devicetree

On Fri, Jan 24, 2014 at 10:33 AM, Mark Rutland <mark.rutland@arm.com> wrote:
>> +- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
>> +                  interrupt,
>> +                  3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
>> +                  separate interrupts.
>> +- interrupt-names  : Array of strings associated with the interrupt numbers:
>> +                  "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
>> +                  For RSPI cores using a single multiplexed interrupt, the
>> +                  name "mux" is optional.
>
> Rather than defining the set of interrupts twice, it would be nice to
> have interrupts defined in terms of interrupt-names:
>
> - interrupts: a list of interrupt-specifiers, one for each entry in
>   interrupt-names. If interrupt-names is not present, an interrupt
>   specifier for a single muxed interrupt.
>
> - interrupt-names: A list of interrupt names. Should contain (if
>   present):
>   * "error" for SPEI
>   * "rx" for SPRI
>   * "tx" to SPTI
>   * "mux" for a single muxed interrupt

Yes, that sounds much better, thank you.
Will update.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 13/14] spi: rspi: Add DT support
@ 2014-01-24 13:05         ` Geert Uytterhoeven
  0 siblings, 0 replies; 57+ messages in thread
From: Geert Uytterhoeven @ 2014-01-24 13:05 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Fri, Jan 24, 2014 at 10:33 AM, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>> +- interrupts       : 1 interrupt for RSPI cores using a single multiplexed
>> +                  interrupt,
>> +                  3 interrupts (SPEI, SPRI, SPTI) for RSPI cores using
>> +                  separate interrupts.
>> +- interrupt-names  : Array of strings associated with the interrupt numbers:
>> +                  "error" for SPEI, "rx" for SPRI, and "tx" for SPTI.
>> +                  For RSPI cores using a single multiplexed interrupt, the
>> +                  name "mux" is optional.
>
> Rather than defining the set of interrupts twice, it would be nice to
> have interrupts defined in terms of interrupt-names:
>
> - interrupts: a list of interrupt-specifiers, one for each entry in
>   interrupt-names. If interrupt-names is not present, an interrupt
>   specifier for a single muxed interrupt.
>
> - interrupt-names: A list of interrupt names. Should contain (if
>   present):
>   * "error" for SPEI
>   * "rx" for SPRI
>   * "tx" to SPTI
>   * "mux" for a single muxed interrupt

Yes, that sounds much better, thank you.
Will update.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
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] 57+ messages in thread

* Re: [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio()
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:02       ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:02 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:51AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio()
@ 2014-01-27 20:02       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:02 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:51AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio()
@ 2014-01-27 20:02       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:02 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:51AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 02/14] spi: rspi: Use core message handling
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:02   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:02 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:52AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Let the generic SPI core handle SPI messages, calling into our
> rspi_transfer_one() method.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 03/14] spi: rspi: Abstract 8/16-bit Data Register access
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:02   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:02 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:53AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add rspi_{write,read}_data(), to abstract 8-bit (QSPI, and RSPI on RZ/A1H)
> versus 16-bit (RSPI) Data Register access.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:03   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:03 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:54AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add helpers rspi_data_{out,in,out_in}() to write, read, or write and
> read data to/from the Data Register, taking care of waiting until data
> or space is available in the buffers.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:03   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:03 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:55AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Split off qspi_transfer_one() (which doesn't support DMA yet) from
> rspi_transfer_one().
> Replace the abstraction of send_pio()/receive_pio() by the abstracrion of
> transfer_one().

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:04       ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:04 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:56AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> rspi_send_pio() and rspi_receive_pio() are very similar:
>   - the former only sends data, using TX Only Mode,
>   - the latter sends and receives full duplex data to/from the hardware,
>     but uses dummy transmit data.
> Merge them into rspi_transfer_out_in(), now supporting full duplex if
> needed.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
@ 2014-01-27 20:04       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:04 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:56AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> rspi_send_pio() and rspi_receive_pio() are very similar:
>   - the former only sends data, using TX Only Mode,
>   - the latter sends and receives full duplex data to/from the hardware,
>     but uses dummy transmit data.
> Merge them into rspi_transfer_out_in(), now supporting full duplex if
> needed.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
@ 2014-01-27 20:04       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:04 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:56AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
> 
> rspi_send_pio() and rspi_receive_pio() are very similar:
>   - the former only sends data, using TX Only Mode,
>   - the latter sends and receives full duplex data to/from the hardware,
>     but uses dummy transmit data.
> Merge them into rspi_transfer_out_in(), now supporting full duplex if
> needed.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio()
  2014-01-24  8:43   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:04   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:04 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:57AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> qspi_send_pio() and qspi_receive_pio() are very similar: they both send
> and receive full duplex data to/from the hardware, but ignore the data
> stream in the unused direction.
> Merge them into qspi_transfer_out_in(), now supporting real full duplex.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v3 08/14] spi: rspi: Add support for more than one interrupt
  2014-01-24  8:43     ` Geert Uytterhoeven
  (?)
  (?)
@ 2014-01-27 20:05     ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:05 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:58AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for multiple interrupts, based on the SDK reference code.
> This is needed for RZ/A1H, which supports 3 interrupts.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 09/14] spi: rspi: Add support for RSPI on RZ/A1H
  2014-01-24  8:43 ` Geert Uytterhoeven
@ 2014-01-27 20:07   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:07 UTC (permalink / raw)
  To: linux-sh

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

On Fri, Jan 24, 2014 at 09:43:59AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for the RSPI variant in the RZ/A1H (r7s72100) SoC.
> 
> Main differences with RSPI on SH are:
>   - Lack of TX only mode, hence we always have to use full duplex
>     transfers,
>   - The Data Register must be accessed used 8-bit operations.

Applied, thanks.  Ideally (and hopefully soon since I have a use for it
myself) we'll have a feature in the core which automatically provides
dummy data for full duplex mode but that's not a blocker here.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 09/14] spi: rspi: Add support for RSPI on RZ/A1H
@ 2014-01-27 20:07   ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:07 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:43:59AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for the RSPI variant in the RZ/A1H (r7s72100) SoC.
> 
> Main differences with RSPI on SH are:
>   - Lack of TX only mode, hence we always have to use full duplex
>     transfers,
>   - The Data Register must be accessed used 8-bit operations.

Applied, thanks.  Ideally (and hopefully soon since I have a use for it
myself) we'll have a feature in the core which automatically provides
dummy data for full duplex mode but that's not a blocker here.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v3 10/14] spi: rspi: Add support for loopback mode
  2014-01-24  8:44   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:08       ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:08 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:00AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for specifying loopback mode.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v3 10/14] spi: rspi: Add support for loopback mode
@ 2014-01-27 20:08       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:08 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:00AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for specifying loopback mode.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v3 10/14] spi: rspi: Add support for loopback mode
@ 2014-01-27 20:08       ` Mark Brown
  0 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:08 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:00AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
> 
> Add support for specifying loopback mode.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare
  2014-01-24  8:44     ` Geert Uytterhoeven
  (?)
  (?)
@ 2014-01-27 20:08     ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:08 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:01AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Get the driver ready for the migration to the common clock framework by
> calling clk_prepare_enable() and clk_disable_unprepare().

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 12/14] spi: rspi: Use NULL as the clock ID
  2014-01-24  8:44   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:08   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:08 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:02AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> There's only one RSPI/QSPI clock, so we can use NULL as the clock ID

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v4 13/14] spi: rspi: Add DT support
  2014-01-24  8:44   ` Geert Uytterhoeven
  (?)
  (?)
@ 2014-01-27 20:11   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:11 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven, devicetree

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

On Fri, Jan 24, 2014 at 09:44:03AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> Cc: devicetree@vger.kernel.org

This looks good modulo Mark's comment on the binding document.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI
  2014-01-24  8:44   ` Geert Uytterhoeven
  (?)
@ 2014-01-27 20:27   ` Mark Brown
  -1 siblings, 0 replies; 57+ messages in thread
From: Mark Brown @ 2014-01-27 20:27 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, linux-kernel, Geert Uytterhoeven

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

On Fri, Jan 24, 2014 at 09:44:04AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> 
> Add support for Quad and Dual SPI Transfers on the Renesas Quad Serial
> Peripheral Interface, as found in R-Car Gen2 SoCs like R-Car H2 (r8a7790)
> and R-Car M2 (r8a7791):

This looks fine but depends on the DT bindings patch so it'll need to
wait for that.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

end of thread, other threads:[~2014-01-27 20:27 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-24  8:43 [PATCH 0/14] spi: rspi: Add support for RZ/A1H, DT, and Quad/Dual on QSPI Geert Uytterhoeven
2014-01-24  8:43 ` Geert Uytterhoeven
2014-01-24  8:43 ` [PATCH 01/14] spi: rspi: Remove unused mesg parameter from {send,receive}_pio() Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
     [not found]   ` <1390553044-11860-2-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-27 20:02     ` Mark Brown
2014-01-27 20:02       ` Mark Brown
2014-01-27 20:02       ` Mark Brown
2014-01-24  8:43 ` [PATCH 02/14] spi: rspi: Use core message handling Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
2014-01-27 20:02   ` Mark Brown
2014-01-24  8:43 ` [PATCH 03/14] spi: rspi: Abstract 8/16-bit Data Register access Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
2014-01-27 20:02   ` Mark Brown
2014-01-24  8:43 ` [PATCH 04/14] spi: rspi: Add rspi_data_{out,in,out_in}() helpers Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
2014-01-27 20:03   ` Mark Brown
2014-01-24  8:43 ` [PATCH 05/14] spi: rspi: Abstract transfer_one() for RSPI and QSPI Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
2014-01-27 20:03   ` Mark Brown
2014-01-24  8:43 ` [PATCH 06/14] spi: rspi: Merge rspi_send_pio() and rspi_receive_pio() Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
     [not found]   ` <1390553044-11860-7-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-27 20:04     ` Mark Brown
2014-01-27 20:04       ` Mark Brown
2014-01-27 20:04       ` Mark Brown
2014-01-24  8:43 ` [PATCH 07/14] spi: rspi: Merge qspi_send_pio() and qspi_receive_pio() Geert Uytterhoeven
2014-01-24  8:43   ` Geert Uytterhoeven
2014-01-27 20:04   ` Mark Brown
2014-01-24  8:44 ` [PATCH v3 10/14] spi: rspi: Add support for loopback mode Geert Uytterhoeven
2014-01-24  8:44   ` Geert Uytterhoeven
     [not found]   ` <1390553044-11860-11-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-27 20:08     ` Mark Brown
2014-01-27 20:08       ` Mark Brown
2014-01-27 20:08       ` Mark Brown
     [not found] ` <1390553044-11860-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-24  8:43   ` [PATCH v3 08/14] spi: rspi: Add support for more than one interrupt Geert Uytterhoeven
2014-01-24  8:43     ` Geert Uytterhoeven
2014-01-24  8:43     ` Geert Uytterhoeven
2014-01-27 20:05     ` Mark Brown
2014-01-24  8:44   ` [PATCH v2 11/14] spi: rspi: Convert to clk_prepare_enable/disable_unprepare Geert Uytterhoeven
2014-01-24  8:44     ` Geert Uytterhoeven
2014-01-24  8:44     ` Geert Uytterhoeven
2014-01-27 20:08     ` Mark Brown
2014-01-24  8:44 ` [PATCH v2 12/14] spi: rspi: Use NULL as the clock ID Geert Uytterhoeven
2014-01-24  8:44   ` Geert Uytterhoeven
2014-01-27 20:08   ` Mark Brown
2014-01-24  8:44 ` [PATCH v4 13/14] spi: rspi: Add DT support Geert Uytterhoeven
2014-01-24  8:44   ` Geert Uytterhoeven
2014-01-24  9:33   ` Mark Rutland
     [not found]     ` <20140124093349.GK15586-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2014-01-24 13:05       ` Geert Uytterhoeven
2014-01-24 13:05         ` Geert Uytterhoeven
2014-01-24 13:05         ` Geert Uytterhoeven
2014-01-27 20:11   ` Mark Brown
2014-01-24  8:44 ` [PATCH 14/14] spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI Geert Uytterhoeven
2014-01-24  8:44   ` Geert Uytterhoeven
2014-01-27 20:27   ` Mark Brown
2014-01-24  8:43 [PATCH 09/14] spi: rspi: Add support for RSPI on RZ/A1H Geert Uytterhoeven
2014-01-24  8:43 ` Geert Uytterhoeven
2014-01-27 20:07 ` Mark Brown
2014-01-27 20:07   ` Mark Brown

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.