linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
@ 2012-08-14 13:49 Richard Genoud
  2012-08-14 13:49 ` [PATCH 01/23] of: add dma-mask binding Richard Genoud
                   ` (24 more replies)
  0 siblings, 25 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based
on your and Jean-Christophe work.
You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.

The goal of this patchset is to share the work I've done, it's not ready
for upstream, but it may save some time.

It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.

Best Regards,
Richard.

Jean-Christophe PLAGNIOL-VILLARD (3):
  of: add dma-mask binding
  of_spi: add generic binding support to specify cs gpio
  spi/atmel: add DT support

Nicolas Ferre (6):
  spi/atmel_spi: trivial: change some comments
  spi/atmel_spi: add physical base address
  spi/atmel_spi: call unmapping on transfers buffers
  spi/atmel_spi: status information passed through controller data
  spi/atmel_spi: add flag to controller data for lock operations
  spi/atmel_spi: add dmaengine support

Richard Genoud (14):
  spi-atmel: update with dmaengine interface
  spi-atmel: fix __init/__devinit sections mismatch
  spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
  AT91 DMA OF support
  add at91sam9x5 Kconfig ARCH/SOC link
  spi-atmel: add DMA OF support
  [BUG] SPI: array out of bound => no CS
  [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes
  sam9x5: declare SPI clocks
  spi-atmel: add sam9x5 SPI in device tree
  spi-atmel: add dma support in sam9x5 device tree
  spi-atmel OF: complete documentation
  spi-atmel: complete DMA slave OF documentation
  sam9x5ek DTS: enable SPI dataflash

 Documentation/devicetree/bindings/spi/spi-bus.txt  |    6 +
 .../devicetree/bindings/spi/spi_atmel.txt          |   46 ++
 arch/arm/boot/dts/at91sam9x5.dtsi                  |   42 ++
 arch/arm/boot/dts/at91sam9x5ek.dtsi                |   10 +
 arch/arm/mach-at91/Kconfig                         |    4 +
 arch/arm/mach-at91/at91sam9x5.c                    |    3 +
 arch/arm/mach-at91/include/mach/at_hdmac.h         |    1 +
 drivers/of/Kconfig                                 |    4 +
 drivers/of/Makefile                                |    1 +
 drivers/of/of_atmel.c                              |  111 ++++
 drivers/of/platform.c                              |   23 +-
 drivers/spi/Kconfig                                |    9 +
 drivers/spi/spi-atmel.c                            |  611 ++++++++++++++++++--
 drivers/spi/spi.c                                  |   55 ++-
 include/linux/of_atmel.h                           |   29 +
 include/linux/spi/spi.h                            |    3 +
 16 files changed, 914 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt
 create mode 100644 drivers/of/of_atmel.c
 create mode 100644 include/linux/of_atmel.h

-- 
1.7.2.5

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

* [PATCH 01/23] of: add dma-mask binding
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 02/23] of_spi: add generic binding support to specify cs gpio Richard Genoud
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

This will allow each device to specify its dma-mask for this we use the
coherent_dma_mask as pointer. By default the dma-mask will be set to
DMA_BIT_MASK(32).
The microblaze architecture hook is drop

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/of/platform.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e44f8c2..11c765c 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -121,6 +121,21 @@ void of_device_make_bus_id(struct device *dev)
 	dev_set_name(dev, "%s.%d", node->name, magic - 1);
 }
 
+static void of_get_dma_mask(struct device *dev, struct device_node *np)
+{
+	const __be32 *prop;
+	int len;
+
+	prop = of_get_property(np, "dma-mask", &len);
+
+	dev->dma_mask = &dev->coherent_dma_mask;
+
+	if (!prop)
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+	else
+		dev->coherent_dma_mask = of_read_number(prop, len / 4);
+}
+
 /**
  * of_device_alloc - Allocate and initialize an of_device
  * @np: device node to assign to device
@@ -161,10 +176,8 @@ struct platform_device *of_device_alloc(struct device_node *np,
 		WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
 	}
 
+	of_get_dma_mask(&dev->dev, np);
 	dev->dev.of_node = of_node_get(np);
-#if defined(CONFIG_MICROBLAZE)
-	dev->dev.dma_mask = &dev->archdata.dma_mask;
-#endif
 	dev->dev.parent = parent;
 
 	if (bus_id)
@@ -201,10 +214,6 @@ struct platform_device *of_platform_device_create_pdata(
 	if (!dev)
 		return NULL;
 
-#if defined(CONFIG_MICROBLAZE)
-	dev->archdata.dma_mask = 0xffffffffUL;
-#endif
-	dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
 
-- 
1.7.2.5

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

* [PATCH 02/23] of_spi: add generic binding support to specify cs gpio
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
  2012-08-14 13:49 ` [PATCH 01/23] of: add dma-mask binding Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 03/23] spi/atmel_spi: trivial: change some comments Richard Genoud
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

This will allow to use gpio for chip select with no modification in the
driver binding

When use the cs-gpios, the gpio number will be passed via the cs_gpio field
and the number of chip select will automatically increased.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: devicetree-discuss at lists.ozlabs.org
Cc: spi-devel-general at lists.sourceforge.net
---
 Documentation/devicetree/bindings/spi/spi-bus.txt |    6 ++
 drivers/spi/spi.c                                 |   55 +++++++++++++++++++-
 include/linux/spi/spi.h                           |    3 +
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index e782add..c253379 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -12,6 +12,7 @@ The SPI master node requires the following properties:
 - #size-cells     - should be zero.
 - compatible      - name of SPI bus controller following generic names
     		recommended practice.
+- cs-gpios	  - (optional) gpios chip select.
 No other properties are required in the SPI bus node.  It is assumed
 that a driver for an SPI bus device will understand that it is an SPI bus.
 However, the binding does not attempt to define the specific method for
@@ -21,6 +22,8 @@ assumption that board specific platform code will be used to manage
 chip selects.  Individual drivers can define additional properties to
 support describing the chip select layout.
 
+If cs-gpios is used the number of chip select will automatically increased.
+
 SPI slave nodes must be children of the SPI master node and can
 contain the following properties.
 - reg             - (required) chip select address of device.
@@ -34,6 +37,9 @@ contain the following properties.
 - spi-cs-high     - (optional) Empty property indicating device requires
     		chip select active high
 
+If a gpio chipselect is used for the SPI slave the gpio number will be passed
+via the controller_data
+
 SPI example for an MPC5200 SPI bus:
 	spi at f00 {
 		#address-cells = <1>;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 84c2861..3fb5b6d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
+#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
 #include <linux/sched.h>
@@ -327,6 +328,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)
 	spi->dev.parent = &master->dev;
 	spi->dev.bus = &spi_bus_type;
 	spi->dev.release = spidev_release;
+	spi->cs_gpio = -EINVAL;
 	device_initialize(&spi->dev);
 	return spi;
 }
@@ -344,15 +346,16 @@ EXPORT_SYMBOL_GPL(spi_alloc_device);
 int spi_add_device(struct spi_device *spi)
 {
 	static DEFINE_MUTEX(spi_add_lock);
-	struct device *dev = spi->master->dev.parent;
+	struct spi_master *master = spi->master;
+	struct device *dev = master->dev.parent;
 	struct device *d;
 	int status;
 
 	/* Chipselects are numbered 0..max; validate. */
-	if (spi->chip_select >= spi->master->num_chipselect) {
+	if (spi->chip_select >= master->num_chipselect) {
 		dev_err(dev, "cs%d >= max %d\n",
 			spi->chip_select,
-			spi->master->num_chipselect);
+			master->num_chipselect);
 		return -EINVAL;
 	}
 
@@ -376,6 +379,9 @@ int spi_add_device(struct spi_device *spi)
 		goto done;
 	}
 
+	if (master->cs_gpios)
+		spi->cs_gpio = master->cs_gpios[spi->chip_select];
+
 	/* Drivers may modify this initial i/o setup, but will
 	 * normally rely on the device being setup.  Devices
 	 * using SPI_CS_HIGH can't coexist well otherwise...
@@ -946,6 +952,45 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
 }
 EXPORT_SYMBOL_GPL(spi_alloc_master);
 
+#ifdef CONFIG_OF
+static int of_spi_register_master(struct spi_master *master)
+{
+	int nb, i;
+	int *cs;
+	struct device_node *np = master->dev.of_node;
+
+	if (!np)
+		return 0;
+
+	nb = of_gpio_named_count(np, "cs-gpios");
+
+	if (nb < 1)
+		return 0;
+
+	cs = devm_kzalloc(&master->dev,
+			  sizeof(int) * (master->num_chipselect + nb),
+			  GFP_KERNEL);
+	master->cs_gpios = cs;
+
+	if (!master->cs_gpios)
+		return -ENOMEM;
+
+	memset(cs, -EINVAL, master->num_chipselect);
+	master->num_chipselect += nb;
+	cs += master->num_chipselect;
+
+	for (i = 0; i < nb; i++)
+		cs[i] = of_get_named_gpio(np, "cs-gpios", i);
+
+	return 0;
+}
+#else
+static int of_spi_register_master(struct spi_master *master)
+{
+	return 0;
+}
+#endif
+
 /**
  * spi_register_master - register SPI master controller
  * @master: initialized master, originally from spi_alloc_master()
@@ -977,6 +1022,10 @@ int spi_register_master(struct spi_master *master)
 	if (!dev)
 		return -ENODEV;
 
+	status = of_spi_register_master(master);
+	if (status)
+		return status;
+
 	/* even if it's just one always-selected device, there must
 	 * be@least one chipselect
 	 */
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index fa702ae..f629189 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -90,6 +90,7 @@ struct spi_device {
 	void			*controller_state;
 	void			*controller_data;
 	char			modalias[SPI_NAME_SIZE];
+	int			cs_gpio;	/* chip select gpio */
 
 	/*
 	 * likely need more hooks for more protocol options affecting how
@@ -362,6 +363,8 @@ struct spi_master {
 	int (*transfer_one_message)(struct spi_master *master,
 				    struct spi_message *mesg);
 	int (*unprepare_transfer_hardware)(struct spi_master *master);
+	/* gpio chip select */
+	int			*cs_gpios;
 };
 
 static inline void *spi_master_get_devdata(struct spi_master *master)
-- 
1.7.2.5

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

* [PATCH 03/23] spi/atmel_spi: trivial: change some comments
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
  2012-08-14 13:49 ` [PATCH 01/23] of: add dma-mask binding Richard Genoud
  2012-08-14 13:49 ` [PATCH 02/23] of_spi: add generic binding support to specify cs gpio Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 04/23] spi/atmel_spi: add physical base address Richard Genoud
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

To be accurate with introduction of dmaengine enabled driver.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/spi-atmel.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 16d6a83..7c41b07 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -201,6 +201,7 @@ struct atmel_spi {
 	struct spi_transfer	*next_transfer;
 	unsigned long		next_remaining_bytes;
 
+	/* scratch buffer */
 	void			*buffer;
 	dma_addr_t		buffer_dma;
 };
@@ -364,7 +365,7 @@ static void atmel_spi_next_xfer_data(struct spi_master *master,
 }
 
 /*
- * Submit next transfer for DMA.
+ * Submit next transfer for PDC.
  * lock is held, spi irq is blocked
  */
 static void atmel_spi_next_xfer(struct spi_master *master,
-- 
1.7.2.5

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

* [PATCH 04/23] spi/atmel_spi: add physical base address
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (2 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 03/23] spi/atmel_spi: trivial: change some comments Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 05/23] spi/atmel_spi: call unmapping on transfers buffers Richard Genoud
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

