Merge tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jun 2012 22:39:26 +0000 (15:39 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jun 2012 22:39:26 +0000 (15:39 -0700)
Pull sound fixes from Takashi Iwai:
 "Just a few trivial driver-specific fixes."

* tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hdspm - Work around broken DDS value on PCI RME MADI
  ALSA: usb-audio: fix rate_list memory leak
  ASoC: fsi: bugfix: ensure dma is terminated
  ASoC: fsi: bugfix: correct dma area
  ASoC: fsi: bugfix: enable master clock control on DMA stream
  ASoC: imx-ssi: Use clk_prepare_enable/clk_disable_unprepare

sound/pci/rme9652/hdspm.c
sound/soc/fsl/imx-ssi.c
sound/soc/sh/fsi.c
sound/usb/pcm.c

index 0a5027b94714afb9600b94922f6d89140271492d..b8ac8710f47fb200d602bc2917598a153cad6884 100644 (file)
@@ -1988,6 +1988,13 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
        period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
        rate = hdspm_calc_dds_value(hdspm, period);
 
+       if (rate > 207000) {
+               /* Unreasonable high sample rate as seen on PCI MADI cards.
+                * Use the cached value instead.
+                */
+               rate = hdspm->system_sample_rate;
+       }
+
        return rate;
 }
 
index cf3ed0362c9ccf76cbbdc975c8788b33725b70f7..28dd76c7cb1c08ac308ca7730d9abfc8b02b0903 100644 (file)
@@ -543,7 +543,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
                        ret);
                goto failed_clk;
        }
-       clk_enable(ssi->clk);
+       clk_prepare_enable(ssi->clk);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
@@ -641,7 +641,7 @@ failed_ac97:
 failed_ioremap:
        release_mem_region(res->start, resource_size(res));
 failed_get_resource:
-       clk_disable(ssi->clk);
+       clk_disable_unprepare(ssi->clk);
        clk_put(ssi->clk);
 failed_clk:
        kfree(ssi);
@@ -664,7 +664,7 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
 
        iounmap(ssi->base);
        release_mem_region(res->start, resource_size(res));
-       clk_disable(ssi->clk);
+       clk_disable_unprepare(ssi->clk);
        clk_put(ssi->clk);
        kfree(ssi);
 
index 7cee22515d9de55c505eae1dd460107b1eacee3a..2ef98536f1da9ecff07ebd3d6903a8bf78345029 100644 (file)
@@ -1052,6 +1052,13 @@ static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
        return 0;
 }
 
+static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
+{
+       struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+       return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
+}
+
 static void fsi_dma_complete(void *data)
 {
        struct fsi_stream *io = (struct fsi_stream *)data;
@@ -1061,7 +1068,7 @@ static void fsi_dma_complete(void *data)
        enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
                DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
-       dma_sync_single_for_cpu(dai->dev, io->dma,
+       dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io),
                        samples_to_bytes(runtime, io->period_samples), dir);
 
        io->buff_sample_pos += io->period_samples;
@@ -1078,13 +1085,6 @@ static void fsi_dma_complete(void *data)
        snd_pcm_period_elapsed(io->substream);
 }
 
-static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
-{
-       struct snd_pcm_runtime *runtime = io->substream->runtime;
-
-       return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
-}
-
 static void fsi_dma_do_tasklet(unsigned long data)
 {
        struct fsi_stream *io = (struct fsi_stream *)data;
@@ -1110,7 +1110,7 @@ static void fsi_dma_do_tasklet(unsigned long data)
        len     = samples_to_bytes(runtime, io->period_samples);
        buf     = fsi_dma_get_area(io);
 
-       dma_sync_single_for_device(dai->dev, io->dma, len, dir);
+       dma_sync_single_for_device(dai->dev, buf, len, dir);
 
        sg_init_table(&sg, 1);
        sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
@@ -1172,9 +1172,16 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
 static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
                                 int start)
 {
+       struct fsi_master *master = fsi_get_master(fsi);
+       u32 clk  = fsi_is_port_a(fsi) ? CRA  : CRB;
        u32 enable = start ? DMA_ON : 0;
 
        fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
+
+       dmaengine_terminate_all(io->chan);
+
+       if (fsi_is_clk_master(fsi))
+               fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
 }
 
 static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
index 24839d932648c81849ecfe63214a8124d914dd0e..cdf8b7601973406c445c69c6e5cd4afbdbbdf23b 100644 (file)
@@ -788,6 +788,9 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
        int count = 0, needs_knot = 0;
        int err;
 
+       kfree(subs->rate_list.list);
+       subs->rate_list.list = NULL;
+
        list_for_each_entry(fp, &subs->fmt_list, list) {
                if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
                        return 0;