Hi Arnd, On Tue, Mar 5, 2013 at 11:12 PM, Arnd Bergmann <a...@arndb.de> wrote: > In order to build the exynos kernel with CONFIG_ARCH_MULTIPLATFORM, > we must convert all users of the Samsung private DMA interface to > the generic dmaengine API. This converts the sound/soc drivers, > breaking the older s3c platforms in the process, since they do not > support the dmaengine interface yet. > > This patch must not get mainlined until mach-s3c* is also converted, > but can be used for testing in the meantime. > > Signed-off-by: Arnd Bergmann <a...@arndb.de> > --- > sound/soc/samsung/ac97.c | 15 ------ > sound/soc/samsung/dma.c | 104 > +++++++++++++++++++++------------------- > sound/soc/samsung/dma.h | 4 +- > sound/soc/samsung/i2s.c | 9 +--- > sound/soc/samsung/pcm.c | 13 ----- > sound/soc/samsung/s3c2412-i2s.c | 10 ---- > sound/soc/samsung/s3c24xx-i2s.c | 10 ---- > sound/soc/samsung/spdif.c | 6 --- > 8 files changed, 57 insertions(+), 114 deletions(-) > > diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c > index c76abdf..214f454 100644 > --- a/sound/soc/samsung/ac97.c > +++ b/sound/soc/samsung/ac97.c > @@ -39,30 +39,15 @@ struct s3c_ac97_info { > }; > static struct s3c_ac97_info s3c_ac97; > > -static struct s3c2410_dma_client s3c_dma_client_out = { > - .name = "AC97 PCMOut" > -}; > - > -static struct s3c2410_dma_client s3c_dma_client_in = { > - .name = "AC97 PCMIn" > -}; > - > -static struct s3c2410_dma_client s3c_dma_client_micin = { > - .name = "AC97 MicIn" > -}; > - > static struct s3c_dma_params s3c_ac97_pcm_out = { > - .client = &s3c_dma_client_out, > .dma_size = 4, > }; > > static struct s3c_dma_params s3c_ac97_pcm_in = { > - .client = &s3c_dma_client_in, > .dma_size = 4, > }; > > static struct s3c_dma_params s3c_ac97_mic_in = { > - .client = &s3c_dma_client_micin, > .dma_size = 4, > }; > > diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c > index 21b7926..67b8dcc 100644 > --- a/sound/soc/samsung/dma.c > +++ b/sound/soc/samsung/dma.c > @@ -16,14 +16,14 @@ > > #include <linux/slab.h> > #include <linux/dma-mapping.h> > +#include <linux/dmaengine.h> > #include <linux/module.h> > +#include <linux/amba/pl330.h> > > #include <sound/soc.h> > #include <sound/pcm_params.h> > > #include <asm/dma.h> > -#include <mach/hardware.h> > -#include <mach/dma.h> > > #include "dma.h" > > @@ -67,12 +67,16 @@ static void audio_buffdone(void *data); > * place a dma buffer onto the queue for the dma system > * to handle. > */ > + > static void dma_enqueue(struct snd_pcm_substream *substream) > { > struct runtime_data *prtd = substream->runtime->private_data; > dma_addr_t pos = prtd->dma_pos; > + unsigned long period = prtd->dma_period; > unsigned int limit; > - struct samsung_dma_prep dma_info; > + enum dma_transfer_direction direction; > + struct dma_chan *chan = prtd->params->ch; > + struct dma_async_tx_descriptor *desc; > > pr_debug("Entered %s\n", __func__); > > @@ -81,29 +85,30 @@ static void dma_enqueue(struct snd_pcm_substream > *substream) > pr_debug("%s: loaded %d, limit %d\n", > __func__, prtd->dma_loaded, limit); > > - dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); > - dma_info.direction = > - (substream->stream == SNDRV_PCM_STREAM_PLAYBACK > - ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); > - dma_info.fp = audio_buffdone; > - dma_info.fp_param = substream; > - dma_info.period = prtd->dma_period; > - dma_info.len = prtd->dma_period*limit; > + direction = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK > + ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); > > while (prtd->dma_loaded < limit) { > pr_debug("dma_loaded: %d\n", prtd->dma_loaded); > > - if ((pos + dma_info.period) > prtd->dma_end) { > - dma_info.period = prtd->dma_end - pos; > + if ((pos + period) > prtd->dma_end) { > + period = prtd->dma_end - pos; > pr_debug("%s: corrected dma len %ld\n", > - __func__, dma_info.period); > + __func__, period); > } > > - dma_info.buf = pos; > - prtd->params->ops->prepare(prtd->params->ch, &dma_info); > + desc = dmaengine_prep_dma_cyclic(chan, pos, > + prtd->dma_period*limit, period, direction, > + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); > + > + if (desc) { > + desc->callback = audio_buffdone; > + desc->callback_param = substream; > + dmaengine_submit(desc); > + } > > prtd->dma_loaded++; > - pos += prtd->dma_period; > + pos += period; > if (pos >= prtd->dma_end) > pos = prtd->dma_start; > } > @@ -125,13 +130,6 @@ static void audio_buffdone(void *data) > > if (substream) > snd_pcm_period_elapsed(substream); > - > - spin_lock(&prtd->lock); > - if (!samsung_dma_has_circular()) { > - prtd->dma_loaded--; > - dma_enqueue(substream); > - } > - spin_unlock(&prtd->lock); > } > } > > @@ -144,8 +142,6 @@ static int dma_hw_params(struct snd_pcm_substream > *substream, > unsigned long totbytes = params_buffer_bytes(params); > struct s3c_dma_params *dma = > snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); > - struct samsung_dma_req req; > - struct samsung_dma_config config; > > pr_debug("Entered %s\n", __func__); > > @@ -157,26 +153,37 @@ static int dma_hw_params(struct snd_pcm_substream > *substream, > /* this may get called several times by oss emulation > * with different params -HW */ > if (prtd->params == NULL) { > + struct dma_slave_config config; > + dma_cap_mask_t mask; > + > /* prepare DMA */ > prtd->params = dma; > > - pr_debug("params %p, client %p, channel %d\n", prtd->params, > - prtd->params->client, prtd->params->channel); > - > - prtd->params->ops = samsung_dma_get_ops(); > - > - req.cap = (samsung_dma_has_circular() ? > - DMA_CYCLIC : DMA_SLAVE); > - req.client = prtd->params->client; > - config.direction = > - (substream->stream == SNDRV_PCM_STREAM_PLAYBACK > - ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); > - config.width = prtd->params->dma_size; > - config.fifo = prtd->params->dma_addr; > - prtd->params->ch = prtd->params->ops->request( > - prtd->params->channel, &req, > rtd->cpu_dai->dev, > - prtd->params->ch_name); > - prtd->params->ops->config(prtd->params->ch, &config); > + pr_debug("params %p, channel %d\n", prtd->params, > + prtd->params->channel); > + > + dma_cap_zero(mask); > + dma_cap_set(DMA_CYCLIC, mask); > + > + prtd->params->ch = dma_request_slave_channel_compat(mask, > + pl330_filter, (void *)prtd->params->channel, > + rtd->cpu_dai->dev, prtd->params->ch_name); > + > + memset(&config, 0, sizeof(struct dma_slave_config)); > + > + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > + config.direction = DMA_MEM_TO_DEV; > + config.dst_addr = prtd->params->dma_size; > + config.dst_addr_width = prtd->params->dma_addr;
dma_addr and dma_size got interchanged. Except the above one I tested this patch on 5250. It's working fine. > + config.dst_maxburst = 1; > + dmaengine_slave_config(prtd->params->ch, &config); > + } else { > + config.direction = DMA_DEV_TO_MEM; > + config.src_addr = prtd->params->dma_addr; > + config.src_addr_width = prtd->params->dma_size; > + config.src_maxburst = 1; > + dmaengine_slave_config(prtd->params->ch, &config); > + } > } > > snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); > @@ -203,9 +210,8 @@ static int dma_hw_free(struct snd_pcm_substream > *substream) > snd_pcm_set_runtime_buffer(substream, NULL); > > if (prtd->params) { > - prtd->params->ops->flush(prtd->params->ch); > - prtd->params->ops->release(prtd->params->ch, > - prtd->params->client); > + dmaengine_terminate_all(prtd->params->ch); > + dma_release_channel(prtd->params->ch); > prtd->params = NULL; > } > > @@ -225,7 +231,7 @@ static int dma_prepare(struct snd_pcm_substream > *substream) > return 0; > > /* flush the DMA channel */ > - prtd->params->ops->flush(prtd->params->ch); > + dmaengine_terminate_all(prtd->params->ch); > > prtd->dma_loaded = 0; > prtd->dma_pos = prtd->dma_start; > @@ -248,12 +254,12 @@ static int dma_trigger(struct snd_pcm_substream > *substream, int cmd) > switch (cmd) { > case SNDRV_PCM_TRIGGER_START: > prtd->state |= ST_RUNNING; > - prtd->params->ops->trigger(prtd->params->ch); > + dma_async_issue_pending(prtd->params->ch); > break; > > case SNDRV_PCM_TRIGGER_STOP: > prtd->state &= ~ST_RUNNING; > - prtd->params->ops->stop(prtd->params->ch); > + dmaengine_terminate_all(prtd->params->ch); > break; > > default: > diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h > index 189a7a6..f7381be 100644 > --- a/sound/soc/samsung/dma.h > +++ b/sound/soc/samsung/dma.h > @@ -13,12 +13,10 @@ > #define _S3C_AUDIO_H > > struct s3c_dma_params { > - struct s3c2410_dma_client *client; /* stream identifier */ > int channel; /* Channel ID */ > dma_addr_t dma_addr; > int dma_size; /* Size of the DMA transfer */ > - unsigned ch; > - struct samsung_dma_ops *ops; > + struct dma_chan *ch; > char *ch_name; > }; > > diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c > index d7231e3..2eed7a3 100644 > --- a/sound/soc/samsung/i2s.c > +++ b/sound/soc/samsung/i2s.c > @@ -18,12 +18,11 @@ > #include <linux/of.h> > #include <linux/of_gpio.h> > #include <linux/pm_runtime.h> > +#include <linux/dmaengine.h> > > #include <sound/soc.h> > #include <sound/pcm_params.h> > > -#include <mach/dma.h> > - > #include <linux/platform_data/asoc-s3c.h> > > #include "dma.h" > @@ -1183,11 +1182,7 @@ static int samsung_i2s_probe(struct platform_device > *pdev) > > pri_dai->dma_playback.dma_addr = regs_base + I2STXD; > pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; > - pri_dai->dma_playback.client = > - (struct s3c2410_dma_client *)&pri_dai->dma_playback; > pri_dai->dma_playback.ch_name = "tx"; > - pri_dai->dma_capture.client = > - (struct s3c2410_dma_client *)&pri_dai->dma_capture; > pri_dai->dma_capture.ch_name = "rx"; > pri_dai->dma_playback.dma_size = 4; > pri_dai->dma_capture.dma_size = 4; > @@ -1205,8 +1200,6 @@ static int samsung_i2s_probe(struct platform_device > *pdev) > goto err; > } > sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; > - sec_dai->dma_playback.client = > - (struct s3c2410_dma_client *)&sec_dai->dma_playback; > sec_dai->dma_playback.ch_name = "tx-sec"; > > if (!np) { > diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c > index 13bab79..525b2d2 100644 > --- a/sound/soc/samsung/pcm.c > +++ b/sound/soc/samsung/pcm.c > @@ -20,7 +20,6 @@ > #include <sound/pcm_params.h> > > #include <linux/platform_data/asoc-s3c.h> > -#include <mach/dma.h> > > #include "dma.h" > #include "pcm.h" > @@ -132,32 +131,20 @@ struct s3c_pcm_info { > struct s3c_dma_params *dma_capture; > }; > > -static struct s3c2410_dma_client s3c_pcm_dma_client_out = { > - .name = "PCM Stereo out" > -}; > - > -static struct s3c2410_dma_client s3c_pcm_dma_client_in = { > - .name = "PCM Stereo in" > -}; > - > static struct s3c_dma_params s3c_pcm_stereo_out[] = { > [0] = { > - .client = &s3c_pcm_dma_client_out, > .dma_size = 4, > }, > [1] = { > - .client = &s3c_pcm_dma_client_out, > .dma_size = 4, > }, > }; > > static struct s3c_dma_params s3c_pcm_stereo_in[] = { > [0] = { > - .client = &s3c_pcm_dma_client_in, > .dma_size = 4, > }, > [1] = { > - .client = &s3c_pcm_dma_client_in, > .dma_size = 4, > }, > }; > diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c > index 2213377..d43f00e 100644 > --- a/sound/soc/samsung/s3c2412-i2s.c > +++ b/sound/soc/samsung/s3c2412-i2s.c > @@ -31,23 +31,13 @@ > #include "regs-i2s-v2.h" > #include "s3c2412-i2s.h" > > -static struct s3c2410_dma_client s3c2412_dma_client_out = { > - .name = "I2S PCM Stereo out" > -}; > - > -static struct s3c2410_dma_client s3c2412_dma_client_in = { > - .name = "I2S PCM Stereo in" > -}; > - > static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { > - .client = &s3c2412_dma_client_out, > .channel = DMACH_I2S_OUT, > .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, > .dma_size = 4, > }; > > static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { > - .client = &s3c2412_dma_client_in, > .channel = DMACH_I2S_IN, > .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, > .dma_size = 4, > diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c > index a7b17c1..d68c23d 100644 > --- a/sound/soc/samsung/s3c24xx-i2s.c > +++ b/sound/soc/samsung/s3c24xx-i2s.c > @@ -29,23 +29,13 @@ > #include "dma.h" > #include "s3c24xx-i2s.h" > > -static struct s3c2410_dma_client s3c24xx_dma_client_out = { > - .name = "I2S PCM Stereo out" > -}; > - > -static struct s3c2410_dma_client s3c24xx_dma_client_in = { > - .name = "I2S PCM Stereo in" > -}; > - > static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { > - .client = &s3c24xx_dma_client_out, > .channel = DMACH_I2S_OUT, > .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, > .dma_size = 2, > }; > > static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { > - .client = &s3c24xx_dma_client_in, > .channel = DMACH_I2S_IN, > .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, > .dma_size = 2, > diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c > index 5008e5b..5c78c78 100644 > --- a/sound/soc/samsung/spdif.c > +++ b/sound/soc/samsung/spdif.c > @@ -18,7 +18,6 @@ > #include <sound/pcm_params.h> > > #include <linux/platform_data/asoc-s3c.h> > -#include <mach/dma.h> > > #include "dma.h" > #include "spdif.h" > @@ -94,10 +93,6 @@ struct samsung_spdif_info { > struct s3c_dma_params *dma_playback; > }; > > -static struct s3c2410_dma_client spdif_dma_client_out = { > - .name = "S/PDIF Stereo out", > -}; > - > static struct s3c_dma_params spdif_stereo_out; > static struct samsung_spdif_info spdif_info; > > @@ -431,7 +426,6 @@ static int spdif_probe(struct platform_device *pdev) > } > > spdif_stereo_out.dma_size = 2; > - spdif_stereo_out.client = &spdif_dma_client_out; > spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; > spdif_stereo_out.channel = dma_res->start; > > -- > 1.8.1.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" > in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Thanks Padma -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html