Needed for future use with dmaengine enabled driver.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/spi-atmel.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 7c41b07..a83f470 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -188,6 +188,7 @@
 struct atmel_spi {
 	spinlock_t		lock;
 
+	resource_size_t		phybase;
 	void __iomem		*regs;
 	int			irq;
 	struct clk		*clk;
@@ -962,6 +963,7 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 	as->regs = ioremap(regs->start, resource_size(regs));
 	if (!as->regs)
 		goto out_free_buffer;
+	as->phybase = regs->start;
 	as->irq = irq;
 	as->clk = clk;
 
-- 
1.7.2.5

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

* [PATCH 05/23] spi/atmel_spi: call unmapping on transfers buffers
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (3 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 04/23] spi/atmel_spi: add physical base address Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 06/23] spi/atmel_spi: status information passed through controller data Richard Genoud
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/spi-atmel.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index a83f470..39285ef 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1011,6 +1011,7 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)
 	struct spi_master	*master = platform_get_drvdata(pdev);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 	struct spi_message	*msg;
+	struct spi_transfer	*xfer;
 
 	/* reset the hardware and block queue progress */
 	spin_lock_irq(&as->lock);
@@ -1022,9 +1023,10 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)
 
 	/* Terminate remaining queued transfers */
 	list_for_each_entry(msg, &as->queue, queue) {
-		/* REVISIT unmapping the dma is a NOP on ARM and AVR32
-		 * but we shouldn't depend on that...
-		 */
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			if (!msg->is_dma_mapped)
+				atmel_spi_dma_unmap_xfer(master, xfer);
+		}
 		msg->status = -ESHUTDOWN;
 		msg->complete(msg->context);
 	}
-- 
1.7.2.5

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

* [PATCH 06/23] spi/atmel_spi: status information passed through controller data
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (4 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 05/23] spi/atmel_spi: call unmapping on transfers buffers Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 07/23] spi/atmel_spi: add flag to controller data for lock operations Richard Genoud
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

The status of transfer is stored in controller data structure
so that it can be used not only by atmel_spi_msg_done() function.
This will be useful for upcoming dmaengine enabled driver.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/spi-atmel.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 39285ef..49a7f4f 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -201,6 +201,7 @@ struct atmel_spi {
 	unsigned long		current_remaining_bytes;
 	struct spi_transfer	*next_transfer;
 	unsigned long		next_remaining_bytes;
+	int			done_status;
 
 	/* scratch buffer */
 	void			*buffer;
@@ -545,15 +546,15 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
 
 static void
 atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
-		struct spi_message *msg, int status, int stay)
+		struct spi_message *msg, int stay)
 {
-	if (!stay || status < 0)
+	if (!stay || as->done_status < 0)
 		cs_deactivate(as, msg->spi);
 	else
 		as->stay = msg->spi;
 
 	list_del(&msg->queue);
-	msg->status = status;
+	msg->status = as->done_status;
 
 	dev_dbg(master->dev.parent,
 		"xfer complete: %u bytes transferred\n",
@@ -565,6 +566,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
 
 	as->current_transfer = NULL;
 	as->next_transfer = NULL;
+	as->done_status = 0;
 
 	/* continue if needed */
 	if (list_empty(&as->queue) || as->stopping)
@@ -642,7 +644,8 @@ atmel_spi_interrupt(int irq, void *dev_id)
 		/* Clear any overrun happening while cleaning up */
 		spi_readl(as, SR);
 
-		atmel_spi_msg_done(master, as, msg, -EIO, 0);
+		as->done_status = -EIO;
+		atmel_spi_msg_done(master, as, msg, 0);
 	} else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) {
 		ret = IRQ_HANDLED;
 
@@ -660,7 +663,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
 
 			if (atmel_spi_xfer_is_last(msg, xfer)) {
 				/* report completed message */
-				atmel_spi_msg_done(master, as, msg, 0,
+				atmel_spi_msg_done(master, as, msg,
 						xfer->cs_change);
 			} else {
 				if (xfer->cs_change) {
-- 
1.7.2.5

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

* [PATCH 07/23] spi/atmel_spi: add flag to controller data for lock operations
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (5 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 06/23] spi/atmel_spi: status information passed through controller data Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 08/23] spi/atmel: add DT support Richard Genoud
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

Will allow to drop the lock during DMA operations.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/spi-atmel.c |   31 +++++++++++++++++++------------
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 49a7f4f..70f7bfa 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -187,6 +187,7 @@
  */
 struct atmel_spi {
 	spinlock_t		lock;
+	unsigned long		flags;
 
 	resource_size_t		phybase;
 	void __iomem		*regs;
@@ -324,6 +325,16 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
 		gpio_set_value(asd->npcs_pin, !active);
 }
 
+static void atmel_spi_lock(struct atmel_spi *as)
+{
+		spin_lock_irqsave(&as->lock, as->flags);
+}
+
+static void atmel_spi_unlock(struct atmel_spi *as)
+{
+		spin_unlock_irqrestore(&as->lock, as->flags);
+}
+
 static inline int atmel_spi_xfer_is_last(struct spi_message *msg,
 					struct spi_transfer *xfer)
 {
@@ -560,9 +571,9 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
 		"xfer complete: %u bytes transferred\n",
 		msg->actual_length);
 
-	spin_unlock(&as->lock);
+	atmel_spi_unlock(as);
 	msg->complete(msg->context);
-	spin_lock(&as->lock);
+	atmel_spi_lock(as);
 
 	as->current_transfer = NULL;
 	as->next_transfer = NULL;
@@ -789,13 +800,11 @@ static int atmel_spi_setup(struct spi_device *spi)
 		spi->controller_state = asd;
 		gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH));
 	} else {
-		unsigned long		flags;
-
-		spin_lock_irqsave(&as->lock, flags);
+		atmel_spi_lock(as);
 		if (as->stay == spi)
 			as->stay = NULL;
 		cs_deactivate(as, spi);
-		spin_unlock_irqrestore(&as->lock, flags);
+		atmel_spi_unlock(as);
 	}
 
 	asd->csr = csr;
@@ -814,7 +823,6 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
 {
 	struct atmel_spi	*as;
 	struct spi_transfer	*xfer;
-	unsigned long		flags;
 	struct device		*controller = spi->master->dev.parent;
 	u8			bits;
 	struct atmel_spi_device	*asd;
@@ -879,11 +887,11 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
 	msg->status = -EINPROGRESS;
 	msg->actual_length = 0;
 
-	spin_lock_irqsave(&as->lock, flags);
+	atmel_spi_lock(as);
 	list_add_tail(&msg->queue, &as->queue);
 	if (!as->current_transfer)
 		atmel_spi_next_message(spi->master);
-	spin_unlock_irqrestore(&as->lock, flags);
+	atmel_spi_unlock(as);
 
 	return 0;
 }
@@ -893,17 +901,16 @@ static void atmel_spi_cleanup(struct spi_device *spi)
 	struct atmel_spi	*as = spi_master_get_devdata(spi->master);
 	struct atmel_spi_device	*asd = spi->controller_state;
 	unsigned		gpio = (unsigned) spi->controller_data;
-	unsigned long		flags;
 
 	if (!asd)
 		return;
 
-	spin_lock_irqsave(&as->lock, flags);
+	atmel_spi_lock(as);
 	if (as->stay == spi) {
 		as->stay = NULL;
 		cs_deactivate(as, spi);
 	}
-	spin_unlock_irqrestore(&as->lock, flags);
+	atmel_spi_unlock(as);
 
 	spi->controller_state = NULL;
 	gpio_free(gpio);
-- 
1.7.2.5

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

* [PATCH 08/23] spi/atmel: add DT support
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (6 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 07/23] spi/atmel_spi: add flag to controller data for lock operations Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 09/23] spi/atmel_spi: add dmaengine support Richard Genoud
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

The atmel_spi use only gpio for chip select.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: devicetree-discuss at lists.ozlabs.org
Cc: spi-devel-general at lists.sourceforge.net
---
 .../devicetree/bindings/spi/spi_atmel.txt          |    6 +++++
 drivers/spi/spi-atmel.c                            |   21 ++++++++++++++++---
 2 files changed, 23 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt

diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt
new file mode 100644
index 0000000..7ec3d8d
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi_atmel.txt
@@ -0,0 +1,6 @@
+Atmel SPI device
+
+Required properties:
+- compatible : should be "atmel,at91rm9200-spi".
+- reg: Address and length of the register set for the device
+- interrupts: Should contain macb interrupt
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 70f7bfa..ad47b6d 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 
 #include <asm/io.h>
 #include <mach/board.h>
@@ -711,7 +712,7 @@ static int atmel_spi_setup(struct spi_device *spi)
 	u32			scbr, csr;
 	unsigned int		bits = spi->bits_per_word;
 	unsigned long		bus_hz;
-	unsigned int		npcs_pin;
+	int			npcs_pin;
 	int			ret;
 
 	as = spi_master_get_devdata(spi->master);
@@ -783,7 +784,9 @@ static int atmel_spi_setup(struct spi_device *spi)
 	csr |= SPI_BF(DLYBCT, 0);
 
 	/* chipselect must have been muxed as GPIO (e.g. in board setup) */
-	npcs_pin = (unsigned int)spi->controller_data;
+	if (!gpio_is_valid(spi->cs_gpio))
+		spi->cs_gpio = (int)spi->controller_data;
+	npcs_pin = spi->cs_gpio;
 	asd = spi->controller_state;
 	if (!asd) {
 		asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL);
@@ -900,7 +903,7 @@ static void atmel_spi_cleanup(struct spi_device *spi)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(spi->master);
 	struct atmel_spi_device	*asd = spi->controller_state;
-	unsigned		gpio = (unsigned) spi->controller_data;
+	unsigned		gpio = spi->cs_gpio;
 
 	if (!asd)
 		return;
@@ -950,7 +953,8 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
 	master->bus_num = pdev->id;
-	master->num_chipselect = 4;
+	master->dev.of_node = pdev->dev.of_node;
+	master->num_chipselect = master->dev.of_node ? 0 : 4;
 	master->setup = atmel_spi_setup;
 	master->transfer = atmel_spi_transfer;
 	master->cleanup = atmel_spi_cleanup;
@@ -1079,11 +1083,20 @@ static int atmel_spi_resume(struct platform_device *pdev)
 #define	atmel_spi_resume	NULL
 #endif
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_spi_dt_ids[] = {
+	{ .compatible = "atmel,at91rm9200-spi" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids);
+#endif
 
 static struct platform_driver atmel_spi_driver = {
 	.driver		= {
 		.name	= "atmel_spi",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_spi_dt_ids),
 	},
 	.suspend	= atmel_spi_suspend,
 	.resume		= atmel_spi_resume,
-- 
1.7.2.5

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

* [PATCH 09/23] spi/atmel_spi: add dmaengine support
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (7 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 08/23] spi/atmel: add DT support Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 10/23] spi-atmel: update with dmaengine interface Richard Genoud
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicolas Ferre <nicolas.ferre@atmel.com>

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/spi/Kconfig     |    9 +
 drivers/spi/spi-atmel.c |  483 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 482 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 5f84b55..169592a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -74,6 +74,15 @@ config SPI_ATMEL
 	  This selects a driver for the Atmel SPI Controller, present on
 	  many AT32 (AVR32) and AT91 (ARM) chips.
 
+config SPI_ATMEL_DMA
+	bool "Atmel SPI DMA support"
+	depends on SPI_ATMEL && (ARCH_AT91SAM9G45 || ARCH_AT91SAM9X5) && DMA_ENGINE && EXPERIMENTAL
+	default y
+	help
+	  Say Y here if you want the Atmel SPI driver to use the DMA engine. Data transfers
+	  will be handled by the DMA controller: it will increase throughput and reduce
+	  CPU utilization.
+
 config SPI_BFIN5XX
 	tristate "SPI controller driver for ADI Blackfin5xx"
 	depends on BLACKFIN
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index ad47b6d..9456fca 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
@@ -25,6 +26,7 @@
 #include <mach/board.h>
 #include <asm/gpio.h>
 #include <mach/cpu.h>
+#include <mach/at_hdmac.h>
 
 /* SPI register offsets */
 #define SPI_CR					0x0000
@@ -181,6 +183,22 @@
 	__raw_writel((value), (port)->regs + SPI_##reg)
 
 
+#if defined(CONFIG_SPI_ATMEL_DMA)
+/* use PIO for small transfers, avoiding DMA setup/teardown overhead and
+ * cache operations; better heuristics consider wordsize and bitrate.
+ */
+#define DMA_MIN_BYTES	16
+
+struct atmel_spi_dma {
+	struct dma_chan			*chan_rx;
+	struct dma_chan			*chan_tx;
+	struct scatterlist		sgrx;
+	struct scatterlist		sgtx;
+	struct dma_async_tx_descriptor	*data_desc_rx;
+	struct dma_async_tx_descriptor	*data_desc_tx;
+};
+#endif
+
 /*
  * The core SPI transfer engine just talks to a register bank to set up
  * DMA transfers; transfer queue progress is driven by IRQs.  The clock
@@ -199,6 +217,7 @@ struct atmel_spi {
 
 	u8			stopping;
 	struct list_head	queue;
+	struct tasklet_struct	tasklet;
 	struct spi_transfer	*current_transfer;
 	unsigned long		current_remaining_bytes;
 	struct spi_transfer	*next_transfer;
@@ -208,6 +227,11 @@ struct atmel_spi {
 	/* scratch buffer */
 	void			*buffer;
 	dma_addr_t		buffer_dma;
+
+#if defined(CONFIG_SPI_ATMEL_DMA)
+	/* dmaengine data */
+	struct atmel_spi_dma	dma;
+#endif
 };
 
 /* Controller-specific per-slave state */
@@ -336,6 +360,17 @@ static void atmel_spi_unlock(struct atmel_spi *as)
 		spin_unlock_irqrestore(&as->lock, as->flags);
 }
 
+static inline bool atmel_spi_use_dma(struct spi_transfer *xfer)
+{
+#if defined(CONFIG_SPI_ATMEL_DMA)
+	if (xfer->len < DMA_MIN_BYTES)
+		return false;
+	return true;
+#else
+	return false;
+#endif
+}
+
 static inline int atmel_spi_xfer_is_last(struct spi_message *msg,
 					struct spi_transfer *xfer)
 {
@@ -347,6 +382,258 @@ static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer)
 	return xfer->delay_usecs == 0 && !xfer->cs_change;
 }
 
+#if defined(CONFIG_SPI_ATMEL_DMA)
+static bool __init filter(struct dma_chan *chan, void *slave)
+{
+	struct	at_dma_slave		*sl = slave;
+
+	if (sl->dma_dev == chan->device->dev) {
+		chan->private = sl;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+static int __init atmel_spi_configure_dma(struct spi_master *master)
+{
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+	struct device		*controller = master->dev.parent;
+	struct at_dma_slave	*sdata;
+
+	sdata = controller->platform_data;
+
+	if (sdata && sdata->dma_dev) {
+		dma_cap_mask_t mask;
+
+		/* setup DMA addresses */
+		sdata->rx_reg = (dma_addr_t)as->phybase + SPI_RDR;
+		sdata->tx_reg = (dma_addr_t)as->phybase + SPI_TDR;
+
+		/* Try to grab two DMA channels */
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+		as->dma.chan_tx = dma_request_channel(mask, filter, sdata);
+		if (as->dma.chan_tx)
+			as->dma.chan_rx = dma_request_channel(mask, filter, sdata);
+	}
+	if (!as->dma.chan_rx || !as->dma.chan_tx) {
+		if (as->dma.chan_rx)
+			dma_release_channel(as->dma.chan_rx);
+		if (as->dma.chan_tx)
+			dma_release_channel(as->dma.chan_tx);
+		dev_err(&as->pdev->dev, "DMA channel not available, "
+					"unable to use SPI\n");
+		return -EBUSY;
+	}
+
+	dev_info(&as->pdev->dev, "Using %s (tx) and "
+				" %s (rx) for DMA transfers\n",
+				dma_chan_name(as->dma.chan_tx),
+				dma_chan_name(as->dma.chan_rx));
+
+	return 0;
+}
+
+static void atmel_spi_stop_dma(struct atmel_spi *as)
+{
+	if (as->dma.chan_rx)
+		as->dma.chan_rx->device->device_control(as->dma.chan_rx,
+							DMA_TERMINATE_ALL, 0);
+	if (as->dma.chan_tx)
+		as->dma.chan_tx->device->device_control(as->dma.chan_tx,
+							DMA_TERMINATE_ALL, 0);
+}
+
+static void atmel_spi_release_dma(struct atmel_spi *as)
+{
+	if (as->dma.chan_rx)
+		dma_release_channel(as->dma.chan_rx);
+	if (as->dma.chan_tx)
+		dma_release_channel(as->dma.chan_tx);
+}
+
+/* This function is called by the DMA driver from tasklet context */
+static void dma_callback(void *data)
+{
+	struct spi_master	*master = data;
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+
+	/* trigger SPI tasklet */
+	tasklet_schedule(&as->tasklet);
+}
+
+/*
+ * Next transfer using PIO.
+ * lock is held, spi tasklet is blocked
+ */
+static void atmel_spi_next_xfer_pio(struct spi_master *master,
+				struct spi_transfer *xfer)
+{
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+
+	dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_pio\n");
+
+	as->current_remaining_bytes = xfer->len;
+
+	/* Make sure data is not remaining in RDR */
+	spi_readl(as, RDR);
+	while (spi_readl(as, SR) & SPI_BIT(RDRF)) {
+		spi_readl(as, RDR);
+		cpu_relax();
+	}
+
+	if (xfer->tx_buf)
+		spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
+	else
+		spi_writel(as, TDR, 0);
+
+	dev_dbg(master->dev.parent,
+		"  start pio xfer %p: len %u tx %p rx %p\n",
+		xfer, xfer->len, xfer->tx_buf, xfer->rx_buf);
+
+	/* Enable relevant interrupts */
+	spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES));
+}
+
+/*
+ * Submit next transfer for DMA.
+ * lock is held, spi tasklet is blocked
+ */
+static int atmel_spi_next_xfer_dma(struct spi_master *master,
+				struct spi_transfer *xfer)
+{
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+	struct dma_chan		*rxchan = as->dma.chan_rx;
+	struct dma_chan		*txchan = as->dma.chan_tx;
+	struct dma_async_tx_descriptor *rxdesc;
+	struct dma_async_tx_descriptor *txdesc;
+	dma_cookie_t		cookie;
+
+	dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma\n");
+
+	/* Check that the channels are available */
+	if (!rxchan || !txchan)
+		return -ENODEV;
+
+	/* release lock for DMA operations */
+	atmel_spi_unlock(as);
+
+	/* prepare the RX dma transfer */
+	sg_init_table(&as->dma.sgrx, 1);
+	sg_dma_len(&as->dma.sgrx) = xfer->len;
+	if (xfer->rx_buf)
+		as->dma.sgrx.dma_address = xfer->rx_dma;
+	else
+		as->dma.sgrx.dma_address = as->buffer_dma;
+
+	/* prepare the TX dma transfer */
+	sg_init_table(&as->dma.sgtx, 1);
+	sg_dma_len(&as->dma.sgtx) = xfer->len;
+	if (xfer->tx_buf) {
+		as->dma.sgtx.dma_address = xfer->tx_dma;
+	} else {
+		as->dma.sgtx.dma_address = as->buffer_dma;
+		memset(as->buffer, 0, xfer->len);
+	}
+
+	/* Send both scatterlists */
+	rxdesc = rxchan->device->device_prep_slave_sg(rxchan,
+					&as->dma.sgrx,
+					1,
+					DMA_FROM_DEVICE,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!rxdesc)
+		goto err_dma;
+
+	txdesc = txchan->device->device_prep_slave_sg(txchan,
+					&as->dma.sgtx,
+					1,
+					DMA_TO_DEVICE,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!txdesc)
+		goto err_dma;
+
+	dev_dbg(master->dev.parent,
+		"  start dma xfer %p: len %u tx %p/%08x rx %p/%08x\n",
+		xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
+		xfer->rx_buf, xfer->rx_dma);
+
+	/* Enable relevant interrupts */
+	spi_writel(as, IER, SPI_BIT(OVRES));
+
+	/* Put the callback on the RX transfer only, that should finish last */
+	rxdesc->callback = dma_callback;
+	rxdesc->callback_param = master;
+
+	/* Submit and fire RX and TX with TX last so we're ready to read! */
+	cookie = rxdesc->tx_submit(rxdesc);
+	if (dma_submit_error(cookie))
+		goto err_dma;
+	cookie = txdesc->tx_submit(txdesc);
+	if (dma_submit_error(cookie))
+		goto err_dma;
+	rxchan->device->device_issue_pending(rxchan);
+	txchan->device->device_issue_pending(txchan);
+
+	/* take back lock */
+	atmel_spi_lock(as);
+	return 0;
+
+err_dma:
+	spi_writel(as, IDR, SPI_BIT(OVRES));
+	atmel_spi_stop_dma(as);
+	atmel_spi_lock(as);
+	return -ENOMEM;
+}
+
+/*
+ * Choose way to submit next transfer and start it.
+ * lock is held, spi tasklet is blocked
+ */
+static void atmel_spi_next_xfer(struct spi_master *master,
+				struct spi_message *msg)
+{
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+	struct spi_transfer	*xfer;
+
+	dev_vdbg(&msg->spi->dev, "atmel_spi_next_xfer\n");
+
+	if (!as->current_transfer)
+		xfer = list_entry(msg->transfers.next,
+				struct spi_transfer, transfer_list);
+	else
+		xfer = list_entry(as->current_transfer->transfer_list.next,
+				struct spi_transfer, transfer_list);
+
+	as->current_transfer = xfer;
+
+	if (atmel_spi_use_dma(xfer)) {
+		if (!atmel_spi_next_xfer_dma(master, xfer))
+			return;
+		else
+			dev_err(&msg->spi->dev, "unable to use DMA, fallback to PIO\n");
+	}
+
+	/* use PIO if xfer is short or error appened using DMA */
+	atmel_spi_next_xfer_pio(master, xfer);
+}
+
+static void atmel_spi_disable_dma_irq(struct atmel_spi *as) {}
+#else
+static void atmel_spi_disable_dma_irq(struct atmel_spi *as)
+{
+	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+}
+
+static int __init atmel_spi_configure_dma(struct spi_master *master)
+{
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+
+	atmel_spi_disable_dma_irq(as);
+	return 0;
+}
+
 static void atmel_spi_next_xfer_data(struct spi_master *master,
 				struct spi_transfer *xfer,
 				dma_addr_t *tx_dma,
@@ -479,6 +766,10 @@ static void atmel_spi_next_xfer(struct spi_master *master,
 	spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
 }
 
+static void atmel_spi_stop_dma(struct atmel_spi *as) {}
+static void atmel_spi_release_dma(struct atmel_spi *as) {}
+#endif
+
 static void atmel_spi_next_message(struct spi_master *master)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(master);
@@ -582,11 +873,175 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
 
 	/* continue if needed */
 	if (list_empty(&as->queue) || as->stopping)
-		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+		atmel_spi_disable_dma_irq(as);
 	else
 		atmel_spi_next_message(master);
 }
 
