]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 Mar 2016 21:36:27 +0000 (14:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 Mar 2016 21:36:27 +0000 (14:36 -0700)
added patches:
asoc-samsung-pass-dma-channels-as-pointers.patch
mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch
mmc-sh_mmcif-rework-dma-channel-handling.patch

queue-4.4/asoc-samsung-pass-dma-channels-as-pointers.patch [new file with mode: 0644]
queue-4.4/mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch [new file with mode: 0644]
queue-4.4/mmc-sh_mmcif-rework-dma-channel-handling.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/asoc-samsung-pass-dma-channels-as-pointers.patch b/queue-4.4/asoc-samsung-pass-dma-channels-as-pointers.patch
new file mode 100644 (file)
index 0000000..45c4e11
--- /dev/null
@@ -0,0 +1,518 @@
+From b9a1a743818ea3265abf98f9431623afa8c50c86 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 18 Nov 2015 15:25:23 +0100
+Subject: ASoC: samsung: pass DMA channels as pointers
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit b9a1a743818ea3265abf98f9431623afa8c50c86 upstream.
+
+ARM64 allmodconfig produces a bunch of warnings when building the
+samsung ASoC code:
+
+sound/soc/samsung/dmaengine.c: In function 'samsung_asoc_init_dma_data':
+sound/soc/samsung/dmaengine.c:53:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
+   playback_data->filter_data = (void *)playback->channel;
+sound/soc/samsung/dmaengine.c:60:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
+   capture_data->filter_data = (void *)capture->channel;
+
+We could easily shut up the warning by adding an intermediate cast,
+but there is a bigger underlying problem: The use of IORESOURCE_DMA
+to pass data from platform code to device drivers is dubious to start
+with, as what we really want is a pointer that can be passed into
+a filter function.
+
+Note that on s3c64xx, the pl08x DMA data is already a pointer, but
+gets cast to resource_size_t so we can pass it as a resource, and it
+then gets converted back to a pointer. In contrast, the data we pass
+for s3c24xx is an index into a device specific table, and we artificially
+convert that into a pointer for the filter function.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-s3c64xx/dev-audio.c        |   41 +++++++++++++-----------
+ arch/arm/mach-s3c64xx/include/mach/dma.h |   52 +++++++++++++++----------------
+ arch/arm/plat-samsung/devs.c             |   11 ++++--
+ include/linux/platform_data/asoc-s3c.h   |    4 ++
+ sound/soc/samsung/ac97.c                 |   26 ++-------------
+ sound/soc/samsung/dma.h                  |    2 -
+ sound/soc/samsung/dmaengine.c            |    4 +-
+ sound/soc/samsung/i2s.c                  |   26 ++-------------
+ sound/soc/samsung/pcm.c                  |   20 ++---------
+ sound/soc/samsung/s3c2412-i2s.c          |    4 +-
+ sound/soc/samsung/s3c24xx-i2s.c          |    4 +-
+ sound/soc/samsung/spdif.c                |   10 +----
+ 12 files changed, 84 insertions(+), 120 deletions(-)
+
+--- a/arch/arm/mach-s3c64xx/dev-audio.c
++++ b/arch/arm/mach-s3c64xx/dev-audio.c
+@@ -54,12 +54,12 @@ static int s3c64xx_i2s_cfg_gpio(struct p
+ static struct resource s3c64xx_iis0_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
+-      [2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
+ };
+-static struct s3c_audio_pdata i2sv3_pdata = {
++static struct s3c_audio_pdata i2s0_pdata = {
+       .cfg_gpio = s3c64xx_i2s_cfg_gpio,
++      .dma_playback = DMACH_I2S0_OUT,
++      .dma_capture = DMACH_I2S0_IN,
+ };
+ struct platform_device s3c64xx_device_iis0 = {
+@@ -68,15 +68,19 @@ struct platform_device s3c64xx_device_ii
+       .num_resources    = ARRAY_SIZE(s3c64xx_iis0_resource),
+       .resource         = s3c64xx_iis0_resource,
+       .dev = {
+-              .platform_data = &i2sv3_pdata,
++              .platform_data = &i2s0_pdata,
+       },
+ };
+ EXPORT_SYMBOL(s3c64xx_device_iis0);
+ static struct resource s3c64xx_iis1_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_I2S1_OUT),
+-      [2] = DEFINE_RES_DMA(DMACH_I2S1_IN),
++};
++
++static struct s3c_audio_pdata i2s1_pdata = {
++      .cfg_gpio = s3c64xx_i2s_cfg_gpio,
++      .dma_playback = DMACH_I2S1_OUT,
++      .dma_capture = DMACH_I2S1_IN,
+ };
+ struct platform_device s3c64xx_device_iis1 = {
+@@ -85,19 +89,19 @@ struct platform_device s3c64xx_device_ii
+       .num_resources    = ARRAY_SIZE(s3c64xx_iis1_resource),
+       .resource         = s3c64xx_iis1_resource,
+       .dev = {
+-              .platform_data = &i2sv3_pdata,
++              .platform_data = &i2s1_pdata,
+       },
+ };
+ EXPORT_SYMBOL(s3c64xx_device_iis1);
+ static struct resource s3c64xx_iisv4_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
+-      [2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
+ };
+ static struct s3c_audio_pdata i2sv4_pdata = {
+       .cfg_gpio = s3c64xx_i2s_cfg_gpio,
++      .dma_playback = DMACH_HSI_I2SV40_TX,
++      .dma_capture = DMACH_HSI_I2SV40_RX,
+       .type = {
+               .i2s = {
+                       .quirks = QUIRK_PRI_6CHAN,
+@@ -142,12 +146,12 @@ static int s3c64xx_pcm_cfg_gpio(struct p
+ static struct resource s3c64xx_pcm0_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
+-      [2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
+ };
+ static struct s3c_audio_pdata s3c_pcm0_pdata = {
+       .cfg_gpio = s3c64xx_pcm_cfg_gpio,
++      .dma_capture = DMACH_PCM0_RX,
++      .dma_playback = DMACH_PCM0_TX,
+ };
+ struct platform_device s3c64xx_device_pcm0 = {
+@@ -163,12 +167,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm0);
+ static struct resource s3c64xx_pcm1_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
+-      [2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
+ };
+ static struct s3c_audio_pdata s3c_pcm1_pdata = {
+       .cfg_gpio = s3c64xx_pcm_cfg_gpio,
++      .dma_playback = DMACH_PCM1_TX,
++      .dma_capture = DMACH_PCM1_RX,
+ };
+ struct platform_device s3c64xx_device_pcm1 = {
+@@ -196,13 +200,14 @@ static int s3c64xx_ac97_cfg_gpe(struct p
+ static struct resource s3c64xx_ac97_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
+-      [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
+-      [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
+-      [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
+-      [4] = DEFINE_RES_IRQ(IRQ_AC97),
++      [1] = DEFINE_RES_IRQ(IRQ_AC97),
+ };
+-static struct s3c_audio_pdata s3c_ac97_pdata;
++static struct s3c_audio_pdata s3c_ac97_pdata = {
++      .dma_playback = DMACH_AC97_PCMOUT,
++      .dma_capture = DMACH_AC97_PCMIN,
++      .dma_capture_mic = DMACH_AC97_MICIN,
++};
+ static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
+--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
++++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
+@@ -14,38 +14,38 @@
+ #define S3C64XX_DMA_CHAN(name)                ((unsigned long)(name))
+ /* DMA0/SDMA0 */
+-#define DMACH_UART0           S3C64XX_DMA_CHAN("uart0_tx")
+-#define DMACH_UART0_SRC2      S3C64XX_DMA_CHAN("uart0_rx")
+-#define DMACH_UART1           S3C64XX_DMA_CHAN("uart1_tx")
+-#define DMACH_UART1_SRC2      S3C64XX_DMA_CHAN("uart1_rx")
+-#define DMACH_UART2           S3C64XX_DMA_CHAN("uart2_tx")
+-#define DMACH_UART2_SRC2      S3C64XX_DMA_CHAN("uart2_rx")
+-#define DMACH_UART3           S3C64XX_DMA_CHAN("uart3_tx")
+-#define DMACH_UART3_SRC2      S3C64XX_DMA_CHAN("uart3_rx")
+-#define DMACH_PCM0_TX         S3C64XX_DMA_CHAN("pcm0_tx")
+-#define DMACH_PCM0_RX         S3C64XX_DMA_CHAN("pcm0_rx")
+-#define DMACH_I2S0_OUT                S3C64XX_DMA_CHAN("i2s0_tx")
+-#define DMACH_I2S0_IN         S3C64XX_DMA_CHAN("i2s0_rx")
++#define DMACH_UART0           "uart0_tx"
++#define DMACH_UART0_SRC2      "uart0_rx"
++#define DMACH_UART1           "uart1_tx"
++#define DMACH_UART1_SRC2      "uart1_rx"
++#define DMACH_UART2           "uart2_tx"
++#define DMACH_UART2_SRC2      "uart2_rx"
++#define DMACH_UART3           "uart3_tx"
++#define DMACH_UART3_SRC2      "uart3_rx"
++#define DMACH_PCM0_TX         "pcm0_tx"
++#define DMACH_PCM0_RX         "pcm0_rx"
++#define DMACH_I2S0_OUT                "i2s0_tx"
++#define DMACH_I2S0_IN         "i2s0_rx"
+ #define DMACH_SPI0_TX         S3C64XX_DMA_CHAN("spi0_tx")
+ #define DMACH_SPI0_RX         S3C64XX_DMA_CHAN("spi0_rx")
+-#define DMACH_HSI_I2SV40_TX   S3C64XX_DMA_CHAN("i2s2_tx")
+-#define DMACH_HSI_I2SV40_RX   S3C64XX_DMA_CHAN("i2s2_rx")
++#define DMACH_HSI_I2SV40_TX   "i2s2_tx"
++#define DMACH_HSI_I2SV40_RX   "i2s2_rx"
+ /* DMA1/SDMA1 */
+-#define DMACH_PCM1_TX         S3C64XX_DMA_CHAN("pcm1_tx")
+-#define DMACH_PCM1_RX         S3C64XX_DMA_CHAN("pcm1_rx")
+-#define DMACH_I2S1_OUT                S3C64XX_DMA_CHAN("i2s1_tx")
+-#define DMACH_I2S1_IN         S3C64XX_DMA_CHAN("i2s1_rx")
++#define DMACH_PCM1_TX         "pcm1_tx"
++#define DMACH_PCM1_RX         "pcm1_rx"
++#define DMACH_I2S1_OUT                "i2s1_tx"
++#define DMACH_I2S1_IN         "i2s1_rx"
+ #define DMACH_SPI1_TX         S3C64XX_DMA_CHAN("spi1_tx")
+ #define DMACH_SPI1_RX         S3C64XX_DMA_CHAN("spi1_rx")
+-#define DMACH_AC97_PCMOUT     S3C64XX_DMA_CHAN("ac97_out")
+-#define DMACH_AC97_PCMIN      S3C64XX_DMA_CHAN("ac97_in")
+-#define DMACH_AC97_MICIN      S3C64XX_DMA_CHAN("ac97_mic")
+-#define DMACH_PWM             S3C64XX_DMA_CHAN("pwm")
+-#define DMACH_IRDA            S3C64XX_DMA_CHAN("irda")
+-#define DMACH_EXTERNAL                S3C64XX_DMA_CHAN("external")
+-#define DMACH_SECURITY_RX     S3C64XX_DMA_CHAN("sec_rx")
+-#define DMACH_SECURITY_TX     S3C64XX_DMA_CHAN("sec_tx")
++#define DMACH_AC97_PCMOUT     "ac97_out"
++#define DMACH_AC97_PCMIN      "ac97_in"
++#define DMACH_AC97_MICIN      "ac97_mic"
++#define DMACH_PWM             "pwm"
++#define DMACH_IRDA            "irda"
++#define DMACH_EXTERNAL                "external"
++#define DMACH_SECURITY_RX     "sec_rx"
++#define DMACH_SECURITY_TX     "sec_tx"
+ enum dma_ch {
+       DMACH_MAX = 32
+--- a/arch/arm/plat-samsung/devs.c
++++ b/arch/arm/plat-samsung/devs.c
+@@ -65,6 +65,7 @@
+ #include <linux/platform_data/usb-ohci-s3c2410.h>
+ #include <plat/usb-phy.h>
+ #include <plat/regs-spi.h>
++#include <linux/platform_data/asoc-s3c.h>
+ #include <linux/platform_data/spi-s3c64xx.h>
+ static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
+@@ -74,9 +75,12 @@ static u64 samsung_device_dma_mask = DMA
+ static struct resource s3c_ac97_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
+       [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
+-      [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
+-      [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
+-      [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
++};
++
++static struct s3c_audio_pdata s3c_ac97_pdata = {
++      .dma_playback = (void *)DMACH_PCM_OUT,
++      .dma_capture = (void *)DMACH_PCM_IN,
++      .dma_capture_mic = (void *)DMACH_MIC_IN,
+ };
+ struct platform_device s3c_device_ac97 = {
+@@ -87,6 +91,7 @@ struct platform_device s3c_device_ac97 =
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
++              .platform_data          = &s3c_ac97_pdata,
+       }
+ };
+ #endif /* CONFIG_CPU_S3C2440 */
+--- a/include/linux/platform_data/asoc-s3c.h
++++ b/include/linux/platform_data/asoc-s3c.h
+@@ -39,6 +39,10 @@ struct samsung_i2s {
+  */
+ struct s3c_audio_pdata {
+       int (*cfg_gpio)(struct platform_device *);
++      void *dma_playback;
++      void *dma_capture;
++      void *dma_play_sec;
++      void *dma_capture_mic;
+       union {
+               struct samsung_i2s i2s;
+       } type;
+--- a/sound/soc/samsung/ac97.c
++++ b/sound/soc/samsung/ac97.c
+@@ -324,7 +324,7 @@ static const struct snd_soc_component_dr
+ static int s3c_ac97_probe(struct platform_device *pdev)
+ {
+-      struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
++      struct resource *mem_res, *irq_res;
+       struct s3c_audio_pdata *ac97_pdata;
+       int ret;
+@@ -335,24 +335,6 @@ static int s3c_ac97_probe(struct platfor
+       }
+       /* Check for availability of necessary resource */
+-      dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+-      if (!dmatx_res) {
+-              dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
+-              return -ENXIO;
+-      }
+-
+-      dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+-      if (!dmarx_res) {
+-              dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
+-              return -ENXIO;
+-      }
+-
+-      dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
+-      if (!dmamic_res) {
+-              dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
+-              return -ENXIO;
+-      }
+-
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!irq_res) {
+               dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
+@@ -364,11 +346,11 @@ static int s3c_ac97_probe(struct platfor
+       if (IS_ERR(s3c_ac97.regs))
+               return PTR_ERR(s3c_ac97.regs);
+-      s3c_ac97_pcm_out.channel = dmatx_res->start;
++      s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
+       s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
+-      s3c_ac97_pcm_in.channel = dmarx_res->start;
++      s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
+       s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
+-      s3c_ac97_mic_in.channel = dmamic_res->start;
++      s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
+       s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
+       init_completion(&s3c_ac97.done);
+--- a/sound/soc/samsung/dma.h
++++ b/sound/soc/samsung/dma.h
+@@ -15,7 +15,7 @@
+ #include <sound/dmaengine_pcm.h>
+ struct s3c_dma_params {
+-      int channel;                            /* Channel ID */
++      void *slave;                            /* Channel ID */
+       dma_addr_t dma_addr;
+       int dma_size;                   /* Size of the DMA transfer */
+       char *ch_name;
+--- a/sound/soc/samsung/dmaengine.c
++++ b/sound/soc/samsung/dmaengine.c
+@@ -50,14 +50,14 @@ void samsung_asoc_init_dma_data(struct s
+       if (playback) {
+               playback_data = &playback->dma_data;
+-              playback_data->filter_data = (void *)playback->channel;
++              playback_data->filter_data = playback->slave;
+               playback_data->chan_name = playback->ch_name;
+               playback_data->addr = playback->dma_addr;
+               playback_data->addr_width = playback->dma_size;
+       }
+       if (capture) {
+               capture_data = &capture->dma_data;
+-              capture_data->filter_data = (void *)capture->channel;
++              capture_data->filter_data = capture->slave;
+               capture_data->chan_name = capture->ch_name;
+               capture_data->addr = capture->dma_addr;
+               capture_data->addr_width = capture->dma_size;
+--- a/sound/soc/samsung/i2s.c
++++ b/sound/soc/samsung/i2s.c
+@@ -1260,27 +1260,14 @@ static int samsung_i2s_probe(struct plat
+       pri_dai->lock = &pri_dai->spinlock;
+       if (!np) {
+-              res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+-              if (!res) {
+-                      dev_err(&pdev->dev,
+-                              "Unable to get I2S-TX dma resource\n");
+-                      return -ENXIO;
+-              }
+-              pri_dai->dma_playback.channel = res->start;
+-
+-              res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+-              if (!res) {
+-                      dev_err(&pdev->dev,
+-                              "Unable to get I2S-RX dma resource\n");
+-                      return -ENXIO;
+-              }
+-              pri_dai->dma_capture.channel = res->start;
+-
+               if (i2s_pdata == NULL) {
+                       dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
+                       return -EINVAL;
+               }
++              pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
++              pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
++
+               if (&i2s_pdata->type)
+                       i2s_cfg = &i2s_pdata->type.i2s;
+@@ -1341,11 +1328,8 @@ static int samsung_i2s_probe(struct plat
+               sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
+               sec_dai->dma_playback.ch_name = "tx-sec";
+-              if (!np) {
+-                      res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
+-                      if (res)
+-                              sec_dai->dma_playback.channel = res->start;
+-              }
++              if (!np)
++                      sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
+               sec_dai->dma_playback.dma_size = 4;
+               sec_dai->addr = pri_dai->addr;
+--- a/sound/soc/samsung/pcm.c
++++ b/sound/soc/samsung/pcm.c
+@@ -486,7 +486,7 @@ static const struct snd_soc_component_dr
+ static int s3c_pcm_dev_probe(struct platform_device *pdev)
+ {
+       struct s3c_pcm_info *pcm;
+-      struct resource *mem_res, *dmatx_res, *dmarx_res;
++      struct resource *mem_res;
+       struct s3c_audio_pdata *pcm_pdata;
+       int ret;
+@@ -499,18 +499,6 @@ static int s3c_pcm_dev_probe(struct plat
+       pcm_pdata = pdev->dev.platform_data;
+       /* Check for availability of necessary resource */
+-      dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+-      if (!dmatx_res) {
+-              dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
+-              return -ENXIO;
+-      }
+-
+-      dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+-      if (!dmarx_res) {
+-              dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
+-              return -ENXIO;
+-      }
+-
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem_res) {
+               dev_err(&pdev->dev, "Unable to get register resource\n");
+@@ -568,8 +556,10 @@ static int s3c_pcm_dev_probe(struct plat
+       s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
+                                                       + S3C_PCM_TXFIFO;
+-      s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
+-      s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;
++      if (pcm_pdata) {
++              s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
++              s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
++      }
+       pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
+       pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
+--- a/sound/soc/samsung/s3c2412-i2s.c
++++ b/sound/soc/samsung/s3c2412-i2s.c
+@@ -34,13 +34,13 @@
+ #include "s3c2412-i2s.h"
+ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
+-      .channel        = DMACH_I2S_OUT,
++      .slave          = (void *)(uintptr_t)DMACH_I2S_OUT,
+       .ch_name        = "tx",
+       .dma_size       = 4,
+ };
+ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
+-      .channel        = DMACH_I2S_IN,
++      .slave          = (void *)(uintptr_t)DMACH_I2S_IN,
+       .ch_name        = "rx",
+       .dma_size       = 4,
+ };
+--- a/sound/soc/samsung/s3c24xx-i2s.c
++++ b/sound/soc/samsung/s3c24xx-i2s.c
+@@ -32,13 +32,13 @@
+ #include "s3c24xx-i2s.h"
+ static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
+-      .channel        = DMACH_I2S_OUT,
++      .slave          = (void *)(uintptr_t)DMACH_I2S_OUT,
+       .ch_name        = "tx",
+       .dma_size       = 2,
+ };
+ static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
+-      .channel        = DMACH_I2S_IN,
++      .slave          = (void *)(uintptr_t)DMACH_I2S_IN,
+       .ch_name        = "rx",
+       .dma_size       = 2,
+ };
+--- a/sound/soc/samsung/spdif.c
++++ b/sound/soc/samsung/spdif.c
+@@ -359,7 +359,7 @@ static const struct snd_soc_component_dr
+ static int spdif_probe(struct platform_device *pdev)
+ {
+       struct s3c_audio_pdata *spdif_pdata;
+-      struct resource *mem_res, *dma_res;
++      struct resource *mem_res;
+       struct samsung_spdif_info *spdif;
+       int ret;
+@@ -367,12 +367,6 @@ static int spdif_probe(struct platform_d
+       dev_dbg(&pdev->dev, "Entered %s\n", __func__);
+-      dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+-      if (!dma_res) {
+-              dev_err(&pdev->dev, "Unable to get dma resource.\n");
+-              return -ENXIO;
+-      }
+-
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem_res) {
+               dev_err(&pdev->dev, "Unable to get register resource.\n");
+@@ -432,7 +426,7 @@ static int spdif_probe(struct platform_d
+       spdif_stereo_out.dma_size = 2;
+       spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
+-      spdif_stereo_out.channel = dma_res->start;
++      spdif_stereo_out.slave = spdif_pdata ? spdif_pdata->dma_playback : NULL;
+       spdif->dma_playback = &spdif_stereo_out;
diff --git a/queue-4.4/mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch b/queue-4.4/mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch
new file mode 100644 (file)
index 0000000..6e32031
--- /dev/null
@@ -0,0 +1,35 @@
+From a32ef81c9889c9554a3c4b465c4ee7b2d26c6b10 Mon Sep 17 00:00:00 2001
+From: Chris Paterson <chris.paterson2@renesas.com>
+Date: Wed, 10 Feb 2016 14:07:01 +0000
+Subject: mmc: sh_mmcif: Correct TX DMA channel allocation
+
+From: Chris Paterson <chris.paterson2@renesas.com>
+
+commit a32ef81c9889c9554a3c4b465c4ee7b2d26c6b10 upstream.
+
+Commit 27cbd7e815a8 ("mmc: sh_mmcif: rework dma channel handling")
+introduced a typo causing the TX DMA channel allocation to be overwritten
+by the requested RX DMA channel.
+
+Fixes: 27cbd7e815a8 ("mmc: sh_mmcif: rework dma channel handling")
+Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sh_mmcif.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -445,7 +445,7 @@ static void sh_mmcif_request_dma(struct
+                                                       pdata->slave_id_rx);
+       } else {
+               host->chan_tx = dma_request_slave_channel(dev, "tx");
+-              host->chan_tx = dma_request_slave_channel(dev, "rx");
++              host->chan_rx = dma_request_slave_channel(dev, "rx");
+       }
+       dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx,
+               host->chan_rx);
diff --git a/queue-4.4/mmc-sh_mmcif-rework-dma-channel-handling.patch b/queue-4.4/mmc-sh_mmcif-rework-dma-channel-handling.patch
new file mode 100644 (file)
index 0000000..70d8fb9
--- /dev/null
@@ -0,0 +1,165 @@
+From 27cbd7e815a8e223ff7c4fe56daca724101288ac Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 16 Nov 2015 17:08:41 +0100
+Subject: mmc: sh_mmcif: rework dma channel handling
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 27cbd7e815a8e223ff7c4fe56daca724101288ac upstream.
+
+When compiling the sh_mmcif driver for ARM64, we currently
+get a harmless build warning:
+
+../drivers/mmc/host/sh_mmcif.c: In function 'sh_mmcif_request_dma_one':
+../drivers/mmc/host/sh_mmcif.c:417:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
+    (void *)pdata->slave_id_tx :
+    ^
+../drivers/mmc/host/sh_mmcif.c:418:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
+    (void *)pdata->slave_id_rx;
+
+This could be worked around by adding another cast to uintptr_t, but
+I decided to simplify the code a little more to avoid that. This
+splits out the platform data using code into a separate function
+and builds that only for CONFIG_SUPERH. This part still has a typecast
+but does not need a second one. The SH platform code could be further
+modified to pass a pointer directly as we do on other architectures
+when we have a filter function.
+
+The normal case is simplified further and now just calls
+dma_request_slave_channel() directly without going through the
+compat handling.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sh_mmcif.c |   84 +++++++++++++++++++-------------------------
+ 1 file changed, 38 insertions(+), 46 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -397,38 +397,26 @@ static void sh_mmcif_start_dma_tx(struct
+ }
+ static struct dma_chan *
+-sh_mmcif_request_dma_one(struct sh_mmcif_host *host,
+-                       struct sh_mmcif_plat_data *pdata,
+-                       enum dma_transfer_direction direction)
++sh_mmcif_request_dma_pdata(struct sh_mmcif_host *host, uintptr_t slave_id)
+ {
+-      struct dma_slave_config cfg = { 0, };
+-      struct dma_chan *chan;
+-      void *slave_data = NULL;
+-      struct resource *res;
+-      struct device *dev = sh_mmcif_host_to_dev(host);
+       dma_cap_mask_t mask;
+-      int ret;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
++      if (slave_id <= 0)
++              return NULL;
+-      if (pdata)
+-              slave_data = direction == DMA_MEM_TO_DEV ?
+-                      (void *)pdata->slave_id_tx :
+-                      (void *)pdata->slave_id_rx;
+-
+-      chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
+-                              slave_data, dev,
+-                              direction == DMA_MEM_TO_DEV ? "tx" : "rx");
+-
+-      dev_dbg(dev, "%s: %s: got channel %p\n", __func__,
+-              direction == DMA_MEM_TO_DEV ? "TX" : "RX", chan);
++      return dma_request_channel(mask, shdma_chan_filter, (void *)slave_id);
++}
+-      if (!chan)
+-              return NULL;
++static int sh_mmcif_dma_slave_config(struct sh_mmcif_host *host,
++                                   struct dma_chan *chan,
++                                   enum dma_transfer_direction direction)
++{
++      struct resource *res;
++      struct dma_slave_config cfg = { 0, };
+       res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
+-
+       cfg.direction = direction;
+       if (direction == DMA_DEV_TO_MEM) {
+@@ -439,38 +427,42 @@ sh_mmcif_request_dma_one(struct sh_mmcif
+               cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       }
+-      ret = dmaengine_slave_config(chan, &cfg);
+-      if (ret < 0) {
+-              dma_release_channel(chan);
+-              return NULL;
+-      }
+-
+-      return chan;
++      return dmaengine_slave_config(chan, &cfg);
+ }
+-static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+-                               struct sh_mmcif_plat_data *pdata)
++static void sh_mmcif_request_dma(struct sh_mmcif_host *host)
+ {
+       struct device *dev = sh_mmcif_host_to_dev(host);
+       host->dma_active = false;
+-      if (pdata) {
+-              if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
+-                      return;
+-      } else if (!dev->of_node) {
+-              return;
++      /* We can only either use DMA for both Tx and Rx or not use it at all */
++      if (IS_ENABLED(CONFIG_SUPERH) && dev->platform_data) {
++              struct sh_mmcif_plat_data *pdata = dev->platform_data;
++
++              host->chan_tx = sh_mmcif_request_dma_pdata(host,
++                                                      pdata->slave_id_tx);
++              host->chan_rx = sh_mmcif_request_dma_pdata(host,
++                                                      pdata->slave_id_rx);
++      } else {
++              host->chan_tx = dma_request_slave_channel(dev, "tx");
++              host->chan_tx = dma_request_slave_channel(dev, "rx");
+       }
++      dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx,
++              host->chan_rx);
+-      /* We can only either use DMA for both Tx and Rx or not use it at all */
+-      host->chan_tx = sh_mmcif_request_dma_one(host, pdata, DMA_MEM_TO_DEV);
+-      if (!host->chan_tx)
+-              return;
++      if (!host->chan_tx || !host->chan_rx ||
++          sh_mmcif_dma_slave_config(host, host->chan_tx, DMA_MEM_TO_DEV) ||
++          sh_mmcif_dma_slave_config(host, host->chan_rx, DMA_DEV_TO_MEM))
++              goto error;
+-      host->chan_rx = sh_mmcif_request_dma_one(host, pdata, DMA_DEV_TO_MEM);
+-      if (!host->chan_rx) {
++      return;
++
++error:
++      if (host->chan_tx)
+               dma_release_channel(host->chan_tx);
+-              host->chan_tx = NULL;
+-      }
++      if (host->chan_rx)
++              dma_release_channel(host->chan_rx);
++      host->chan_tx = host->chan_rx = NULL;
+ }
+ static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
+@@ -1102,7 +1094,7 @@ static void sh_mmcif_set_ios(struct mmc_
+       if (ios->power_mode == MMC_POWER_UP) {
+               if (!host->card_present) {
+                       /* See if we also get DMA */
+-                      sh_mmcif_request_dma(host, dev->platform_data);
++                      sh_mmcif_request_dma(host);
+                       host->card_present = true;
+               }
+               sh_mmcif_set_power(host, ios);
index 857e9860e371157d3156421aab1407f76e90431a..2f19c374f34abd091ca51fbbd71105cbc70fa1b2 100644 (file)
@@ -1,3 +1,6 @@
 s390-cpumf-fix-lpp-detection.patch
 regulator-core-avoid-unused-variable-warning.patch
 regulator-core-fix-nested-locking-of-supplies.patch
+asoc-samsung-pass-dma-channels-as-pointers.patch
+mmc-sh_mmcif-rework-dma-channel-handling.patch
+mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch