From: Greg Kroah-Hartman Date: Fri, 18 Mar 2016 21:36:27 +0000 (-0700) Subject: 4.4-stable patches X-Git-Tag: v4.5.1~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d841db0bca2c67b11e891eccaeb2b156fa539700;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches 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 --- 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 index 00000000000..45c4e11eb09 --- /dev/null +++ b/queue-4.4/asoc-samsung-pass-dma-channels-as-pointers.patch @@ -0,0 +1,518 @@ +From b9a1a743818ea3265abf98f9431623afa8c50c86 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 18 Nov 2015 15:25:23 +0100 +Subject: ASoC: samsung: pass DMA channels as pointers + +From: Arnd Bergmann + +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 +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #include + + 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 + + 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 index 00000000000..6e320317500 --- /dev/null +++ b/queue-4.4/mmc-sh_mmcif-correct-tx-dma-channel-allocation.patch @@ -0,0 +1,35 @@ +From a32ef81c9889c9554a3c4b465c4ee7b2d26c6b10 Mon Sep 17 00:00:00 2001 +From: Chris Paterson +Date: Wed, 10 Feb 2016 14:07:01 +0000 +Subject: mmc: sh_mmcif: Correct TX DMA channel allocation + +From: Chris Paterson + +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 +Acked-by: Laurent Pinchart +Acked-by: Arnd Bergmann +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..70d8fb98ad4 --- /dev/null +++ b/queue-4.4/mmc-sh_mmcif-rework-dma-channel-handling.patch @@ -0,0 +1,165 @@ +From 27cbd7e815a8e223ff7c4fe56daca724101288ac Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 16 Nov 2015 17:08:41 +0100 +Subject: mmc: sh_mmcif: rework dma channel handling + +From: Arnd Bergmann + +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 +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.4/series b/queue-4.4/series index 857e9860e37..2f19c374f34 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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