+#if defined(CONFIG_SPI_ATMEL_DMA)
+/* Called from IRQ
+ * lock is held
+ *
+ * Must update "current_remaining_bytes" to keep track of data
+ * to transfer.
+ */
+static void
+atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)
+{
+	u8		*txp;
+	u8		*rxp;
+	unsigned long	xfer_pos = xfer->len - as->current_remaining_bytes;
+
+	if (xfer->rx_buf) {
+		rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
+		*rxp = spi_readl(as, RDR);
+	} else {
+		spi_readl(as, RDR);
+	}
+
+	as->current_remaining_bytes--;
+
+	if (as->current_remaining_bytes) {
+		if (xfer->tx_buf) {
+			txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
+			spi_writel(as, TDR, *txp);
+		} else {
+			spi_writel(as, TDR, 0);
+		}
+	}
+}
+
+/* Tasklet
+ * Called from DMA callback + pio transfer and overrun IRQ.
+ */
+static void atmel_spi_tasklet_func(unsigned long data)
+{
+	struct spi_master	*master = (struct spi_master *)data;
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+	struct spi_message	*msg;
+	struct spi_transfer	*xfer;
+
+	dev_vdbg(master->dev.parent, "atmel_spi_tasklet_func\n");
+
+	atmel_spi_lock(as);
+
+	xfer = as->current_transfer;
+
+	if (xfer == NULL)
+		/* already been there */
+		goto tasklet_out;
+
+	msg = list_entry(as->queue.next, struct spi_message, queue);
+
+	if (as->done_status < 0) {
+		/* error happened (overrun) */
+		if (atmel_spi_use_dma(xfer))
+			atmel_spi_stop_dma(as);
+	} else {
+		/* only update length if no error */
+		msg->actual_length += xfer->len;
+	}
+
+	if (atmel_spi_use_dma(xfer)) {
+		if (!msg->is_dma_mapped)
+			atmel_spi_dma_unmap_xfer(master, xfer);
+	}
+
+	if (xfer->delay_usecs)
+		udelay(xfer->delay_usecs);
+
+	if (atmel_spi_xfer_is_last(msg, xfer) || as->done_status < 0) {
+		/* report completed (or erroneous) message */
+		atmel_spi_msg_done(master, as, msg, xfer->cs_change);
+	} else {
+		if (xfer->cs_change) {
+			cs_deactivate(as, msg->spi);
+			udelay(1);
+			cs_activate(as, msg->spi);
+		}
+
+		/*
+		 * Not done yet. Submit the next transfer.
+		 *
+		 * FIXME handle protocol options for xfer
+		 */
+		atmel_spi_next_xfer(master, msg);
+	}
+
+tasklet_out:
+	atmel_spi_unlock(as);
+}
+
+
+/* Interrupt with DMA engine management
+ *
+ * No need for locking in this Interrupt handler: done_status is the
+ * only information modified. What we need is the update of this field
+ * before tasklet runs. This is ensured by using barrier.
+ */
+static irqreturn_t
+atmel_spi_interrupt(int irq, void *dev_id)
+{
+	struct spi_master	*master = dev_id;
+	struct atmel_spi	*as = spi_master_get_devdata(master);
+	u32			status, pending, imr;
+	struct spi_transfer	*xfer;
+	int			ret = IRQ_NONE;
+
+	imr = spi_readl(as, IMR);
+	status = spi_readl(as, SR);
+	pending = status & imr;
+
+	if (pending & SPI_BIT(OVRES)) {
+		ret = IRQ_HANDLED;
+		spi_writel(as, IDR, SPI_BIT(OVRES));
+		dev_warn(master->dev.parent, "overrun\n");
+
+		/*
+		 * When we get an overrun, we disregard the current
+		 * transfer. Data will not be copied back from any
+		 * bounce buffer and msg->actual_len will not be
+		 * updated with the last xfer.
+		 *
+		 * We will also not process any remaning transfers in
+		 * the message.
+		 *
+		 * All actions are done in tasklet with done_status indication
+		 */
+		as->done_status = -EIO;
+		smp_wmb();
+
+		/* Clear any overrun happening while cleaning up */
+		spi_readl(as, SR);
+
+		tasklet_schedule(&as->tasklet);
+
+	} else if (pending & SPI_BIT(RDRF)) {
+		atmel_spi_lock(as);
+
+		if (as->current_remaining_bytes) {
+			ret = IRQ_HANDLED;
+			xfer = as->current_transfer;
+			atmel_spi_pump_pio_data(as, xfer);
+			if (!as->current_remaining_bytes) {
+				/* no more data to xfer, kick tasklet */
+				spi_writel(as, IDR, pending);
+				tasklet_schedule(&as->tasklet);
+			}
+		}
+
+		atmel_spi_unlock(as);
+	} else {
+		WARN_ONCE(pending, "IRQ not handled, pending = %x\n", pending);
+		ret = IRQ_HANDLED;
+		spi_writel(as, IDR, pending);
+	}
+
+	return ret;
+}
+#else
+static void atmel_spi_tasklet_func(unsigned long data) {}
+
 static irqreturn_t
 atmel_spi_interrupt(int irq, void *dev_id)
 {
@@ -704,6 +1159,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
 
 	return ret;
 }
+#endif
 
 static int atmel_spi_setup(struct spi_device *spi)
 {
@@ -865,13 +1321,9 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
 
 		/*
 		 * DMA map early, for performance (empties dcache ASAP) and
-		 * better fault reporting.  This is a DMA-only driver.
-		 *
-		 * NOTE that if dma_unmap_single() ever starts to do work on
-		 * platforms supported by this driver, we would need to clean
-		 * up mappings for previously-mapped transfers.
+		 * better fault reporting.
 		 */
-		if (!msg->is_dma_mapped) {
+		if (!msg->is_dma_mapped && atmel_spi_use_dma(xfer)) {
 			if (atmel_spi_dma_map_xfer(as, xfer) < 0)
 				return -ENOMEM;
 		}
@@ -973,6 +1425,7 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 
 	spin_lock_init(&as->lock);
 	INIT_LIST_HEAD(&as->queue);
+	tasklet_init(&as->tasklet, atmel_spi_tasklet_func, (unsigned long)master);
 	as->pdev = pdev;
 	as->regs = ioremap(regs->start, resource_size(regs));
 	if (!as->regs)
@@ -991,7 +1444,11 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 	spi_writel(as, CR, SPI_BIT(SWRST));
 	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
 	spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS));
-	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+
+	ret = atmel_spi_configure_dma(master);
+	if (ret)
+		goto out_reset_hw;
+
 	spi_writel(as, CR, SPI_BIT(SPIEN));
 
 	/* go! */
@@ -1000,10 +1457,12 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 
 	ret = spi_register_master(master);
 	if (ret)
-		goto out_reset_hw;
+		goto out_free_dma;
 
 	return 0;
 
+out_free_dma:
+	atmel_spi_release_dma(as);
 out_reset_hw:
 	spi_writel(as, CR, SPI_BIT(SWRST));
 	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
@@ -1012,6 +1471,7 @@ out_reset_hw:
 out_unmap_regs:
 	iounmap(as->regs);
 out_free_buffer:
+	tasklet_kill(&as->tasklet);
 	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
 			as->buffer_dma);
 out_free:
@@ -1030,6 +1490,8 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)
 	/* reset the hardware and block queue progress */
 	spin_lock_irq(&as->lock);
 	as->stopping = 1;
+	atmel_spi_stop_dma(as);
+	atmel_spi_release_dma(as);
 	spi_writel(as, CR, SPI_BIT(SWRST));
 	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
 	spi_readl(as, SR);
@@ -1038,13 +1500,14 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)
 	/* Terminate remaining queued transfers */
 	list_for_each_entry(msg, &as->queue, queue) {
 		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-			if (!msg->is_dma_mapped)
+			if (!msg->is_dma_mapped && atmel_spi_use_dma(xfer))
 				atmel_spi_dma_unmap_xfer(master, xfer);
 		}
 		msg->status = -ESHUTDOWN;
 		msg->complete(msg->context);
 	}
 
+	tasklet_kill(&as->tasklet);
 	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
 			as->buffer_dma);
 
-- 
1.7.2.5

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

* [PATCH 10/23] spi-atmel: update with dmaengine interface
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (8 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 09/23] spi/atmel_spi: add dmaengine support Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 11/23] spi-atmel: fix __init/__devinit sections mismatch Richard Genoud
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

commit 185ecb5f4fd43911c35956d4cc7d94a1da30417f changed dmaengine
interface.
=> we have to update spi-atmel accordingly

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/spi/spi-atmel.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 9456fca..48bf3bc 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -542,7 +542,8 @@ static int atmel_spi_next_xfer_dma(struct spi_master *master,
 					&as->dma.sgrx,
 					1,
 					DMA_FROM_DEVICE,
-					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+					NULL);
 	if (!rxdesc)
 		goto err_dma;
 
@@ -550,7 +551,8 @@ static int atmel_spi_next_xfer_dma(struct spi_master *master,
 					&as->dma.sgtx,
 					1,
 					DMA_TO_DEVICE,
-					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+					NULL);
 	if (!txdesc)
 		goto err_dma;
 
-- 
1.7.2.5

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

* [PATCH 11/23] spi-atmel: fix __init/__devinit sections mismatch
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (9 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 10/23] spi-atmel: update with dmaengine interface Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 12/23] spi-atmel: Fix spi-atmel driver to adapt to slave_config changes Richard Genoud
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/spi/spi-atmel.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 48bf3bc..d90e8fb 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -383,7 +383,7 @@ static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer)
 }
 
 #if defined(CONFIG_SPI_ATMEL_DMA)
-static bool __init filter(struct dma_chan *chan, void *slave)
+static bool filter(struct dma_chan *chan, void *slave)
 {
 	struct	at_dma_slave		*sl = slave;
 
@@ -395,7 +395,7 @@ static bool __init filter(struct dma_chan *chan, void *slave)
 	}
 }
 
-static int __init atmel_spi_configure_dma(struct spi_master *master)
+static int __devinit atmel_spi_configure_dma(struct spi_master *master)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 	struct device		*controller = master->dev.parent;
@@ -628,7 +628,7 @@ static void atmel_spi_disable_dma_irq(struct atmel_spi *as)
 	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
 }
 
-static int __init atmel_spi_configure_dma(struct spi_master *master)
+static int __devinit atmel_spi_configure_dma(struct spi_master *master)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 
-- 
1.7.2.5

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

* [PATCH 12/23] spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (10 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 11/23] spi-atmel: fix __init/__devinit sections mismatch Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 13/23] AT91 DMA OF support Richard Genoud
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

