* [PATCH 00/30] ARM: exynos multiplatform support @ 2013-04-11 0:04 Arnd Bergmann 2013-04-11 0:05 ` [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API Arnd Bergmann 0 siblings, 1 reply; 8+ messages in thread From: Arnd Bergmann @ 2013-04-11 0:04 UTC (permalink / raw) To: linux-arm-kernel Cc: linux-kernel, Kukjin Kim, linux-samsung-soc, Arnd Bergmann, stern, a.zummo, ben-linux, cjb, dwmw2, grant.likely, gregkh, jg1.han, john.stultz, broonie, mchehab, mturquette, padma.kvr, thierry.reding, tglx, t.figa, wsa, rui.zhang, alsa-devel, linux-fbdev, linux-i2c, linux-media, linux-mmc, linux-mtd, linux-pm, linux-serial, linux-usb, rtc-linux, spi-devel-general Hi everyone, I have updated my series for multiplatform support of the ARM exynos platform, based on what is currently queued up in arm-soc. It would be really nice to still get this merged for 3.10. A lot of the patches are really trivial, but there are some complex ones as well. To all subsystem maintainers: feel free to directly apply the patches for your subsystem, there should be no dependencies between any of them, aside from the last patch requiring all of the earlier ones to be applied first. Getting an Ack is also fine so we can put the patches into arm-soc. Arnd Arnd Bergmann (30): ARM: exynos: introduce EXYNOS_ATAGS symbol ARM: exynos: prepare for sparse IRQ ARM: exynos: move debug-macro.S to include/debug/ ARM: samsung: move mfc device definition to s5p-dev-mfc.c tty: serial/samsung: prepare for common clock API tty: serial/samsung: make register definitions global tty: serial/samsung: fix modular build i2c: s3c2410: make header file local mmc: sdhci-s3c: remove platform dependencies usb: exynos: do not include plat/usb-phy.h [media] exynos: remove unnecessary header inclusions video/exynos: remove unnecessary header inclusions video/s3c: move platform_data out of arch/arm thermal/exynos: remove unnecessary header inclusions mtd: onenand/samsung: make regs-onenand.h file local rtc: s3c: make header file local pwm: samsung: repair the worst MMIO abuses ASoC: samsung: move plat/ headers to local directory ASoC: samsung: use irq resource for idma ASoC: samsung: convert to dmaengine API ASoC: samsung/i2s: fix module_device_table ASoC: samsung/idma: export idma_reg_addr_init clk: exynos: prepare for multiplatform clocksource: exynos_mct: remove platform header dependency irqchip: exynos: pass max combiner number to combiner_init irqchip: exynos: allocate combiner_data dynamically irqchip: exynos: localize irq lookup for ATAGS irqchip: exynos: pass irq_base from platform spi: s3c64xx: move to generic dmaengine API ARM: exynos: enable multiplatform support arch/arm/Kconfig | 10 +- arch/arm/Kconfig.debug | 8 + arch/arm/configs/exynos4_defconfig | 2 +- .../mach/debug-macro.S => include/debug/exynos.S} | 12 +- .../plat/debug-macro.S => include/debug/samsung.S} | 2 +- arch/arm/mach-exynos/Kconfig | 40 ++- arch/arm/mach-exynos/Makefile | 5 +- arch/arm/mach-exynos/common.c | 26 +- arch/arm/mach-exynos/common.h | 7 +- arch/arm/mach-exynos/dev-uart.c | 1 + arch/arm/mach-exynos/include/mach/irqs.h | 5 +- arch/arm/mach-exynos/mach-armlex4210.c | 2 + arch/arm/mach-exynos/mach-exynos4-dt.c | 3 + arch/arm/mach-exynos/mach-exynos5-dt.c | 2 + arch/arm/mach-exynos/mach-nuri.c | 2 + arch/arm/mach-exynos/mach-origen.c | 2 + arch/arm/mach-exynos/mach-smdk4x12.c | 2 + arch/arm/mach-exynos/mach-smdkv310.c | 3 + arch/arm/mach-exynos/setup-sdhci-gpio.c | 2 +- arch/arm/mach-exynos/setup-usb-phy.c | 8 +- arch/arm/mach-s3c24xx/clock-s3c2440.c | 5 + arch/arm/mach-s3c24xx/common.c | 5 + arch/arm/mach-s3c24xx/dma-s3c2410.c | 2 - arch/arm/mach-s3c24xx/dma-s3c2412.c | 2 - arch/arm/mach-s3c24xx/dma-s3c2440.c | 2 - arch/arm/mach-s3c24xx/dma-s3c2443.c | 2 - arch/arm/mach-s3c24xx/include/mach/debug-macro.S | 2 +- arch/arm/mach-s3c24xx/mach-rx1950.c | 1 - arch/arm/mach-s3c64xx/include/mach/debug-macro.S | 2 +- arch/arm/mach-s3c64xx/setup-usb-phy.c | 4 +- arch/arm/mach-s5p64x0/include/mach/debug-macro.S | 2 +- arch/arm/mach-s5pc100/include/mach/debug-macro.S | 2 +- arch/arm/mach-s5pc100/setup-sdhci-gpio.c | 1 - arch/arm/mach-s5pv210/include/mach/debug-macro.S | 2 +- arch/arm/mach-s5pv210/setup-sdhci-gpio.c | 1 - arch/arm/mach-s5pv210/setup-usb-phy.c | 4 +- arch/arm/plat-samsung/Kconfig | 7 +- arch/arm/plat-samsung/Makefile | 8 +- arch/arm/plat-samsung/devs.c | 62 ++--- arch/arm/plat-samsung/include/plat/fb.h | 50 +--- arch/arm/plat-samsung/include/plat/pm.h | 5 + arch/arm/plat-samsung/include/plat/regs-serial.h | 282 +-------------------- arch/arm/plat-samsung/include/plat/sdhci.h | 56 +--- arch/arm/plat-samsung/include/plat/usb-phy.h | 5 +- arch/arm/plat-samsung/irq-vic-timer.c | 1 + arch/arm/plat-samsung/pm.c | 1 + arch/arm/plat-samsung/s5p-dev-mfc.c | 42 ++- arch/arm/plat-samsung/s5p-irq.c | 1 + drivers/clk/samsung/clk-exynos4.c | 93 +++---- drivers/clk/samsung/clk-exynos5250.c | 1 - drivers/clk/samsung/clk-exynos5440.c | 1 - drivers/clk/samsung/clk.h | 2 - drivers/clocksource/exynos_mct.c | 21 +- drivers/gpio/Makefile | 2 +- drivers/i2c/busses/i2c-s3c2410.c | 3 +- .../regs-iic.h => drivers/i2c/busses/i2c-s3c2410.h | 0 drivers/irqchip/exynos-combiner.c | 116 +++++---- drivers/media/platform/exynos-gsc/gsc-regs.c | 1 - drivers/media/platform/s5p-tv/sii9234_drv.c | 3 - drivers/mmc/host/Kconfig | 2 +- .../mmc/host/sdhci-s3c-regs.h | 0 drivers/mmc/host/sdhci-s3c.c | 5 +- drivers/mtd/onenand/samsung.c | 4 +- .../mtd/onenand/samsung.h | 2 - drivers/pwm/pwm-samsung.c | 60 +++-- drivers/rtc/rtc-s3c.c | 3 +- .../plat/regs-rtc.h => drivers/rtc/rtc-s3c.h | 3 +- drivers/spi/spi-s3c64xx.c | 185 ++++++++++---- drivers/thermal/exynos_thermal.c | 2 - drivers/tty/serial/samsung.c | 17 +- drivers/tty/serial/samsung.h | 4 +- drivers/usb/host/ehci-s5p.c | 1 - drivers/usb/host/ohci-exynos.c | 1 - drivers/video/exynos/exynos_mipi_dsi.c | 2 - drivers/video/exynos/exynos_mipi_dsi_common.c | 2 - drivers/video/exynos/exynos_mipi_dsi_lowlevel.c | 2 - drivers/video/s3c-fb.c | 3 +- include/linux/platform_data/mmc-sdhci-s3c.h | 56 ++++ include/linux/platform_data/spi-s3c64xx.h | 3 + include/linux/platform_data/video_s3c.h | 54 ++++ include/linux/serial_s3c.h | 260 +++++++++++++++++++ sound/soc/samsung/ac97.c | 2 +- sound/soc/samsung/dma.c | 219 ++++++++++++++++ sound/soc/samsung/dma.h | 15 +- sound/soc/samsung/h1940_uda1380.c | 2 +- sound/soc/samsung/i2s.c | 4 +- sound/soc/samsung/idma.c | 11 +- sound/soc/samsung/neo1973_wm8753.c | 2 +- sound/soc/samsung/pcm.c | 1 - .../include/plat => sound/soc/samsung}/regs-ac97.h | 0 .../include/plat => sound/soc/samsung}/regs-iis.h | 0 sound/soc/samsung/rx1950_uda1380.c | 2 +- sound/soc/samsung/s3c24xx-i2s.c | 2 +- sound/soc/samsung/s3c24xx_uda134x.c | 2 +- sound/soc/samsung/spdif.c | 1 - 95 files changed, 1146 insertions(+), 734 deletions(-) rename arch/arm/{mach-exynos/include/mach/debug-macro.S => include/debug/exynos.S} (84%) rename arch/arm/{plat-samsung/include/plat/debug-macro.S => include/debug/samsung.S} (98%) rename arch/arm/plat-samsung/include/plat/regs-iic.h => drivers/i2c/busses/i2c-s3c2410.h (100%) rename arch/arm/plat-samsung/include/plat/regs-sdhci.h => drivers/mmc/host/sdhci-s3c-regs.h (100%) rename arch/arm/plat-samsung/include/plat/regs-onenand.h => drivers/mtd/onenand/samsung.h (98%) rename arch/arm/plat-samsung/include/plat/regs-rtc.h => drivers/rtc/rtc-s3c.h (97%) create mode 100644 include/linux/platform_data/mmc-sdhci-s3c.h create mode 100644 include/linux/platform_data/video_s3c.h create mode 100644 include/linux/serial_s3c.h rename {arch/arm/plat-samsung/include/plat => sound/soc/samsung}/regs-ac97.h (100%) rename {arch/arm/plat-samsung/include/plat => sound/soc/samsung}/regs-iis.h (100%) -- 1.8.1.2 Cc: stern@rowland.harvard.edu Cc: a.zummo@towertech.it Cc: ben-linux@fluff.org Cc: cjb@laptop.org Cc: dwmw2@infradead.org Cc: grant.likely@secretlab.ca Cc: gregkh@linuxfoundation.org Cc: jg1.han@samsung.com Cc: john.stultz@linaro.org Cc: broonie@opensource.wolfsonmicro.com Cc: mchehab@redhat.com Cc: mturquette@linaro.org Cc: padma.kvr@gmail.com Cc: thierry.reding@avionic-design.de Cc: tglx@linutronix.de Cc: t.figa@samsung.com Cc: wsa@the-dreams.de Cc: rui.zhang@intel.com Cc: alsa-devel@alsa-project.org Cc: linux-fbdev@vger.kernel.org Cc: linux-i2c@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: linux-mmc@vger.kernel.org Cc: linux-mtd@lists.infradead.org Cc: linux-pm@vger.kernel.org Cc: linux-serial@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: rtc-linux@googlegroups.com Cc: spi-devel-general@lists.sourceforge.net . ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API 2013-04-11 0:04 [PATCH 00/30] ARM: exynos multiplatform support Arnd Bergmann @ 2013-04-11 0:05 ` Arnd Bergmann 2013-04-11 16:55 ` Mark Brown 2013-04-17 20:05 ` [PATCH 29/30] " Arnd Bergmann 0 siblings, 2 replies; 8+ messages in thread From: Arnd Bergmann @ 2013-04-11 0:05 UTC (permalink / raw) To: linux-arm-kernel Cc: linux-kernel, Kukjin Kim, linux-samsung-soc, Arnd Bergmann, spi-devel-general, Mark Brown, Grant Likely, Padma Venkat The spi-s3c64xx uses a Samsung proprietary interface for talking to the DMA engine, which does not work with multiplatform kernels. This version of the patch leaves the old code in place, behind an #ifdef. This can be removed in the future, after the s3c64xx platform start supporting the regular dmaengine interface. An earlier version of this patch was tested successfully on exynos5250 by Padma Venkat. The conversion was rather mechanical, since the samsung interface is just a shallow wrapper around the dmaengine interface. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: spi-devel-general@lists.sourceforge.net Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Padma Venkat <padma.kvr@gmail.com> --- arch/arm/plat-samsung/devs.c | 10 ++ drivers/spi/spi-s3c64xx.c | 185 +++++++++++++++++++++++------- include/linux/platform_data/spi-s3c64xx.h | 3 + 3 files changed, 154 insertions(+), 44 deletions(-) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index b441908..30c2fe2 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include <linux/amba/pl330.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -1512,6 +1513,9 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); } @@ -1550,6 +1554,9 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); } @@ -1588,6 +1595,9 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); } diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 4188b2f..74809af 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> @@ -31,9 +32,12 @@ #include <linux/of.h> #include <linux/of_gpio.h> -#include <mach/dma.h> #include <linux/platform_data/spi-s3c64xx.h> +#ifdef CONFIG_SAMSUNG_DMADEV +#include <mach/dma.h> +#endif + #define MAX_SPI_PORTS 3 /* Registers and bit-fields */ @@ -131,9 +135,9 @@ #define TXBUSY (1<<3) struct s3c64xx_spi_dma_data { - unsigned ch; + struct dma_chan *ch; enum dma_transfer_direction direction; - enum dma_ch dmach; + unsigned int dmach; }; /** @@ -195,16 +199,14 @@ struct s3c64xx_spi_driver_data { unsigned cur_speed; struct s3c64xx_spi_dma_data rx_dma; struct s3c64xx_spi_dma_data tx_dma; +#ifdef CONFIG_SAMSUNG_DMADEV struct samsung_dma_ops *ops; +#endif struct s3c64xx_spi_port_config *port_conf; unsigned int port_id; unsigned long gpios[4]; }; -static struct s3c2410_dma_client s3c64xx_spi_dma_client = { - .name = "samsung-spi-dma", -}; - static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) { void __iomem *regs = sdd->regs; @@ -281,6 +283,13 @@ static void s3c64xx_spi_dmacb(void *data) spin_unlock_irqrestore(&sdd->lock, flags); } +#ifdef CONFIG_SAMSUNG_DMADEV +/* FIXME: remove this section once arch/arm/mach-s3c64xx uses dmaengine */ + +static struct s3c2410_dma_client s3c64xx_spi_dma_client = { + .name = "samsung-spi-dma", +}; + static void prepare_dma(struct s3c64xx_spi_dma_data *dma, unsigned len, dma_addr_t buf) { @@ -294,14 +303,14 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, config.direction = sdd->rx_dma.direction; config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; config.width = sdd->cur_bpw / 8; - sdd->ops->config(sdd->rx_dma.ch, &config); + sdd->ops->config((enum dma_ch)sdd->rx_dma.ch, &config); } else { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, tx_dma); config.direction = sdd->tx_dma.direction; config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; config.width = sdd->cur_bpw / 8; - sdd->ops->config(sdd->tx_dma.ch, &config); + sdd->ops->config((enum dma_ch)sdd->tx_dma.ch, &config); } info.cap = DMA_SLAVE; @@ -311,8 +320,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, info.direction = dma->direction; info.buf = buf; - sdd->ops->prepare(dma->ch, &info); - sdd->ops->trigger(dma->ch); + sdd->ops->prepare((enum dma_ch)dma->ch, &info); + sdd->ops->trigger((enum dma_ch)dma->ch); } static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) @@ -325,12 +334,126 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; - sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); - sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); + sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); + sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); return 1; } +static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Acquire DMA channels */ + while (!acquire_dma(sdd)) + usleep_range(10000, 11000); + + pm_runtime_get_sync(&sdd->pdev->dev); + + return 0; +} + +static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Free DMA channels */ + sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, &s3c64xx_spi_dma_client); + sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, &s3c64xx_spi_dma_client); + + pm_runtime_put(&sdd->pdev->dev); + + return 0; +} + +static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, + struct s3c64xx_spi_dma_data *dma) +{ + sdd->ops->stop((enum dma_ch)dma->ch); +} +#else + +static void prepare_dma(struct s3c64xx_spi_dma_data *dma, + unsigned len, dma_addr_t buf) +{ + struct s3c64xx_spi_driver_data *sdd; + struct dma_slave_config config; + struct scatterlist sg; + struct dma_async_tx_descriptor *desc; + + if (dma->direction == DMA_DEV_TO_MEM) { + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); + config.direction = dma->direction; + config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + config.src_addr_width = sdd->cur_bpw / 8; + config.src_maxburst = 1; + dmaengine_slave_config(dma->ch, &config); + } else { + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); + config.direction = dma->direction; + config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + config.dst_addr_width = sdd->cur_bpw / 8; + config.dst_maxburst = 1; + dmaengine_slave_config(dma->ch, &config); + } + + sg_init_table(&sg, 1); + sg_dma_len(&sg) = len; + sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), + len, offset_in_page(buf)); + sg_dma_address(&sg) = buf; + + desc = dmaengine_prep_slave_sg(dma->ch, + &sg, 1, dma->direction, DMA_PREP_INTERRUPT); + + desc->callback = s3c64xx_spi_dmacb; + desc->callback_param = dma; + + dmaengine_submit(desc); + dma_async_issue_pending(dma->ch); +} + +static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + dma_filter_fn filter = sdd->cntrlr_info->filter; + struct device *dev = &sdd->pdev->dev; + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* Acquire DMA channels */ + sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void*)sdd->rx_dma.dmach, dev, "rx"); + sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void*)sdd->tx_dma.dmach, dev, "tx"); + pm_runtime_get_sync(&sdd->pdev->dev); + + return 0; +} + +static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Free DMA channels */ + dma_release_channel(sdd->rx_dma.ch); + dma_release_channel(sdd->tx_dma.ch); + + pm_runtime_put(&sdd->pdev->dev); + return 0; +} + +static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, + struct s3c64xx_spi_dma_data *dma) +{ + dmaengine_terminate_all(dma->ch); +} +#endif + static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, struct spi_device *spi, struct spi_transfer *xfer, int dma_mode) @@ -713,9 +836,9 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, } /* Polling method for xfers not bigger than FIFO capacity */ - if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) - use_dma = 0; - else + use_dma = 0; + if (sdd->rx_dma.ch && sdd->tx_dma.ch && + (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))) use_dma = 1; spin_lock_irqsave(&sdd->lock, flags); @@ -750,10 +873,10 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, if (use_dma) { if (xfer->tx_buf != NULL && (sdd->state & TXBUSY)) - sdd->ops->stop(sdd->tx_dma.ch); + s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); if (xfer->rx_buf != NULL && (sdd->state & RXBUSY)) - sdd->ops->stop(sdd->rx_dma.ch); + s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); } goto out; @@ -790,32 +913,6 @@ out: return 0; } -static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - - /* Acquire DMA channels */ - while (!acquire_dma(sdd)) - usleep_range(10000, 11000); - - pm_runtime_get_sync(&sdd->pdev->dev); - - return 0; -} - -static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - - /* Free DMA channels */ - sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); - sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); - - pm_runtime_put(&sdd->pdev->dev); - - return 0; -} - static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( struct s3c64xx_spi_driver_data *sdd, struct spi_device *spi) diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index ceba18d..8447f63 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -11,6 +11,8 @@ #ifndef __S3C64XX_PLAT_SPI_H #define __S3C64XX_PLAT_SPI_H +#include <linux/dmaengine.h> + struct platform_device; /** @@ -38,6 +40,7 @@ struct s3c64xx_spi_info { int src_clk_nr; int num_cs; int (*cfg_gpio)(void); + dma_filter_fn filter; }; /** -- 1.8.1.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API 2013-04-11 0:05 ` [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API Arnd Bergmann @ 2013-04-11 16:55 ` Mark Brown [not found] ` <20130411165536.GO9243-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> 2013-04-17 20:05 ` [PATCH 29/30] " Arnd Bergmann 1 sibling, 1 reply; 8+ messages in thread From: Mark Brown @ 2013-04-11 16:55 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, linux-kernel, Kukjin Kim, linux-samsung-soc, spi-devel-general, Grant Likely, Padma Venkat [-- Attachment #1: Type: text/plain, Size: 275 bytes --] On Thu, Apr 11, 2013 at 02:05:11AM +0200, Arnd Bergmann wrote: > The spi-s3c64xx uses a Samsung proprietary interface for > talking to the DMA engine, which does not work with > multiplatform kernels. This doesn't apply against my spi-next, can you please check and resend? [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <20130411165536.GO9243-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>]
* [PATCH v2] spi: s3c64xx: move to generic dmaengine API [not found] ` <20130411165536.GO9243-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> @ 2013-04-11 20:42 ` Arnd Bergmann 2013-04-12 12:55 ` Mark Brown 2013-04-17 14:46 ` Mark Brown 0 siblings, 2 replies; 8+ messages in thread From: Arnd Bergmann @ 2013-04-11 20:42 UTC (permalink / raw) To: Mark Brown Cc: linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Kukjin Kim, Padma Venkat, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r The spi-s3c64xx uses a Samsung proprietary interface for talking to the DMA engine, which does not work with multiplatform kernels. This version of the patch leaves the old code in place, behind an #ifdef. This can be removed in the future, after the s3c64xx platform start supporting the regular dmaengine interface. An earlier version of this patch was tested successfully on exynos5250 by Padma Venkat. The conversion was rather mechanical, since the samsung interface is just a shallow wrapper around the dmaengine interface. Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Cc: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> Cc: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> Cc: Padma Venkat <padma.kvr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> ---- v2: rebased to git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git spi-next diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 51afedd..03db14d 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include <linux/amba/pl330.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -1552,6 +1553,9 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); } @@ -1590,6 +1594,9 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); } @@ -1628,6 +1635,9 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; +#ifdef CONFIG_PL330_DMA + pd.filter = pl330_filter; +#endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); } diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 682b1e7..4989aeb 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> @@ -31,9 +32,12 @@ #include <linux/of.h> #include <linux/of_gpio.h> -#include <mach/dma.h> #include <linux/platform_data/spi-s3c64xx.h> +#ifdef CONFIG_SAMSUNG_DMADEV +#include <mach/dma.h> +#endif + #define MAX_SPI_PORTS 3 /* Registers and bit-fields */ @@ -131,9 +135,9 @@ #define TXBUSY (1<<3) struct s3c64xx_spi_dma_data { - unsigned ch; + struct dma_chan *ch; enum dma_transfer_direction direction; - enum dma_ch dmach; + unsigned int dmach; }; /** @@ -195,16 +199,14 @@ struct s3c64xx_spi_driver_data { unsigned cur_speed; struct s3c64xx_spi_dma_data rx_dma; struct s3c64xx_spi_dma_data tx_dma; +#ifdef CONFIG_SAMSUNG_DMADEV struct samsung_dma_ops *ops; +#endif struct s3c64xx_spi_port_config *port_conf; unsigned int port_id; unsigned long gpios[4]; }; -static struct s3c2410_dma_client s3c64xx_spi_dma_client = { - .name = "samsung-spi-dma", -}; - static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) { void __iomem *regs = sdd->regs; @@ -281,6 +283,13 @@ static void s3c64xx_spi_dmacb(void *data) spin_unlock_irqrestore(&sdd->lock, flags); } +#ifdef CONFIG_SAMSUNG_DMADEV +/* FIXME: remove this section once arch/arm/mach-s3c64xx uses dmaengine */ + +static struct s3c2410_dma_client s3c64xx_spi_dma_client = { + .name = "samsung-spi-dma", +}; + static void prepare_dma(struct s3c64xx_spi_dma_data *dma, unsigned len, dma_addr_t buf) { @@ -294,14 +303,14 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, config.direction = sdd->rx_dma.direction; config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; config.width = sdd->cur_bpw / 8; - sdd->ops->config(sdd->rx_dma.ch, &config); + sdd->ops->config((enum dma_ch)sdd->rx_dma.ch, &config); } else { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, tx_dma); config.direction = sdd->tx_dma.direction; config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; config.width = sdd->cur_bpw / 8; - sdd->ops->config(sdd->tx_dma.ch, &config); + sdd->ops->config((enum dma_ch)sdd->tx_dma.ch, &config); } info.cap = DMA_SLAVE; @@ -311,8 +320,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, info.direction = dma->direction; info.buf = buf; - sdd->ops->prepare(dma->ch, &info); - sdd->ops->trigger(dma->ch); + sdd->ops->prepare((enum dma_ch)dma->ch, &info); + sdd->ops->trigger((enum dma_ch)dma->ch); } static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) @@ -325,12 +334,126 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) req.cap = DMA_SLAVE; req.client = &s3c64xx_spi_dma_client; - sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); - sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); + sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx"); + sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx"); return 1; } +static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Acquire DMA channels */ + while (!acquire_dma(sdd)) + usleep_range(10000, 11000); + + pm_runtime_get_sync(&sdd->pdev->dev); + + return 0; +} + +static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Free DMA channels */ + sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, &s3c64xx_spi_dma_client); + sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, &s3c64xx_spi_dma_client); + + pm_runtime_put(&sdd->pdev->dev); + + return 0; +} + +static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, + struct s3c64xx_spi_dma_data *dma) +{ + sdd->ops->stop((enum dma_ch)dma->ch); +} +#else + +static void prepare_dma(struct s3c64xx_spi_dma_data *dma, + unsigned len, dma_addr_t buf) +{ + struct s3c64xx_spi_driver_data *sdd; + struct dma_slave_config config; + struct scatterlist sg; + struct dma_async_tx_descriptor *desc; + + if (dma->direction == DMA_DEV_TO_MEM) { + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); + config.direction = dma->direction; + config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + config.src_addr_width = sdd->cur_bpw / 8; + config.src_maxburst = 1; + dmaengine_slave_config(dma->ch, &config); + } else { + sdd = container_of((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); + config.direction = dma->direction; + config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + config.dst_addr_width = sdd->cur_bpw / 8; + config.dst_maxburst = 1; + dmaengine_slave_config(dma->ch, &config); + } + + sg_init_table(&sg, 1); + sg_dma_len(&sg) = len; + sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), + len, offset_in_page(buf)); + sg_dma_address(&sg) = buf; + + desc = dmaengine_prep_slave_sg(dma->ch, + &sg, 1, dma->direction, DMA_PREP_INTERRUPT); + + desc->callback = s3c64xx_spi_dmacb; + desc->callback_param = dma; + + dmaengine_submit(desc); + dma_async_issue_pending(dma->ch); +} + +static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + dma_filter_fn filter = sdd->cntrlr_info->filter; + struct device *dev = &sdd->pdev->dev; + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* Acquire DMA channels */ + sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void*)sdd->rx_dma.dmach, dev, "rx"); + sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, + (void*)sdd->tx_dma.dmach, dev, "tx"); + pm_runtime_get_sync(&sdd->pdev->dev); + + return 0; +} + +static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) +{ + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); + + /* Free DMA channels */ + dma_release_channel(sdd->rx_dma.ch); + dma_release_channel(sdd->tx_dma.ch); + + pm_runtime_put(&sdd->pdev->dev); + return 0; +} + +static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, + struct s3c64xx_spi_dma_data *dma) +{ + dmaengine_terminate_all(dma->ch); +} +#endif + static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, struct spi_device *spi, struct spi_transfer *xfer, int dma_mode) @@ -713,9 +836,9 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, } /* Polling method for xfers not bigger than FIFO capacity */ - if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) - use_dma = 0; - else + use_dma = 0; + if (sdd->rx_dma.ch && sdd->tx_dma.ch && + (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))) use_dma = 1; spin_lock_irqsave(&sdd->lock, flags); @@ -750,10 +873,10 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, if (use_dma) { if (xfer->tx_buf != NULL && (sdd->state & TXBUSY)) - sdd->ops->stop(sdd->tx_dma.ch); + s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); if (xfer->rx_buf != NULL && (sdd->state & RXBUSY)) - sdd->ops->stop(sdd->rx_dma.ch); + s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); } goto out; @@ -790,32 +913,6 @@ out: return 0; } -static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - - /* Acquire DMA channels */ - while (!acquire_dma(sdd)) - usleep_range(10000, 11000); - - pm_runtime_get_sync(&sdd->pdev->dev); - - return 0; -} - -static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); - - /* Free DMA channels */ - sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); - sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); - - pm_runtime_put(&sdd->pdev->dev); - - return 0; -} - static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( struct spi_device *spi) { diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index ceba18d..8447f63 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -11,6 +11,8 @@ #ifndef __S3C64XX_PLAT_SPI_H #define __S3C64XX_PLAT_SPI_H +#include <linux/dmaengine.h> + struct platform_device; /** @@ -38,6 +40,7 @@ struct s3c64xx_spi_info { int src_clk_nr; int num_cs; int (*cfg_gpio)(void); + dma_filter_fn filter; }; /** ------------------------------------------------------------------------------ Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis & visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] spi: s3c64xx: move to generic dmaengine API 2013-04-11 20:42 ` [PATCH v2] " Arnd Bergmann @ 2013-04-12 12:55 ` Mark Brown 2013-04-17 14:46 ` Mark Brown 1 sibling, 0 replies; 8+ messages in thread From: Mark Brown @ 2013-04-12 12:55 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, linux-kernel, Kukjin Kim, linux-samsung-soc, spi-devel-general, Grant Likely, Padma Venkat [-- Attachment #1: Type: text/plain, Size: 219 bytes --] On Thu, Apr 11, 2013 at 10:42:03PM +0200, Arnd Bergmann wrote: > The spi-s3c64xx uses a Samsung proprietary interface for > talking to the DMA engine, which does not work with > multiplatform kernels. Applied, thanks. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] spi: s3c64xx: move to generic dmaengine API 2013-04-11 20:42 ` [PATCH v2] " Arnd Bergmann 2013-04-12 12:55 ` Mark Brown @ 2013-04-17 14:46 ` Mark Brown 1 sibling, 0 replies; 8+ messages in thread From: Mark Brown @ 2013-04-17 14:46 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, linux-kernel, Kukjin Kim, linux-samsung-soc, spi-devel-general, Grant Likely, Padma Venkat [-- Attachment #1: Type: text/plain, Size: 441 bytes --] On Thu, Apr 11, 2013 at 10:42:03PM +0200, Arnd Bergmann wrote: > The spi-s3c64xx uses a Samsung proprietary interface for > talking to the DMA engine, which does not work with > multiplatform kernels. Actually it seems that this patch is causing issues for bulk SPI transfers on s3c64xx, especially when they're driven quickly one after another. I've only just found the problem so I've not been able to debug yet but a revert fixes it... [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API 2013-04-11 0:05 ` [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API Arnd Bergmann 2013-04-11 16:55 ` Mark Brown @ 2013-04-17 20:05 ` Arnd Bergmann 2013-04-18 16:46 ` Mark Brown 1 sibling, 1 reply; 8+ messages in thread From: Arnd Bergmann @ 2013-04-17 20:05 UTC (permalink / raw) To: linux-arm-kernel Cc: linux-kernel, Kukjin Kim, linux-samsung-soc, spi-devel-general, Mark Brown, Grant Likely, Padma Venkat On Thursday 11 April 2013, Arnd Bergmann wrote: > @@ -713,9 +836,9 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, > } > > /* Polling method for xfers not bigger than FIFO capacity */ > - if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) > - use_dma = 0; > - else > + use_dma = 0; > + if (sdd->rx_dma.ch && sdd->tx_dma.ch && > + (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))) > use_dma = 1; > > spin_lock_irqsave(&sdd->lock, flags); Can you try just reverting this hunk? It's actually not required and comes from an earlier version of the patch. I assumed it was harmless, but it's the only think I see that should actually make a difference in my patch for the case of !CONFIG_SAMSUNG_DMADEV. Arnd ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API 2013-04-17 20:05 ` [PATCH 29/30] " Arnd Bergmann @ 2013-04-18 16:46 ` Mark Brown 0 siblings, 0 replies; 8+ messages in thread From: Mark Brown @ 2013-04-18 16:46 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, linux-kernel, Kukjin Kim, linux-samsung-soc, spi-devel-general, Grant Likely, Padma Venkat [-- Attachment #1: Type: text/plain, Size: 994 bytes --] On Wed, Apr 17, 2013 at 10:05:35PM +0200, Arnd Bergmann wrote: > On Thursday 11 April 2013, Arnd Bergmann wrote: > > + use_dma = 0; > > + if (sdd->rx_dma.ch && sdd->tx_dma.ch && > > + (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))) > > use_dma = 1; > Can you try just reverting this hunk? It's actually not required and > comes from an earlier version of the patch. I assumed it was harmless, > but it's the only think I see that should actually make a difference > in my patch for the case of !CONFIG_SAMSUNG_DMADEV. That's not it, the checks are now needed - otherwise we get a null pointer dereference in prepare_dma() instead. What's actually gone wrong is that your ifdefs are for SAMSUNG_DMADEV instead of S3C_DMA so s3c64xx is trying to use dmaengine. The driver doesn't actually check to see if it failed to get the channels so it then tries to do the transfer with a missing channel which unsurprisingly fails. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-04-18 16:46 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-04-11 0:04 [PATCH 00/30] ARM: exynos multiplatform support Arnd Bergmann 2013-04-11 0:05 ` [PATCH 29/30] spi: s3c64xx: move to generic dmaengine API Arnd Bergmann 2013-04-11 16:55 ` Mark Brown [not found] ` <20130411165536.GO9243-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> 2013-04-11 20:42 ` [PATCH v2] " Arnd Bergmann 2013-04-12 12:55 ` Mark Brown 2013-04-17 14:46 ` Mark Brown 2013-04-17 20:05 ` [PATCH 29/30] " Arnd Bergmann 2013-04-18 16:46 ` Mark Brown
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).