linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
To: Feng Tang <feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linus.walleij-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org,
	alan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org
Subject: Re: [Patch v2 3/3] spi/dw_spi: add DMA support
Date: Fri, 24 Dec 2010 01:12:14 -0700	[thread overview]
Message-ID: <20101224081214.GC5544@angua.secretlab.ca> (raw)
In-Reply-To: <1293170351-7426-3-git-send-email-feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

On Fri, Dec 24, 2010 at 01:59:11PM +0800, Feng Tang wrote:
> dw_spi driver in upstream only supports PIO mode, and this patch
> will support it to cowork with the Designware dma controller used
> on Intel Moorestown platform, at the same time it provides a general
> framework to support dw_spi core to cowork with dma controllers on
> other platforms
> 
> It has been tested with a Option GTM501L 3G modem and Infenion 60x60
> modem. To use DMA mode, DMA controller 2 of Moorestown has to be enabled
> 
> Also change the dma interface suggested by Linus Walleij.
> 
> Acked-by: Linus Walleij <linus.walleij-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org>
> Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> Signed-off-by: Feng Tang <feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> [Typo fix and renames to match intel_mid_dma renaming]
> Signed-off-by: Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Alan Cox <alan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Applied for -next, thanks.

g.

> ---
>  drivers/spi/Kconfig        |    4 +
>  drivers/spi/Makefile       |    3 +-
>  drivers/spi/dw_spi.c       |   33 ++++---
>  drivers/spi/dw_spi_mid.c   |  224 ++++++++++++++++++++++++++++++++++++++++++++
>  drivers/spi/dw_spi_pci.c   |   20 +++-
>  include/linux/spi/dw_spi.h |   24 ++++-
>  6 files changed, 284 insertions(+), 24 deletions(-)
>  create mode 100644 drivers/spi/dw_spi_mid.c
> 
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 78f9fd0..d53c830 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -396,6 +396,10 @@ config SPI_DW_PCI
>  	tristate "PCI interface driver for DW SPI core"
>  	depends on SPI_DESIGNWARE && PCI
>  
> +config SPI_DW_MID_DMA
> +	bool "DMA support for DW SPI controller on Intel Moorestown platform"
> +	depends on SPI_DW_PCI && INTEL_MID_DMAC
> +
>  config SPI_DW_MMIO
>  	tristate "Memory-mapped io interface driver for DW SPI core"
>  	depends on SPI_DESIGNWARE && HAVE_CLK
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 8bc1a5a..5e6e812 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -17,7 +17,8 @@ obj-$(CONFIG_SPI_BUTTERFLY)		+= spi_butterfly.o
>  obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= coldfire_qspi.o
>  obj-$(CONFIG_SPI_DAVINCI)		+= davinci_spi.o
>  obj-$(CONFIG_SPI_DESIGNWARE)		+= dw_spi.o
> -obj-$(CONFIG_SPI_DW_PCI)		+= dw_spi_pci.o
> +obj-$(CONFIG_SPI_DW_PCI)		+= dw_spi_midpci.o
> +dw_spi_midpci-objs			:= dw_spi_pci.o dw_spi_mid.o
>  obj-$(CONFIG_SPI_DW_MMIO)		+= dw_spi_mmio.o
>  obj-$(CONFIG_SPI_EP93XX)		+= ep93xx_spi.o
>  obj-$(CONFIG_SPI_GPIO)			+= spi_gpio.o
> diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
> index b50bf5b..497ecb3 100644
> --- a/drivers/spi/dw_spi.c
> +++ b/drivers/spi/dw_spi.c
> @@ -288,8 +288,10 @@ static void *next_transfer(struct dw_spi *dws)
>   */
>  static int map_dma_buffers(struct dw_spi *dws)
>  {
> -	if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited
> -		|| !dws->cur_chip->enable_dma)
> +	if (!dws->cur_msg->is_dma_mapped
> +		|| !dws->dma_inited
> +		|| !dws->cur_chip->enable_dma
> +		|| !dws->dma_ops)
>  		return 0;
>  
>  	if (dws->cur_transfer->tx_dma)
> @@ -341,7 +343,7 @@ static void int_error_stop(struct dw_spi *dws, const char *msg)
>  	tasklet_schedule(&dws->pump_transfers);
>  }
>  
> -static void transfer_complete(struct dw_spi *dws)
> +void dw_spi_xfer_done(struct dw_spi *dws)
>  {
>  	/* Update total byte transfered return count actual bytes read */
>  	dws->cur_msg->actual_length += dws->len;
> @@ -356,6 +358,7 @@ static void transfer_complete(struct dw_spi *dws)
>  	} else
>  		tasklet_schedule(&dws->pump_transfers);
>  }
> +EXPORT_SYMBOL_GPL(dw_spi_xfer_done);
>  
>  static irqreturn_t interrupt_transfer(struct dw_spi *dws)
>  {
> @@ -387,7 +390,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
>  		if (dws->tx_end > dws->tx)
>  			spi_umask_intr(dws, SPI_INT_TXEI);
>  		else
> -			transfer_complete(dws);
> +			dw_spi_xfer_done(dws);
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -422,11 +425,7 @@ static void poll_transfer(struct dw_spi *dws)
>  	 */
>  	dws->read(dws);
>  
> -	transfer_complete(dws);
> -}
> -
> -static void dma_transfer(struct dw_spi *dws, int cs_change)
> -{
> +	dw_spi_xfer_done(dws);
>  }
>  
>  static void pump_transfers(unsigned long data)
> @@ -608,7 +607,7 @@ static void pump_transfers(unsigned long data)
>  	}
>  
>  	if (dws->dma_mapped)
> -		dma_transfer(dws, cs_change);
> +		dws->dma_ops->dma_transfer(dws, cs_change);
>  
>  	if (chip->poll_mode)
>  		poll_transfer(dws);
> @@ -904,11 +903,17 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
>  	master->setup = dw_spi_setup;
>  	master->transfer = dw_spi_transfer;
>  
> -	dws->dma_inited = 0;
> -
>  	/* Basic HW init */
>  	spi_hw_init(dws);
>  
> +	if (dws->dma_ops && dws->dma_ops->dma_init) {
> +		ret = dws->dma_ops->dma_init(dws);
> +		if (ret) {
> +			dev_warn(&master->dev, "DMA init failed\n");
> +			dws->dma_inited = 0;
> +		}
> +	}
> +
>  	/* Initial and start queue */
>  	ret = init_queue(dws);
>  	if (ret) {
> @@ -933,6 +938,8 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
>  
>  err_queue_alloc:
>  	destroy_queue(dws);
> +	if (dws->dma_ops && dws->dma_ops->dma_exit)
> +		dws->dma_ops->dma_exit(dws);
>  err_diable_hw:
>  	spi_enable_chip(dws, 0);
>  	free_irq(dws->irq, dws);
> @@ -957,6 +964,8 @@ void __devexit dw_spi_remove_host(struct dw_spi *dws)
>  		dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not "
>  			"complete, message memory not freed\n");
>  
> +	if (dws->dma_ops && dws->dma_ops->dma_exit)
> +		dws->dma_ops->dma_exit(dws);
>  	spi_enable_chip(dws, 0);
>  	/* Disable clk */
>  	spi_set_clk(dws, 0);
> diff --git a/drivers/spi/dw_spi_mid.c b/drivers/spi/dw_spi_mid.c
> new file mode 100644
> index 0000000..8a49a13
> --- /dev/null
> +++ b/drivers/spi/dw_spi_mid.c
> @@ -0,0 +1,224 @@
> +/*
> + * dw_spi_mid.c - special handling for DW core on Intel MID platform
> + *
> + * Copyright (c) 2009, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
> +#include <linux/interrupt.h>
> +#include <linux/slab.h>
> +#include <linux/spi/spi.h>
> +#include <linux/spi/dw_spi.h>
> +
> +#ifdef CONFIG_SPI_DW_MID_DMA
> +#include <linux/intel_mid_dma.h>
> +#include <linux/pci.h>
> +
> +struct mid_dma {
> +	struct intel_mid_dma_slave	dmas_tx;
> +	struct intel_mid_dma_slave	dmas_rx;
> +};
> +
> +static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
> +{
> +	struct dw_spi *dws = param;
> +
> +	return dws->dmac && (&dws->dmac->dev == chan->device->dev);
> +}
> +
> +static int mid_spi_dma_init(struct dw_spi *dws)
> +{
> +	struct mid_dma *dw_dma = dws->dma_priv;
> +	struct intel_mid_dma_slave *rxs, *txs;
> +	dma_cap_mask_t mask;
> +
> +	/*
> +	 * Get pci device for DMA controller, currently it could only
> +	 * be the DMA controller of either Moorestown or Medfield
> +	 */
> +	dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0813, NULL);
> +	if (!dws->dmac)
> +		dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
> +
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +
> +	/* 1. Init rx channel */
> +	dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws);
> +	if (!dws->rxchan)
> +		goto err_exit;
> +	rxs = &dw_dma->dmas_rx;
> +	rxs->hs_mode = LNW_DMA_HW_HS;
> +	rxs->cfg_mode = LNW_DMA_PER_TO_MEM;
> +	dws->rxchan->private = rxs;
> +
> +	/* 2. Init tx channel */
> +	dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws);
> +	if (!dws->txchan)
> +		goto free_rxchan;
> +	txs = &dw_dma->dmas_tx;
> +	txs->hs_mode = LNW_DMA_HW_HS;
> +	txs->cfg_mode = LNW_DMA_MEM_TO_PER;
> +	dws->txchan->private = txs;
> +
> +	dws->dma_inited = 1;
> +	return 0;
> +
> +free_rxchan:
> +	dma_release_channel(dws->rxchan);
> +err_exit:
> +	return -1;
> +
> +}
> +
> +static void mid_spi_dma_exit(struct dw_spi *dws)
> +{
> +	dma_release_channel(dws->txchan);
> +	dma_release_channel(dws->rxchan);
> +}
> +
> +/*
> + * dws->dma_chan_done is cleared before the dma transfer starts,
> + * callback for rx/tx channel will each increment it by 1.
> + * Reaching 2 means the whole spi transaction is done.
> + */
> +static void dw_spi_dma_done(void *arg)
> +{
> +	struct dw_spi *dws = arg;
> +
> +	if (++dws->dma_chan_done != 2)
> +		return;
> +	dw_spi_xfer_done(dws);
> +}
> +
> +static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
> +{
> +	struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL;
> +	struct dma_chan *txchan, *rxchan;
> +	struct dma_slave_config txconf, rxconf;
> +	u16 dma_ctrl = 0;
> +
> +	/* 1. setup DMA related registers */
> +	if (cs_change) {
> +		spi_enable_chip(dws, 0);
> +		dw_writew(dws, dmardlr, 0xf);
> +		dw_writew(dws, dmatdlr, 0x10);
> +		if (dws->tx_dma)
> +			dma_ctrl |= 0x2;
> +		if (dws->rx_dma)
> +			dma_ctrl |= 0x1;
> +		dw_writew(dws, dmacr, dma_ctrl);
> +		spi_enable_chip(dws, 1);
> +	}
> +
> +	dws->dma_chan_done = 0;
> +	txchan = dws->txchan;
> +	rxchan = dws->rxchan;
> +
> +	/* 2. Prepare the TX dma transfer */
> +	txconf.direction = DMA_TO_DEVICE;
> +	txconf.dst_addr = dws->dma_addr;
> +	txconf.dst_maxburst = LNW_DMA_MSIZE_16;
> +	txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +	txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> +
> +	txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
> +				       (unsigned long) &txconf);
> +
> +	memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl));
> +	dws->tx_sgl.dma_address = dws->tx_dma;
> +	dws->tx_sgl.length = dws->len;
> +
> +	txdesc = txchan->device->device_prep_slave_sg(txchan,
> +				&dws->tx_sgl,
> +				1,
> +				DMA_TO_DEVICE,
> +				DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP);
> +	txdesc->callback = dw_spi_dma_done;
> +	txdesc->callback_param = dws;
> +
> +	/* 3. Prepare the RX dma transfer */
> +	rxconf.direction = DMA_FROM_DEVICE;
> +	rxconf.src_addr = dws->dma_addr;
> +	rxconf.src_maxburst = LNW_DMA_MSIZE_16;
> +	rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +	rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> +
> +	rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG,
> +				       (unsigned long) &rxconf);
> +
> +	memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl));
> +	dws->rx_sgl.dma_address = dws->rx_dma;
> +	dws->rx_sgl.length = dws->len;
> +
> +	rxdesc = rxchan->device->device_prep_slave_sg(rxchan,
> +				&dws->rx_sgl,
> +				1,
> +				DMA_FROM_DEVICE,
> +				DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP);
> +	rxdesc->callback = dw_spi_dma_done;
> +	rxdesc->callback_param = dws;
> +
> +	/* rx must be started before tx due to spi instinct */
> +	rxdesc->tx_submit(rxdesc);
> +	txdesc->tx_submit(txdesc);
> +	return 0;
> +}
> +
> +static struct dw_spi_dma_ops mid_dma_ops = {
> +	.dma_init	= mid_spi_dma_init,
> +	.dma_exit	= mid_spi_dma_exit,
> +	.dma_transfer	= mid_spi_dma_transfer,
> +};
> +#endif
> +
> +/* Some specific info for SPI0 controller on Moorestown */
> +
> +/* HW info for MRST CLk Control Unit, one 32b reg */
> +#define MRST_SPI_CLK_BASE	100000000	/* 100m */
> +#define MRST_CLK_SPI0_REG	0xff11d86c
> +#define CLK_SPI_BDIV_OFFSET	0
> +#define CLK_SPI_BDIV_MASK	0x00000007
> +#define CLK_SPI_CDIV_OFFSET	9
> +#define CLK_SPI_CDIV_MASK	0x00000e00
> +#define CLK_SPI_DISABLE_OFFSET	8
> +
> +int dw_spi_mid_init(struct dw_spi *dws)
> +{
> +	u32 *clk_reg, clk_cdiv;
> +
> +	clk_reg = ioremap_nocache(MRST_CLK_SPI0_REG, 16);
> +	if (!clk_reg)
> +		return -ENOMEM;
> +
> +	/* get SPI controller operating freq info */
> +	clk_cdiv  = (readl(clk_reg) & CLK_SPI_CDIV_MASK) >> CLK_SPI_CDIV_OFFSET;
> +	dws->max_freq = MRST_SPI_CLK_BASE / (clk_cdiv + 1);
> +	iounmap(clk_reg);
> +
> +	dws->num_cs = 16;
> +	dws->fifo_len = 40;	/* FIFO has 40 words buffer */
> +
> +#ifdef CONFIG_SPI_DW_MID_DMA
> +	dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL);
> +	if (!dws->dma_priv)
> +		return -ENOMEM;
> +	dws->dma_ops = &mid_dma_ops;
> +#endif
> +	return 0;
> +}
> +
> diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c
> index 1f52755..49ec3aa 100644
> --- a/drivers/spi/dw_spi_pci.c
> +++ b/drivers/spi/dw_spi_pci.c
> @@ -1,5 +1,5 @@
>  /*
> - * mrst_spi_pci.c - PCI interface driver for DW SPI Core
> + * dw_spi_pci.c - PCI interface driver for DW SPI Core
>   *
>   * Copyright (c) 2009, Intel Corporation.
>   *
> @@ -26,8 +26,8 @@
>  #define DRIVER_NAME "dw_spi_pci"
>  
>  struct dw_spi_pci {
> -	struct pci_dev		*pdev;
> -	struct dw_spi		dws;
> +	struct pci_dev	*pdev;
> +	struct dw_spi	dws;
>  };
>  
>  static int __devinit spi_pci_probe(struct pci_dev *pdev,
> @@ -72,9 +72,17 @@ static int __devinit spi_pci_probe(struct pci_dev *pdev,
>  	dws->parent_dev = &pdev->dev;
>  	dws->bus_num = 0;
>  	dws->num_cs = 4;
> -	dws->max_freq = 25000000;	/* for Moorestwon */
>  	dws->irq = pdev->irq;
> -	dws->fifo_len = 40;		/* FIFO has 40 words buffer */
> +
> +	/*
> +	 * Specific handling for Intel MID paltforms, like dma setup,
> +	 * clock rate, FIFO depth.
> +	 */
> +	if (pdev->device == 0x0800) {
> +		ret = dw_spi_mid_init(dws);
> +		if (ret)
> +			goto err_unmap;
> +	}
>  
>  	ret = dw_spi_add_host(dws);
>  	if (ret)
> @@ -140,7 +148,7 @@ static int spi_resume(struct pci_dev *pdev)
>  #endif
>  
>  static const struct pci_device_id pci_ids[] __devinitdata = {
> -	/* Intel Moorestown platform SPI controller 0 */
> +	/* Intel MID platform SPI controller 0 */
>  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },
>  	{},
>  };
> diff --git a/include/linux/spi/dw_spi.h b/include/linux/spi/dw_spi.h
> index c91302f..6cd10f6 100644
> --- a/include/linux/spi/dw_spi.h
> +++ b/include/linux/spi/dw_spi.h
> @@ -1,5 +1,6 @@
>  #ifndef DW_SPI_HEADER_H
>  #define DW_SPI_HEADER_H
> +
>  #include <linux/io.h>
>  
>  /* Bit fields in CTRLR0 */
> @@ -82,6 +83,13 @@ struct dw_spi_reg {
>  				though only low 16 bits matters */
>  } __packed;
>  
> +struct dw_spi;
> +struct dw_spi_dma_ops {
> +	int (*dma_init)(struct dw_spi *dws);
> +	void (*dma_exit)(struct dw_spi *dws);
> +	int (*dma_transfer)(struct dw_spi *dws, int cs_change);
> +};
> +
>  struct dw_spi {
>  	struct spi_master	*master;
>  	struct spi_device	*cur_dev;
> @@ -136,13 +144,15 @@ struct dw_spi {
>  	/* Dma info */
>  	int			dma_inited;
>  	struct dma_chan		*txchan;
> +	struct scatterlist	tx_sgl;
>  	struct dma_chan		*rxchan;
> -	int			txdma_done;
> -	int			rxdma_done;
> -	u64			tx_param;
> -	u64			rx_param;
> +	struct scatterlist	rx_sgl;
> +	int			dma_chan_done;
>  	struct device		*dma_dev;
> -	dma_addr_t		dma_addr;
> +	dma_addr_t		dma_addr; /* phy address of the Data register */
> +	struct dw_spi_dma_ops	*dma_ops;
> +	void			*dma_priv; /* platform relate info */
> +	struct pci_dev		*dmac;
>  
>  	/* Bus interface info */
>  	void			*priv;
> @@ -216,4 +226,8 @@ extern int dw_spi_add_host(struct dw_spi *dws);
>  extern void dw_spi_remove_host(struct dw_spi *dws);
>  extern int dw_spi_suspend_host(struct dw_spi *dws);
>  extern int dw_spi_resume_host(struct dw_spi *dws);
> +extern void dw_spi_xfer_done(struct dw_spi *dws);
> +
> +/* platform related setup */
> +extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */
>  #endif /* DW_SPI_HEADER_H */
> -- 
> 1.7.0.4
> 

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl

  parent reply	other threads:[~2010-12-24  8:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-24  5:59 [Patch v2 1/3] spi/dw_spi: Fix too short timeout in spi polling loop Feng Tang
     [not found] ` <1293170351-7426-1-git-send-email-feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2010-12-24  5:59   ` [Patch v2 2/3] spi/dw_spi: change to EXPORT_SYMBOL_GPL for exported APIs Feng Tang
     [not found]     ` <1293170351-7426-2-git-send-email-feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2010-12-24  8:11       ` Grant Likely
2010-12-24  5:59   ` [Patch v2 3/3] spi/dw_spi: add DMA support Feng Tang
     [not found]     ` <1293170351-7426-3-git-send-email-feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2010-12-24  8:12       ` Grant Likely [this message]
2010-12-24  8:10   ` [Patch v2 1/3] spi/dw_spi: Fix too short timeout in spi polling loop Grant Likely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101224081214.GC5544@angua.secretlab.ca \
    --to=grant.likely-s3s/wqlpoipyb63q8fvjnq@public.gmane.org \
    --cc=alan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=feng.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    --cc=linus.walleij-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org \
    --cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).