This is the following of the patch e2b35f3dbfc080f15b72834d08f04f0269dbe9be

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/spi/spi-atmel.c |   45 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index d90e8fb..28a00ab 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -399,17 +399,24 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 	struct device		*controller = master->dev.parent;
+	struct dma_slave_config slave_config;
 	struct at_dma_slave	*sdata;
+	int err;
 
 	sdata = controller->platform_data;
 
+	memset(&slave_config, 0, sizeof(slave_config));
+	slave_config.dst_addr = (dma_addr_t)as->phybase + SPI_TDR;
+	slave_config.src_addr = (dma_addr_t)as->phybase + SPI_RDR;
+	slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	slave_config.src_maxburst = 1;
+	slave_config.dst_maxburst = 1;
+	slave_config.device_fc = false;
+
 	if (sdata && sdata->dma_dev) {
 		dma_cap_mask_t mask;
 
-		/* setup DMA addresses */
-		sdata->rx_reg = (dma_addr_t)as->phybase + SPI_RDR;
-		sdata->tx_reg = (dma_addr_t)as->phybase + SPI_TDR;
-
 		/* Try to grab two DMA channels */
 		dma_cap_zero(mask);
 		dma_cap_set(DMA_SLAVE, mask);
@@ -417,14 +424,28 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master)
 		if (as->dma.chan_tx)
 			as->dma.chan_rx = dma_request_channel(mask, filter, sdata);
 	}
+
 	if (!as->dma.chan_rx || !as->dma.chan_tx) {
-		if (as->dma.chan_rx)
-			dma_release_channel(as->dma.chan_rx);
-		if (as->dma.chan_tx)
-			dma_release_channel(as->dma.chan_tx);
 		dev_err(&as->pdev->dev, "DMA channel not available, "
 					"unable to use SPI\n");
-		return -EBUSY;
+		err = -EBUSY;
+		goto error;
+	}
+
+	slave_config.direction = DMA_TO_DEVICE;
+	if (dmaengine_slave_config(as->dma.chan_tx, &slave_config)) {
+		dev_err(&as->pdev->dev,
+			"failed to configure tx dma channel\n");
+		err = -EINVAL;
+		goto error;
+	}
+
+	slave_config.direction = DMA_FROM_DEVICE;
+	if (dmaengine_slave_config(as->dma.chan_rx, &slave_config)) {
+		dev_err(&as->pdev->dev,
+			"failed to configure rx dma channel\n");
+		err = -EINVAL;
+		goto error;
 	}
 
 	dev_info(&as->pdev->dev, "Using %s (tx) and "
@@ -433,6 +454,12 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master)
 				dma_chan_name(as->dma.chan_rx));
 
 	return 0;
+error:
+	if (as->dma.chan_rx)
+		dma_release_channel(as->dma.chan_rx);
+	if (as->dma.chan_tx)
+		dma_release_channel(as->dma.chan_tx);
+	return err;
 }
 
 static void atmel_spi_stop_dma(struct atmel_spi *as)
-- 
1.7.2.5

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

* [PATCH 13/23] AT91 DMA OF support
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (11 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 12/23] spi-atmel: Fix spi-atmel driver to adapt to slave_config changes Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 14:47   ` Nicolas Ferre
  2012-08-14 13:49 ` [PATCH 14/23] add at91sam9x5 Kconfig ARCH/SOC link Richard Genoud
                   ` (11 subsequent siblings)
  24 siblings, 1 reply; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 arch/arm/mach-at91/include/mach/at_hdmac.h |    1 +
 drivers/of/Kconfig                         |    4 +
 drivers/of/Makefile                        |    1 +
 drivers/of/of_atmel.c                      |  112 ++++++++++++++++++++++++++++
 include/linux/of_atmel.h                   |   29 +++++++
 5 files changed, 147 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/of_atmel.c
 create mode 100644 include/linux/of_atmel.h

diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
index cab0997..35667bd 100644
--- a/arch/arm/mach-at91/include/mach/at_hdmac.h
+++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
@@ -52,6 +52,7 @@ struct at_dma_slave {
 #define		ATC_LOCK_IF_L_CHUNK	(0x0 << 22)
 #define		ATC_LOCK_IF_L_BUFFER	(0x1 << 22)
 #define	ATC_AHB_PROT_MASK	(0x7 << 24)	/* AHB Protection */
+#define	ATC_AHB_PROT(h)		(((h) <<  24) && ATC_AHB_PROT_MASK)
 #define	ATC_FIFOCFG_MASK	(0x3 << 28)	/* FIFO Request Configuration */
 #define		ATC_FIFOCFG_LARGESTBURST	(0x0 << 28)
 #define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index dfba3e6..4667960 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -83,4 +83,8 @@ config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_ATMEL
+	depends on AT_HDMAC
+	def_bool y
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index e027f44..897de3b 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_ATMEL)	+= of_atmel.o
diff --git a/drivers/of/of_atmel.c b/drivers/of/of_atmel.c
new file mode 100644
index 0000000..bcd3c54a
--- /dev/null
+++ b/drivers/of/of_atmel.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 Richard Genoud, Paratronic S.A.
+ *                    <richard.genoud@gmail.com>
+ *
+ * Atmel specifics OF helpers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/printk.h>
+#include <linux/byteorder/generic.h>
+#include <mach/at_hdmac.h>
+#include <linux/of.h>
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+/**
+ * of_create_at_dma_slave - Alloc and initialize the struct at_dma_slave
+ * @np: pointer to node to create the struct for
+ * @bus: pointer to the bus type of the DMA device.
+ *
+ * Returns pointer to created DMA slave structure, or NULL in case of error.
+ */
+struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
+					    struct bus_type *bus)
+{
+	struct at_dma_slave *atslave;
+	struct device_node *n;
+	struct property *prop;
+	const __be32 *dma_list;
+	phandle phandle;
+	int size;
+	int err = -1;
+	u32 val;
+
+	atslave = kzalloc(sizeof(struct at_dma_slave), GFP_KERNEL);
+	if (unlikely(!atslave)) {
+		pr_err("cannot allocate memory\n");
+		goto error;
+	}
+
+	atslave->cfg |= of_property_read_bool(np, "atc_src_rep") ? ATC_SRC_REP : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_dst_rep") ? ATC_DST_REP : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_src_h2sel_hw") ? ATC_SRC_H2SEL_HW : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_dst_h2sel_hw") ? ATC_DST_H2SEL_HW : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_sod") ? ATC_SOD : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_lock_if") ? ATC_LOCK_IF : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_lock_b") ? ATC_LOCK_B : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l") ? ATC_LOCK_IF_L : 0;
+	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l_buffer") ? ATC_LOCK_IF_L_BUFFER : 0;
+	if (of_property_read_bool(np, "atc_fifocfg_halffifo"))
+		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_HALFFIFO;
+	if (of_property_read_bool(np, "atc_fifocfg_enoughspace"))
+		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_ENOUGHSPACE;
+	if (of_property_read_bool(np, "atc_fifocfg_largestburst"))
+		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_LARGESTBURST;
+	if (!of_property_read_u32(np, "atc_ahb_prot", &val))
+		atslave->cfg |= ATC_AHB_PROT(val);
+	if (!of_property_read_u32(np, "atc_src_per", &val))
+		atslave->cfg |= ATC_SRC_PER(val);
+	if (!of_property_read_u32(np, "atc_dst_per", &val))
+		atslave->cfg |= ATC_DST_PER(val);
+
+	/* we need to associate the wanted dma struct device to
+	 * atslave->dma_dev. This is needed when searching for
+	 * a free dma channel
+	 */
+	prop = of_find_property(np, "dma", &size);
+	if (!prop) {
+		pr_err("can't find the dma child node\n");
+		goto error;
+	}
+	dma_list = prop->value;
+	size /= sizeof(*dma_list);
+	if (size != 1) {
+		pr_err("only one dma handle is supported\n");
+		goto error;
+	}
+
+	phandle = be32_to_cpup(dma_list);
+	n = of_find_node_by_phandle(phandle);
+	if (!n) {
+		pr_err("unable to find dma device: invalid phandle %s\n",
+		       prop->name);
+		goto error;
+	}
+
+	atslave->dma_dev = bus_find_device(bus, NULL, n, of_dev_node_match);
+	if (!atslave->dma_dev) {
+		pr_err("can't find struct device for DMA %s\n", prop->name);
+		goto error;
+	}
+
+	pr_debug("DMA cfg register=0x%x DMA device path=%s\n",
+		 atslave->cfg, prop->name);
+	err = 0;
+error:
+	if (err)
+		kfree(atslave);
+	return atslave;
+}
+EXPORT_SYMBOL_GPL(of_create_at_dma_slave);
+
diff --git a/include/linux/of_atmel.h b/include/linux/of_atmel.h
new file mode 100644
index 0000000..256f336
--- /dev/null
+++ b/include/linux/of_atmel.h
@@ -0,0 +1,29 @@
+#ifndef _LINUX_OF_ATMEL_H
+#define _LINUX_OF_ATMEL_H
+/*
+ * Copyright (C) 2012 Richard Genoud, Paratronic S.A.
+ *                    <richard.genoud@gmail.com>
+ *
+ * Atmel specifics OF helpers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/of.h>
+#include <linux/device.h>
+#include <mach/at_hdmac.h>
+
+#ifdef CONFIG_OF_ATMEL
+extern struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
+						   struct bus_type *bus);
+#else
+static struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
+						   struct bus_type *bus)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF_ATMEL */
+
+#endif	/* _LINUX_OF_ATMEL_H */
-- 
1.7.2.5

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

* [PATCH 14/23] add at91sam9x5 Kconfig ARCH/SOC link
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (12 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 13/23] AT91 DMA OF support Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 15/23] spi-atmel: add DMA OF support Richard Genoud
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

---
 arch/arm/mach-at91/Kconfig |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index c8050b1..c6eb877 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -141,6 +141,10 @@ config ARCH_AT91SAM9G45
 	bool "AT91SAM9G45"
 	select SOC_AT91SAM9G45
 
+config ARCH_AT91SAM9X5
+	bool "AT91SAM9x5"
+	select SOC_AT91SAM9X5
+
 config ARCH_AT91X40
 	bool "AT91x40"
 	depends on !MMU
-- 
1.7.2.5

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

* [PATCH 15/23] spi-atmel: add DMA OF support
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (13 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 14/23] add at91sam9x5 Kconfig ARCH/SOC link Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 16/23] [BUG] SPI: array out of bound => no CS Richard Genoud
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/of/of_atmel.c   |    1 -
 drivers/spi/spi-atmel.c |   22 ++++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/of/of_atmel.c b/drivers/of/of_atmel.c
index bcd3c54a..a59b9ced 100644
--- a/drivers/of/of_atmel.c
+++ b/drivers/of/of_atmel.c
@@ -55,7 +55,6 @@ struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
 	atslave->cfg |= of_property_read_bool(np, "atc_sod") ? ATC_SOD : 0;
 	atslave->cfg |= of_property_read_bool(np, "atc_lock_if") ? ATC_LOCK_IF : 0;
 	atslave->cfg |= of_property_read_bool(np, "atc_lock_b") ? ATC_LOCK_B : 0;
-	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l") ? ATC_LOCK_IF_L : 0;
 	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l_buffer") ? ATC_LOCK_IF_L_BUFFER : 0;
 	if (of_property_read_bool(np, "atc_fifocfg_halffifo"))
 		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_HALFFIFO;
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 28a00ab..d629422 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -21,6 +21,7 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_atmel.h>
 
 #include <asm/io.h>
 #include <mach/board.h>
@@ -1411,6 +1412,8 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 	int			ret;
 	struct spi_master	*master;
 	struct atmel_spi	*as;
+	struct bus_type		*bus = pdev->dev.bus;
+	struct device_node	*of = pdev->dev.of_node;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs)
@@ -1430,6 +1433,17 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)
 	if (!master)
 		goto out_free;
 
+
+	/* populate platform_data from device tree */
+	if (of) {
+		pdev->dev.platform_data = of_create_at_dma_slave(of, bus);
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "could not get DMA\n");
+			ret = -EINVAL;
+			goto out_free;
+		}
+	}
+
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
@@ -1504,6 +1518,10 @@ out_free_buffer:
 	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
 			as->buffer_dma);
 out_free:
+	if (of) {
+		kfree((struct at_dma_slave*)(pdev->dev.platform_data));
+		pdev->dev.platform_data = NULL;
+	}
 	clk_put(clk);
 	spi_master_put(master);
 	return ret;
@@ -1546,6 +1564,10 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)
 	iounmap(as->regs);
 
 	spi_unregister_master(master);
+	if (pdev->dev.of_node) {
+		kfree((struct at_dma_slave*)(pdev->dev.platform_data));
+		pdev->dev.platform_data = NULL;
+	}
 
 	return 0;
 }
-- 
1.7.2.5

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

* [PATCH 16/23] [BUG] SPI: array out of bound => no CS
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (14 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 15/23] spi-atmel: add DMA OF support Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 17/23] [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes Richard Genoud
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

---
 drivers/spi/spi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 3fb5b6d..74e6577 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -976,8 +976,8 @@ static int of_spi_register_master(struct spi_master *master)
 		return -ENOMEM;
 
 	memset(cs, -EINVAL, master->num_chipselect);
-	master->num_chipselect += nb;
 	cs += master->num_chipselect;
+	master->num_chipselect += nb;
 
 	for (i = 0; i < nb; i++)
 		cs[i] = of_get_named_gpio(np, "cs-gpios", i);
-- 
1.7.2.5

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

* [PATCH 17/23] [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (15 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 16/23] [BUG] SPI: array out of bound => no CS Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 18/23] sam9x5: declare SPI clocks Richard Genoud
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

this is just a quick and suboptimal workaround
---
 drivers/spi/spi-atmel.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index d629422..0899da2 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -638,7 +638,8 @@ static void atmel_spi_next_xfer(struct spi_master *master,
 
 	as->current_transfer = xfer;
 
-	if (atmel_spi_use_dma(xfer)) {
+	/* quick (and *really* not optimal) workaround for DMA BUG */
+	if (atmel_spi_use_dma(xfer) && (xfer->len < BUFFER_SIZE)) {
 		if (!atmel_spi_next_xfer_dma(master, xfer))
 			return;
 		else
-- 
1.7.2.5

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

* [PATCH 18/23] sam9x5: declare SPI clocks
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (16 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 17/23] [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 19/23] spi-atmel: add sam9x5 SPI in device tree Richard Genoud
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 arch/arm/mach-at91/at91sam9x5.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index bbd2f8e..e213e2d 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -16,6 +16,7 @@
 #include <mach/at91_pmc.h>
 #include <mach/cpu.h>
 #include <mach/board.h>
+#include <mach/gpio.h>
 
 #include "soc.h"
 #include "generic.h"
@@ -231,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
 	CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "f0000000.spi", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi1_clk),
 	CLKDEV_CON_ID("pioA", &pioAB_clk),
 	CLKDEV_CON_ID("pioB", &pioAB_clk),
 	CLKDEV_CON_ID("pioC", &pioCD_clk),
-- 
1.7.2.5

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

* [PATCH 19/23] spi-atmel: add sam9x5 SPI in device tree
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (17 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 18/23] sam9x5: declare SPI clocks Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 20/23] spi-atmel: add dma support in sam9x5 " Richard Genoud
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 arch/arm/boot/dts/at91sam9x5.dtsi |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index e58965d6..8cb8b0d 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -344,6 +344,36 @@
 					trigger-value = <0x6>;
 				};
 			};
+
+			spi0: spi at f0000000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91rm9200-spi";
+				reg = <0xf0000000 0x100>;
+				interrupts = <13 4 3>;
+				cs-gpios = <&pioA 14 0
+					    &pioA 7 0 /* conflicts with TXD2 */
+					    &pioA 1 0 /* conflicts with RXD0 */
+					    &pioB 3 0 /* conflicts with ERXDV */
+					   >;
+				dma-mask = <0xffffffff>;
+				status = "disabled";
+			};
+
+			spi1: spi at f0004000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91rm9200-spi";
+				reg = <0xf0004000 0x100>;
+				interrupts = <14 4 3>;
+				cs-gpios = <&pioA 8 0 /* conflitcs with RXD2 */
+					    &pioA 0 0 /* conflitcs with TXD0 */
+					    &pioA 31 0 /* conflitcs with TWCK0 */
+					    &pioA 30 0 /* conflitcs with TWD0 */
+					   >;
+				dma-mask = <0xffffffff>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand at 40000000 {
-- 
1.7.2.5

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

* [PATCH 20/23] spi-atmel: add dma support in sam9x5 device tree
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (18 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 19/23] spi-atmel: add sam9x5 SPI in device tree Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 21/23] spi-atmel OF: complete documentation Richard Genoud
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 arch/arm/boot/dts/at91sam9x5.dtsi |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 8cb8b0d..ef09816 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -357,6 +357,12 @@
 					    &pioB 3 0 /* conflicts with ERXDV */
 					   >;
 				dma-mask = <0xffffffff>;
+				dma = <&dma0>;
+				atc_src_per = <2>; /* AT_DMA_ID_SPI0_RX */
+				atc_dst_per = <1>; /* AT_DMA_ID_SPI0_TX */
+				atc_fifocfg_halffifo;
+				atc_src_h2sel_hw;
+				atc_dst_h2sel_hw;
 				status = "disabled";
 			};
 
@@ -372,6 +378,12 @@
 					    &pioA 30 0 /* conflitcs with TWD0 */
 					   >;
 				dma-mask = <0xffffffff>;
+				dma = <&dma0>;
+				atc_src_per = <4>; /* AT_DMA_ID_SPI1_RX */
+				atc_dst_per = <3>; /* AT_DMA_ID_SPI1_TX */
+				atc_fifocfg_halffifo;
+				atc_src_h2sel_hw;
+				atc_dst_h2sel_hw;
 				status = "disabled";
 			};
 		};
-- 
1.7.2.5

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

* [PATCH 21/23] spi-atmel OF: complete documentation
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (19 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 20/23] spi-atmel: add dma support in sam9x5 " Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 22/23] spi-atmel: complete DMA slave OF documentation Richard Genoud
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 .../devicetree/bindings/spi/spi_atmel.txt          |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt
index 7ec3d8d..6d2e5e1 100644
--- a/Documentation/devicetree/bindings/spi/spi_atmel.txt
+++ b/Documentation/devicetree/bindings/spi/spi_atmel.txt
@@ -4,3 +4,18 @@ Required properties:
 - compatible : should be "atmel,at91rm9200-spi".
 - reg: Address and length of the register set for the device
 - interrupts: Should contain macb interrupt
+- cs-gpio: Should contain the GPIOs used for chipselect.
+
+spi0: spi at f0000000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "atmel,at91rm9200-spi";
+	reg = <0xf0000000 0x100>;
+	interrupts = <13 4>;
+	cs-gpios = <&pioA 14 0
+		    &pioA 7 0 /* conflicts with TXD2 */
+		    &pioA 1 0 /* conflicts with RXD0 */
+		    &pioB 3 0 /* conflicts with ERXDV */
+		   >;
+	status = "disabled";
+};
-- 
1.7.2.5

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

* [PATCH 22/23] spi-atmel: complete DMA slave OF documentation
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (20 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 21/23] spi-atmel OF: complete documentation Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 13:49 ` [PATCH 23/23] sam9x5ek DTS: enable SPI dataflash Richard Genoud
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 .../devicetree/bindings/spi/spi_atmel.txt          |   25 ++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt
index 6d2e5e1..b5d8082 100644
--- a/Documentation/devicetree/bindings/spi/spi_atmel.txt
+++ b/Documentation/devicetree/bindings/spi/spi_atmel.txt
@@ -5,6 +5,24 @@ Required properties:
 - reg: Address and length of the register set for the device
 - interrupts: Should contain macb interrupt
 - cs-gpio: Should contain the GPIOs used for chipselect.
+- dma-mask: device coherent dma mask.
+/* dma transfer configuration. Cf DMA Channel configuration register */
+- dma: handle to the dma controller that should be used.
+- atc_src_per: source channel for DMA operation.
+- atc_dst_per: destination channel for DMA operation.
+- atc_src_h2sel_hw: Hardware handshaking interface is used to trigger a
+transfer request.
+- atc_dst_h2sel_hw: Hardware handshaking interface is used to trigger a
+transfer request.
+- atc_sod: STOP ON DONE activated.
+- atc_lock_if: Interface Lock capability is enabled.
+- atc_lock_b: AHB Bus Locking capability is enabled.
+- atc_lock_if_l_buffer: The Master Interface Arbiter is locked by the channel x for a buffer transfer.
+- atc_fifocfg_halffifo: When half FIFO size is available/filled, a source/destination request is serviced.
+- atc_fifocfg_enoughspace: When there is enough space/data available to perform a single AHB access, then the request is serviced.
+- atc_fifocfg_largestburst: The largest defined length AHB burst is performed on the destination AHB interface.
+- atc_ahb_prot: AHB Protection value. (cf release manual)
+
 
 spi0: spi at f0000000 {
 	#address-cells = <1>;
@@ -17,5 +35,12 @@ spi0: spi at f0000000 {
 		    &pioA 1 0 /* conflicts with RXD0 */
 		    &pioB 3 0 /* conflicts with ERXDV */
 		   >;
+	dma-mask = <0xffffffff>;
+	dma = <&dma0>;
+	atc_src_per = <2>; /* AT_DMA_ID_SPI0_RX */
+	atc_dst_per = <1>; /* AT_DMA_ID_SPI0_TX */
+	atc_fifocfg_halffifo;
+	atc_src_h2sel_hw;
+	atc_dst_h2sel_hw;
 	status = "disabled";
 };
-- 
1.7.2.5

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

* [PATCH 23/23] sam9x5ek DTS: enable SPI dataflash
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (21 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 22/23] spi-atmel: complete DMA slave OF documentation Richard Genoud
@ 2012-08-14 13:49 ` Richard Genoud
  2012-08-14 14:16 ` [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
  2012-08-14 15:29 ` Nicolas Ferre
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 arch/arm/boot/dts/at91sam9x5ek.dtsi |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
index e5000a7..c99f1cc 100644
--- a/arch/arm/boot/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -30,6 +30,16 @@
 				phy-mode = "rmii";
 				status = "okay";
 			};
+
+			spi0: spi at f0000000 {
+				status = "okay";
+				cs-gpios = <&pioA 14 0>;
+				m25p80 at 0 {
+					compatible = "atmel,at25df321a";
+					spi-max-frequency = <50000000>;
+					reg = <0>;
+				};
+			};
 		};
 
 		usb0: ohci at 00600000 {
-- 
1.7.2.5

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

* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (22 preceding siblings ...)
  2012-08-14 13:49 ` [PATCH 23/23] sam9x5ek DTS: enable SPI dataflash Richard Genoud
@ 2012-08-14 14:16 ` Richard Genoud
  2012-08-14 15:29 ` Nicolas Ferre
  24 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-14 14:16 UTC (permalink / raw)
  To: linux-arm-kernel

2012/8/14 Richard Genoud <richard.genoud@gmail.com>:
> Nicolas,
> I said that I had some work done on sam9g35-ek, here is the spi part, based
> on your and Jean-Christophe work.
> You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.
I forgot something:
As I didn't get pinctrl to work, on top of this patchset, I did a
revert of "ARM: at91: add pinctrl support"
and I made this change :
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index e213e2d..bc3fdbf 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -313,6 +313,13 @@ static void __init at91sam9x5_map_io(void)
 	at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
 }

+
+void __init at91sam9x5_initialize(void)
+{
+	/* Register GPIO subsystem (using DT) */
+	at91_gpio_init(NULL, 0);
+}
+
 /* --------------------------------------------------------------------
  *  Interrupt initialization
  * -------------------------------------------------------------------- */
@@ -320,4 +327,5 @@ static void __init at91sam9x5_map_io(void)
 struct at91_init_soc __initdata at91sam9x5_soc = {
 	.map_io = at91sam9x5_map_io,
 	.register_clocks = at91sam9x5_register_clocks,
+	.init = at91sam9x5_initialize,
 };

I also enabled the spi controller in the DTS:
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi
b/arch/arm/boot/dts/at91sam9x5.dtsi
index ef09816..cc1c830 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -363,7 +363,7 @@
 				atc_fifocfg_halffifo;
 				atc_src_h2sel_hw;
 				atc_dst_h2sel_hw;
-				status = "disabled";
+				status = "okay";
 			};

 			spi1: spi at f0004000 {

-- 
for me, ck means con kolivas and not calvin klein... does it mean I'm a geek ?

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

* [PATCH 13/23] AT91 DMA OF support
  2012-08-14 13:49 ` [PATCH 13/23] AT91 DMA OF support Richard Genoud
@ 2012-08-14 14:47   ` Nicolas Ferre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Ferre @ 2012-08-14 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Richard,

I am not sure that this one will go further: there is an initiative to
build a pretty generic DMA OF support... It takes time but it is
progressing...

Anyway, there may have some bits to integrate in at_hdmac.c driver: I
will have a closer look later.

Thanks,

On 08/14/2012 03:49 PM, Richard Genoud :
> Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
> ---
>  arch/arm/mach-at91/include/mach/at_hdmac.h |    1 +
>  drivers/of/Kconfig                         |    4 +
>  drivers/of/Makefile                        |    1 +
>  drivers/of/of_atmel.c                      |  112 ++++++++++++++++++++++++++++
>  include/linux/of_atmel.h                   |   29 +++++++
>  5 files changed, 147 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/of/of_atmel.c
>  create mode 100644 include/linux/of_atmel.h
> 
> diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
> index cab0997..35667bd 100644
> --- a/arch/arm/mach-at91/include/mach/at_hdmac.h
> +++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
> @@ -52,6 +52,7 @@ struct at_dma_slave {
>  #define		ATC_LOCK_IF_L_CHUNK	(0x0 << 22)
>  #define		ATC_LOCK_IF_L_BUFFER	(0x1 << 22)
>  #define	ATC_AHB_PROT_MASK	(0x7 << 24)	/* AHB Protection */
> +#define	ATC_AHB_PROT(h)		(((h) <<  24) && ATC_AHB_PROT_MASK)
>  #define	ATC_FIFOCFG_MASK	(0x3 << 28)	/* FIFO Request Configuration */
>  #define		ATC_FIFOCFG_LARGESTBURST	(0x0 << 28)
>  #define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index dfba3e6..4667960 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -83,4 +83,8 @@ config OF_MTD
>  	depends on MTD
>  	def_bool y
>  
> +config OF_ATMEL
> +	depends on AT_HDMAC
> +	def_bool y
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index e027f44..897de3b 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>  obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_ATMEL)	+= of_atmel.o
> diff --git a/drivers/of/of_atmel.c b/drivers/of/of_atmel.c
> new file mode 100644
> index 0000000..bcd3c54a
> --- /dev/null
> +++ b/drivers/of/of_atmel.c
> @@ -0,0 +1,112 @@
> +/*
> + * Copyright (C) 2012 Richard Genoud, Paratronic S.A.
> + *                    <richard.genoud@gmail.com>
> + *
> + * Atmel specifics OF helpers
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +#include <linux/kernel.h>
> +#include <linux/export.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <linux/printk.h>
> +#include <linux/byteorder/generic.h>
> +#include <mach/at_hdmac.h>
> +#include <linux/of.h>
> +
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +/**
> + * of_create_at_dma_slave - Alloc and initialize the struct at_dma_slave
> + * @np: pointer to node to create the struct for
> + * @bus: pointer to the bus type of the DMA device.
> + *
> + * Returns pointer to created DMA slave structure, or NULL in case of error.
> + */
> +struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
> +					    struct bus_type *bus)
> +{
> +	struct at_dma_slave *atslave;
> +	struct device_node *n;
> +	struct property *prop;
> +	const __be32 *dma_list;
> +	phandle phandle;
> +	int size;
> +	int err = -1;
> +	u32 val;
> +
> +	atslave = kzalloc(sizeof(struct at_dma_slave), GFP_KERNEL);
> +	if (unlikely(!atslave)) {
> +		pr_err("cannot allocate memory\n");
> +		goto error;
> +	}
> +
> +	atslave->cfg |= of_property_read_bool(np, "atc_src_rep") ? ATC_SRC_REP : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_dst_rep") ? ATC_DST_REP : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_src_h2sel_hw") ? ATC_SRC_H2SEL_HW : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_dst_h2sel_hw") ? ATC_DST_H2SEL_HW : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_sod") ? ATC_SOD : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_lock_if") ? ATC_LOCK_IF : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_lock_b") ? ATC_LOCK_B : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l") ? ATC_LOCK_IF_L : 0;
> +	atslave->cfg |= of_property_read_bool(np, "atc_lock_if_l_buffer") ? ATC_LOCK_IF_L_BUFFER : 0;
> +	if (of_property_read_bool(np, "atc_fifocfg_halffifo"))
> +		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_HALFFIFO;
> +	if (of_property_read_bool(np, "atc_fifocfg_enoughspace"))
> +		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_ENOUGHSPACE;
> +	if (of_property_read_bool(np, "atc_fifocfg_largestburst"))
> +		atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK) | ATC_FIFOCFG_LARGESTBURST;
> +	if (!of_property_read_u32(np, "atc_ahb_prot", &val))
> +		atslave->cfg |= ATC_AHB_PROT(val);
> +	if (!of_property_read_u32(np, "atc_src_per", &val))
> +		atslave->cfg |= ATC_SRC_PER(val);
> +	if (!of_property_read_u32(np, "atc_dst_per", &val))
> +		atslave->cfg |= ATC_DST_PER(val);
> +
> +	/* we need to associate the wanted dma struct device to
> +	 * atslave->dma_dev. This is needed when searching for
> +	 * a free dma channel
> +	 */
> +	prop = of_find_property(np, "dma", &size);
> +	if (!prop) {
> +		pr_err("can't find the dma child node\n");
> +		goto error;
> +	}
> +	dma_list = prop->value;
> +	size /= sizeof(*dma_list);
> +	if (size != 1) {
> +		pr_err("only one dma handle is supported\n");
> +		goto error;
> +	}
> +
> +	phandle = be32_to_cpup(dma_list);
> +	n = of_find_node_by_phandle(phandle);
> +	if (!n) {
> +		pr_err("unable to find dma device: invalid phandle %s\n",
> +		       prop->name);
> +		goto error;
> +	}
> +
> +	atslave->dma_dev = bus_find_device(bus, NULL, n, of_dev_node_match);
> +	if (!atslave->dma_dev) {
> +		pr_err("can't find struct device for DMA %s\n", prop->name);
> +		goto error;
> +	}
> +
> +	pr_debug("DMA cfg register=0x%x DMA device path=%s\n",
> +		 atslave->cfg, prop->name);
> +	err = 0;
> +error:
> +	if (err)
> +		kfree(atslave);
> +	return atslave;
> +}
> +EXPORT_SYMBOL_GPL(of_create_at_dma_slave);
> +
> diff --git a/include/linux/of_atmel.h b/include/linux/of_atmel.h
> new file mode 100644
> index 0000000..256f336
> --- /dev/null
> +++ b/include/linux/of_atmel.h
> @@ -0,0 +1,29 @@
> +#ifndef _LINUX_OF_ATMEL_H
> +#define _LINUX_OF_ATMEL_H
> +/*
> + * Copyright (C) 2012 Richard Genoud, Paratronic S.A.
> + *                    <richard.genoud@gmail.com>
> + *
> + * Atmel specifics OF helpers
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +#include <linux/of.h>
> +#include <linux/device.h>
> +#include <mach/at_hdmac.h>
> +
> +#ifdef CONFIG_OF_ATMEL
> +extern struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
> +						   struct bus_type *bus);
> +#else
> +static struct at_dma_slave *of_create_at_dma_slave(struct device_node *np,
> +						   struct bus_type *bus)
> +{
> +	return NULL;
> +}
> +#endif /* CONFIG_OF_ATMEL */
> +
> +#endif	/* _LINUX_OF_ATMEL_H */
> 


-- 
Nicolas Ferre

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

* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
  2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
                   ` (23 preceding siblings ...)
  2012-08-14 14:16 ` [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
@ 2012-08-14 15:29 ` Nicolas Ferre
  2012-08-14 17:44   ` Jean-Christophe PLAGNIOL-VILLARD
  24 siblings, 1 reply; 30+ messages in thread
From: Nicolas Ferre @ 2012-08-14 15:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/14/2012 03:49 PM, Richard Genoud :
> Nicolas,
> I said that I had some work done on sam9g35-ek, here is the spi part, based
> on your and Jean-Christophe work.
> You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.
> 
> The goal of this patchset is to share the work I've done, it's not ready
> for upstream, but it may save some time.
> 
> It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
> 
> Best Regards,

Richard,

Thanks a lot for updating this material: We really appreciate.

We will try to review this material together with Jean-Christophe and
colleagues @ Atmel. I hope that we will go forward with this collected
material in the near future.

Maybe DMA OF part will not be upstreamed as-is because of an ongoing
initiative to build a generic dmaengine OF support.

> Jean-Christophe PLAGNIOL-VILLARD (3):
>   of: add dma-mask binding
>   of_spi: add generic binding support to specify cs gpio

I know that Jean-Christophe has had difficulties to have feedback on
there parts...

>   spi/atmel: add DT support
> 
> Nicolas Ferre (6):
>   spi/atmel_spi: trivial: change some comments
>   spi/atmel_spi: add physical base address
>   spi/atmel_spi: call unmapping on transfers buffers
>   spi/atmel_spi: status information passed through controller data
>   spi/atmel_spi: add flag to controller data for lock operations
>   spi/atmel_spi: add dmaengine support
> 
> Richard Genoud (14):
>   spi-atmel: update with dmaengine interface

This will certainly be squashed in previous path.

>   spi-atmel: fix __init/__devinit sections mismatch

This one also: but it is good to have them separated at fist.

>   spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
>   AT91 DMA OF support
>   add at91sam9x5 Kconfig ARCH/SOC link

Is it fixup for a bug? Jean-Christophe, a though about this one?

>   spi-atmel: add DMA OF support
>   [BUG] SPI: array out of bound => no CS
>   [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes
>   sam9x5: declare SPI clocks
>   spi-atmel: add sam9x5 SPI in device tree
>   spi-atmel: add dma support in sam9x5 device tree
>   spi-atmel OF: complete documentation

Maybe documentation has to be folded in the patch that actually adds the
OF support.

>   spi-atmel: complete DMA slave OF documentation
>   sam9x5ek DTS: enable SPI dataflash
> 
>  Documentation/devicetree/bindings/spi/spi-bus.txt  |    6 +
>  .../devicetree/bindings/spi/spi_atmel.txt          |   46 ++
>  arch/arm/boot/dts/at91sam9x5.dtsi                  |   42 ++
>  arch/arm/boot/dts/at91sam9x5ek.dtsi                |   10 +
>  arch/arm/mach-at91/Kconfig                         |    4 +
>  arch/arm/mach-at91/at91sam9x5.c                    |    3 +
>  arch/arm/mach-at91/include/mach/at_hdmac.h         |    1 +
>  drivers/of/Kconfig                                 |    4 +
>  drivers/of/Makefile                                |    1 +
>  drivers/of/of_atmel.c                              |  111 ++++
>  drivers/of/platform.c                              |   23 +-
>  drivers/spi/Kconfig                                |    9 +
>  drivers/spi/spi-atmel.c                            |  611 ++++++++++++++++++--
>  drivers/spi/spi.c                                  |   55 ++-
>  include/linux/of_atmel.h                           |   29 +
>  include/linux/spi/spi.h                            |    3 +
>  16 files changed, 914 insertions(+), 44 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt
>  create mode 100644 drivers/of/of_atmel.c
>  create mode 100644 include/linux/of_atmel.h
> 


-- 
Nicolas Ferre

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

* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
  2012-08-14 15:29 ` Nicolas Ferre
@ 2012-08-14 17:44   ` Jean-Christophe PLAGNIOL-VILLARD
  2012-08-14 17:48     ` Nicolas Ferre
  0 siblings, 1 reply; 30+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-08-14 17:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:29 Tue 14 Aug     , Nicolas Ferre wrote:
> On 08/14/2012 03:49 PM, Richard Genoud :
> > Nicolas,
> > I said that I had some work done on sam9g35-ek, here is the spi part, based
> > on your and Jean-Christophe work.
> > You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.
> > 
> > The goal of this patchset is to share the work I've done, it's not ready
> > for upstream, but it may save some time.
> > 
> > It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
> > 
> > Best Regards,
> 
> Richard,
> 
> Thanks a lot for updating this material: We really appreciate.
> 
> We will try to review this material together with Jean-Christophe and
> colleagues @ Atmel. I hope that we will go forward with this collected
> material in the near future.
> 
> Maybe DMA OF part will not be upstreamed as-is because of an ongoing
> initiative to build a generic dmaengine OF support.
> 
> > Jean-Christophe PLAGNIOL-VILLARD (3):
> >   of: add dma-mask binding
> >   of_spi: add generic binding support to specify cs gpio
> 
> I know that Jean-Christophe has had difficulties to have feedback on
> there parts...
yes I need to re-write it as suggest by Grant

will take a look later next week on this
> 
> >   spi/atmel: add DT support
> > 
> > Nicolas Ferre (6):
> >   spi/atmel_spi: trivial: change some comments
> >   spi/atmel_spi: add physical base address
> >   spi/atmel_spi: call unmapping on transfers buffers
> >   spi/atmel_spi: status information passed through controller data
> >   spi/atmel_spi: add flag to controller data for lock operations
> >   spi/atmel_spi: add dmaengine support
> > 
> > Richard Genoud (14):
> >   spi-atmel: update with dmaengine interface
> 
> This will certainly be squashed in previous path.
> 
> >   spi-atmel: fix __init/__devinit sections mismatch
> 
> This one also: but it is good to have them separated at fist.
> 
> >   spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
> >   AT91 DMA OF support
> >   add at91sam9x5 Kconfig ARCH/SOC link
> 
> Is it fixup for a bug? Jean-Christophe, a though about this one?
no the ARCH_xxx is old style can not be used on DT only soc

this patch need to be droped

Best Regards,
J.

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

* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
  2012-08-14 17:44   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2012-08-14 17:48     ` Nicolas Ferre
  2012-08-16  7:07       ` Richard Genoud
  0 siblings, 1 reply; 30+ messages in thread
From: Nicolas Ferre @ 2012-08-14 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/14/2012 07:44 PM, Jean-Christophe PLAGNIOL-VILLARD :
> On 17:29 Tue 14 Aug     , Nicolas Ferre wrote:
>> On 08/14/2012 03:49 PM, Richard Genoud :
>>> Nicolas,
>>> I said that I had some work done on sam9g35-ek, here is the spi part, based
>>> on your and Jean-Christophe work.
>>> You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.
>>>
>>> The goal of this patchset is to share the work I've done, it's not ready
>>> for upstream, but it may save some time.
>>>
>>> It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
>>>
>>> Best Regards,
>>
>> Richard,
>>
>> Thanks a lot for updating this material: We really appreciate.
>>
>> We will try to review this material together with Jean-Christophe and
>> colleagues @ Atmel. I hope that we will go forward with this collected
>> material in the near future.
>>
>> Maybe DMA OF part will not be upstreamed as-is because of an ongoing
>> initiative to build a generic dmaengine OF support.
>>
>>> Jean-Christophe PLAGNIOL-VILLARD (3):
>>>   of: add dma-mask binding
>>>   of_spi: add generic binding support to specify cs gpio
>>
>> I know that Jean-Christophe has had difficulties to have feedback on
>> there parts...
> yes I need to re-write it as suggest by Grant
> 
> will take a look later next week on this
>>
>>>   spi/atmel: add DT support
>>>
>>> Nicolas Ferre (6):
>>>   spi/atmel_spi: trivial: change some comments
>>>   spi/atmel_spi: add physical base address
>>>   spi/atmel_spi: call unmapping on transfers buffers
>>>   spi/atmel_spi: status information passed through controller data
>>>   spi/atmel_spi: add flag to controller data for lock operations
>>>   spi/atmel_spi: add dmaengine support
>>>
>>> Richard Genoud (14):
>>>   spi-atmel: update with dmaengine interface
>>
>> This will certainly be squashed in previous path.
>>
>>>   spi-atmel: fix __init/__devinit sections mismatch
>>
>> This one also: but it is good to have them separated at fist.
>>
>>>   spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
>>>   AT91 DMA OF support
>>>   add at91sam9x5 Kconfig ARCH/SOC link
>>
>> Is it fixup for a bug? Jean-Christophe, a though about this one?
> no the ARCH_xxx is old style can not be used on DT only soc
> 
> this patch need to be droped

That is what I suspected, thanks J.

Bye,
-- 
Nicolas Ferre

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

* [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5
  2012-08-14 17:48     ` Nicolas Ferre
@ 2012-08-16  7:07       ` Richard Genoud
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Genoud @ 2012-08-16  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

2012/8/14 Nicolas Ferre <nicolas.ferre@atmel.com>:
>>>>   add at91sam9x5 Kconfig ARCH/SOC link
>>>
>>> Is it fixup for a bug? Jean-Christophe, a though about this one?
>> no the ARCH_xxx is old style can not be used on DT only soc
>>
>> this patch need to be droped
>
> That is what I suspected, thanks J.
Yes, Jean-Christophe is right. This patch needs to be dropped, and
this one should be applied instead:

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 169592a..f45d823 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -76,7 +76,7 @@ config SPI_ATMEL

 config SPI_ATMEL_DMA
 	bool "Atmel SPI DMA support"
-	depends on SPI_ATMEL && (ARCH_AT91SAM9G45 || ARCH_AT91SAM9X5) &&
DMA_ENGINE && EXPERIMENTAL
+	depends on SPI_ATMEL && (SOC_AT91SAM9G45 || SOC_AT91SAM9X5) &&
DMA_ENGINE && EXPERIMENTAL
 	default y
 	help
 	  Say Y here if you want the Atmel SPI driver to use the DMA engine.
Data transfers

Richard.

-- 
for me, ck means con kolivas and not calvin klein... does it mean I'm a geek ?

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

end of thread, other threads:[~2012-08-16  7:07 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-14 13:49 [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
2012-08-14 13:49 ` [PATCH 01/23] of: add dma-mask binding Richard Genoud
2012-08-14 13:49 ` [PATCH 02/23] of_spi: add generic binding support to specify cs gpio Richard Genoud
2012-08-14 13:49 ` [PATCH 03/23] spi/atmel_spi: trivial: change some comments Richard Genoud
2012-08-14 13:49 ` [PATCH 04/23] spi/atmel_spi: add physical base address Richard Genoud
2012-08-14 13:49 ` [PATCH 05/23] spi/atmel_spi: call unmapping on transfers buffers Richard Genoud
2012-08-14 13:49 ` [PATCH 06/23] spi/atmel_spi: status information passed through controller data Richard Genoud
2012-08-14 13:49 ` [PATCH 07/23] spi/atmel_spi: add flag to controller data for lock operations Richard Genoud
2012-08-14 13:49 ` [PATCH 08/23] spi/atmel: add DT support Richard Genoud
2012-08-14 13:49 ` [PATCH 09/23] spi/atmel_spi: add dmaengine support Richard Genoud
2012-08-14 13:49 ` [PATCH 10/23] spi-atmel: update with dmaengine interface Richard Genoud
2012-08-14 13:49 ` [PATCH 11/23] spi-atmel: fix __init/__devinit sections mismatch Richard Genoud
2012-08-14 13:49 ` [PATCH 12/23] spi-atmel: Fix spi-atmel driver to adapt to slave_config changes Richard Genoud
2012-08-14 13:49 ` [PATCH 13/23] AT91 DMA OF support Richard Genoud
2012-08-14 14:47   ` Nicolas Ferre
2012-08-14 13:49 ` [PATCH 14/23] add at91sam9x5 Kconfig ARCH/SOC link Richard Genoud
2012-08-14 13:49 ` [PATCH 15/23] spi-atmel: add DMA OF support Richard Genoud
2012-08-14 13:49 ` [PATCH 16/23] [BUG] SPI: array out of bound => no CS Richard Genoud
2012-08-14 13:49 ` [PATCH 17/23] [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes Richard Genoud
2012-08-14 13:49 ` [PATCH 18/23] sam9x5: declare SPI clocks Richard Genoud
2012-08-14 13:49 ` [PATCH 19/23] spi-atmel: add sam9x5 SPI in device tree Richard Genoud
2012-08-14 13:49 ` [PATCH 20/23] spi-atmel: add dma support in sam9x5 " Richard Genoud
2012-08-14 13:49 ` [PATCH 21/23] spi-atmel OF: complete documentation Richard Genoud
2012-08-14 13:49 ` [PATCH 22/23] spi-atmel: complete DMA slave OF documentation Richard Genoud
2012-08-14 13:49 ` [PATCH 23/23] sam9x5ek DTS: enable SPI dataflash Richard Genoud
2012-08-14 14:16 ` [PATCH 00/23] work in progress: SPI controller w/DMA SAM9X5 Richard Genoud
2012-08-14 15:29 ` Nicolas Ferre
2012-08-14 17:44   ` Jean-Christophe PLAGNIOL-VILLARD
2012-08-14 17:48     ` Nicolas Ferre
2012-08-16  7:07       ` Richard Genoud

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).