Commit c66bce9b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Except for a slightly big OMAP changes, all rest are small, mostly
  boring changes; all either 3.11 regression fixes or stable materials.

   - ASoC OMAP fixes due to non-DT OMAP4 removals
   - Other ASoC driver changes (sglt5000, wm8978, wm8948, samsung)
   - Fix missing locking for snd_pcm_stop() calls in many drivers
   - Fix the blocking request_module() in OSS sequencer
   - Fix old OSS vwsnd driver builds
   - Add a new HD-audio HDMI codec ID"

* tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (23 commits)
  ALSA: seq-oss: Initialize MIDI clients asynchronously
  ALSA: hda - Add new GPU codec ID to snd-hda
  staging: line6: Fix unlocked snd_pcm_stop() call
  [media] saa7134: Fix unlocked snd_pcm_stop() call
  ASoC: s6000: Fix unlocked snd_pcm_stop() call
  ASoC: atmel: Fix unlocked snd_pcm_stop() call
  ALSA: pxa2xx: Fix unlocked snd_pcm_stop() call
  ALSA: usx2y: Fix unlocked snd_pcm_stop() call
  ALSA: ua101: Fix unlocked snd_pcm_stop() call
  ALSA: 6fire: Fix unlocked snd_pcm_stop() call
  ALSA: atiixp: Fix unlocked snd_pcm_stop() call
  ALSA: asihpi: Fix unlocked snd_pcm_stop() call
  sound: oss/vwsnd: Always define vwsnd_mutex
  sound: oss/vwsnd: Add missing inclusion of linux/delay.h
  ASoC: wm8978: enable symmetric rates
  ASoC: omap-mcbsp: Use different method for DMA request when booted with DT
  ASoC: omap-dmic: Do not use platform_get_resource_byname() for DMA
  ASoC: omap-mcpdm: Do not use platform_get_resource_byname() for DMA
  ASoC: omap-pcm: Request the DMA channel differently when DT is involved
  ASoC: Samsung: Set RFS and BFS in slave mode
  ...
parents 61f98b0f 256ca9c3
...@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, ...@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
dev->dmasound.bufsize, dev->dmasound.blocks); dev->dmasound.bufsize, dev->dmasound.blocks);
spin_unlock(&dev->slock); spin_unlock(&dev->slock);
snd_pcm_stream_lock(dev->dmasound.substream);
snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(dev->dmasound.substream);
return; return;
} }
......
...@@ -392,8 +392,11 @@ static int snd_line6_pcm_free(struct snd_device *device) ...@@ -392,8 +392,11 @@ static int snd_line6_pcm_free(struct snd_device *device)
*/ */
static void pcm_disconnect_substream(struct snd_pcm_substream *substream) static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
{ {
if (substream->runtime && snd_pcm_running(substream)) if (substream->runtime && snd_pcm_running(substream)) {
snd_pcm_stream_lock_irq(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
snd_pcm_stream_unlock_irq(substream);
}
} }
/* /*
......
...@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) ...@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
} else { } else {
printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
rtd->params->name, dma_ch, dcsr); rtd->params->name, dma_ch, dcsr);
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(substream);
} }
} }
EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/workqueue.h>
/* /*
* common variables * common variables
...@@ -60,6 +61,14 @@ static void free_devinfo(void *private); ...@@ -60,6 +61,14 @@ static void free_devinfo(void *private);
#define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec) #define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)
/* call snd_seq_oss_midi_lookup_ports() asynchronously */
static void async_call_lookup_ports(struct work_struct *work)
{
snd_seq_oss_midi_lookup_ports(system_client);
}
static DECLARE_WORK(async_lookup_work, async_call_lookup_ports);
/* /*
* create sequencer client for OSS sequencer * create sequencer client for OSS sequencer
*/ */
...@@ -85,9 +94,6 @@ snd_seq_oss_create_client(void) ...@@ -85,9 +94,6 @@ snd_seq_oss_create_client(void)
system_client = rc; system_client = rc;
debug_printk(("new client = %d\n", rc)); debug_printk(("new client = %d\n", rc));
/* look up midi devices */
snd_seq_oss_midi_lookup_ports(system_client);
/* create annoucement receiver port */ /* create annoucement receiver port */
memset(port, 0, sizeof(*port)); memset(port, 0, sizeof(*port));
strcpy(port->name, "Receiver"); strcpy(port->name, "Receiver");
...@@ -115,6 +121,9 @@ snd_seq_oss_create_client(void) ...@@ -115,6 +121,9 @@ snd_seq_oss_create_client(void)
} }
rc = 0; rc = 0;
/* look up midi devices */
schedule_work(&async_lookup_work);
__error: __error:
kfree(port); kfree(port);
return rc; return rc;
...@@ -160,6 +169,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic ...@@ -160,6 +169,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic
int int
snd_seq_oss_delete_client(void) snd_seq_oss_delete_client(void)
{ {
cancel_work_sync(&async_lookup_work);
if (system_client >= 0) if (system_client >= 0)
snd_seq_delete_kernel_client(system_client); snd_seq_delete_kernel_client(system_client);
......
...@@ -72,7 +72,7 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, ...@@ -72,7 +72,7 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
* look up the existing ports * look up the existing ports
* this looks a very exhausting job. * this looks a very exhausting job.
*/ */
int __init int
snd_seq_oss_midi_lookup_ports(int client) snd_seq_oss_midi_lookup_ports(int client)
{ {
struct snd_seq_client_info *clinfo; struct snd_seq_client_info *clinfo;
......
...@@ -149,17 +149,19 @@ ...@@ -149,17 +149,19 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h>
#include <asm/visws/cobalt.h> #include <asm/visws/cobalt.h>
#include "sound_config.h" #include "sound_config.h"
static DEFINE_MUTEX(vwsnd_mutex);
/*****************************************************************************/ /*****************************************************************************/
/* debug stuff */ /* debug stuff */
#ifdef VWSND_DEBUG #ifdef VWSND_DEBUG
static DEFINE_MUTEX(vwsnd_mutex);
static int shut_up = 1; static int shut_up = 1;
/* /*
......
...@@ -769,7 +769,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) ...@@ -769,7 +769,10 @@ static void snd_card_asihpi_timer_function(unsigned long data)
s->number); s->number);
ds->drained_count++; ds->drained_count++;
if (ds->drained_count > 20) { if (ds->drained_count > 20) {
unsigned long flags;
snd_pcm_stream_lock_irqsave(s, flags);
snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(s, flags);
continue; continue;
} }
} else { } else {
......
...@@ -689,7 +689,9 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) ...@@ -689,7 +689,9 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma)
if (! dma->substream || ! dma->running) if (! dma->substream || ! dma->running)
return; return;
snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
snd_pcm_stream_lock(dma->substream);
snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(dma->substream);
} }
/* /*
......
...@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip, ...@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip,
if (! dma->substream || ! dma->running) if (! dma->substream || ! dma->running)
return; return;
snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type); snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type);
snd_pcm_stream_lock(dma->substream);
snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(dma->substream);
} }
/* /*
......
...@@ -2622,6 +2622,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { ...@@ -2622,6 +2622,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi },
{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_generic_hdmi },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
...@@ -2674,6 +2675,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0042"); ...@@ -2674,6 +2675,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0042");
MODULE_ALIAS("snd-hda-codec-id:10de0043"); MODULE_ALIAS("snd-hda-codec-id:10de0043");
MODULE_ALIAS("snd-hda-codec-id:10de0044"); MODULE_ALIAS("snd-hda-codec-id:10de0044");
MODULE_ALIAS("snd-hda-codec-id:10de0051"); MODULE_ALIAS("snd-hda-codec-id:10de0051");
MODULE_ALIAS("snd-hda-codec-id:10de0060");
MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de0067");
MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_ALIAS("snd-hda-codec-id:10de8001");
MODULE_ALIAS("snd-hda-codec-id:11069f80"); MODULE_ALIAS("snd-hda-codec-id:11069f80");
......
...@@ -81,7 +81,9 @@ static void atmel_pcm_dma_irq(u32 ssc_sr, ...@@ -81,7 +81,9 @@ static void atmel_pcm_dma_irq(u32 ssc_sr,
/* stop RX and capture: will be enabled again at restart */ /* stop RX and capture: will be enabled again at restart */
ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable);
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(substream);
/* now drain RHR and read status to remove xrun condition */ /* now drain RHR and read status to remove xrun condition */
ssc_readx(prtd->ssc->regs, SSC_RHR); ssc_readx(prtd->ssc->regs, SSC_RHR);
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
static const struct reg_default sgtl5000_reg_defaults[] = { static const struct reg_default sgtl5000_reg_defaults[] = {
{ SGTL5000_CHIP_CLK_CTRL, 0x0008 }, { SGTL5000_CHIP_CLK_CTRL, 0x0008 },
{ SGTL5000_CHIP_I2S_CTRL, 0x0010 }, { SGTL5000_CHIP_I2S_CTRL, 0x0010 },
{ SGTL5000_CHIP_SSS_CTRL, 0x0008 }, { SGTL5000_CHIP_SSS_CTRL, 0x0010 },
{ SGTL5000_CHIP_DAC_VOL, 0x3c3c }, { SGTL5000_CHIP_DAC_VOL, 0x3c3c },
{ SGTL5000_CHIP_PAD_STRENGTH, 0x015f }, { SGTL5000_CHIP_PAD_STRENGTH, 0x015f },
{ SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 }, { SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 },
......
...@@ -347,7 +347,7 @@ ...@@ -347,7 +347,7 @@
#define SGTL5000_PLL_INT_DIV_MASK 0xf800 #define SGTL5000_PLL_INT_DIV_MASK 0xf800
#define SGTL5000_PLL_INT_DIV_SHIFT 11 #define SGTL5000_PLL_INT_DIV_SHIFT 11
#define SGTL5000_PLL_INT_DIV_WIDTH 5 #define SGTL5000_PLL_INT_DIV_WIDTH 5
#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700 #define SGTL5000_PLL_FRAC_DIV_MASK 0x07ff
#define SGTL5000_PLL_FRAC_DIV_SHIFT 0 #define SGTL5000_PLL_FRAC_DIV_SHIFT 0
#define SGTL5000_PLL_FRAC_DIV_WIDTH 11 #define SGTL5000_PLL_FRAC_DIV_WIDTH 11
......
...@@ -921,6 +921,7 @@ static struct snd_soc_dai_driver wm8978_dai = { ...@@ -921,6 +921,7 @@ static struct snd_soc_dai_driver wm8978_dai = {
.formats = WM8978_FORMATS, .formats = WM8978_FORMATS,
}, },
.ops = &wm8978_dai_ops, .ops = &wm8978_dai_ops,
.symmetric_rates = 1,
}; };
static int wm8978_suspend(struct snd_soc_codec *codec) static int wm8978_suspend(struct snd_soc_codec *codec)
......
...@@ -3852,8 +3852,6 @@ static void wm8958_mic_work(struct work_struct *work) ...@@ -3852,8 +3852,6 @@ static void wm8958_mic_work(struct work_struct *work)
mic_complete_work.work); mic_complete_work.work);
struct snd_soc_codec *codec = wm8994->hubs.codec; struct snd_soc_codec *codec = wm8994->hubs.codec;
dev_crit(codec->dev, "MIC WORK %x\n", wm8994->mic_status);
pm_runtime_get_sync(codec->dev); pm_runtime_get_sync(codec->dev);
mutex_lock(&wm8994->accdet_lock); mutex_lock(&wm8994->accdet_lock);
...@@ -3863,8 +3861,6 @@ static void wm8958_mic_work(struct work_struct *work) ...@@ -3863,8 +3861,6 @@ static void wm8958_mic_work(struct work_struct *work)
mutex_unlock(&wm8994->accdet_lock); mutex_unlock(&wm8994->accdet_lock);
pm_runtime_put(codec->dev); pm_runtime_put(codec->dev);
dev_crit(codec->dev, "MIC WORK %x DONE\n", wm8994->mic_status);
} }
static irqreturn_t wm8958_mic_irq(int irq, void *data) static irqreturn_t wm8958_mic_irq(int irq, void *data)
......
...@@ -1012,28 +1012,33 @@ int omap_mcbsp_init(struct platform_device *pdev) ...@@ -1012,28 +1012,33 @@ int omap_mcbsp_init(struct platform_device *pdev)
} }
} }
if (!pdev->dev.of_node) {
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
if (!res) {
dev_err(&pdev->dev, "invalid tx DMA channel\n");
return -ENODEV;
}
mcbsp->dma_req[0] = res->start;
mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
if (!res) { if (!res) {
dev_err(&pdev->dev, "invalid rx DMA channel\n"); dev_err(&pdev->dev, "invalid rx DMA channel\n");
return -ENODEV; return -ENODEV;
} }
/* RX DMA request number, and port address configuration */
mcbsp->dma_req[1] = res->start; mcbsp->dma_req[1] = res->start;
mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1]; mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1); } else {
mcbsp->dma_data[1].maxburst = 4; mcbsp->dma_data[0].filter_data = "tx";
mcbsp->dma_data[1].filter_data = "rx";
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
if (!res) {
dev_err(&pdev->dev, "invalid tx DMA channel\n");
return -ENODEV;
} }
/* TX DMA request number, and port address configuration */
mcbsp->dma_req[0] = res->start;
mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0); mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
mcbsp->dma_data[0].maxburst = 4; mcbsp->dma_data[0].maxburst = 4;
mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
mcbsp->dma_data[1].maxburst = 4;
mcbsp->fclk = clk_get(&pdev->dev, "fck"); mcbsp->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(mcbsp->fclk)) { if (IS_ERR(mcbsp->fclk)) {
ret = PTR_ERR(mcbsp->fclk); ret = PTR_ERR(mcbsp->fclk);
......
...@@ -57,7 +57,6 @@ struct omap_dmic { ...@@ -57,7 +57,6 @@ struct omap_dmic {
struct mutex mutex; struct mutex mutex;
struct snd_dmaengine_dai_dma_data dma_data; struct snd_dmaengine_dai_dma_data dma_data;
unsigned int dma_req;
}; };
static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
...@@ -478,15 +477,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) ...@@ -478,15 +477,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
} }
dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG; dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
res = platform_get_resource(pdev, IORESOURCE_DMA, 0); dmic->dma_data.filter_data = "up_link";
if (!res) {
dev_err(dmic->dev, "invalid dma resource\n");
ret = -ENODEV;
goto err_put_clk;
}
dmic->dma_req = res->start;
dmic->dma_data.filter_data = &dmic->dma_req;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
if (!res) { if (!res) {
......
...@@ -66,7 +66,6 @@ struct omap_mcpdm { ...@@ -66,7 +66,6 @@ struct omap_mcpdm {
bool restart; bool restart;
struct snd_dmaengine_dai_dma_data dma_data[2]; struct snd_dmaengine_dai_dma_data dma_data[2];
unsigned int dma_req[2];
}; };
/* /*
...@@ -477,19 +476,8 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) ...@@ -477,19 +476,8 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA; mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA;
mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA; mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); mcpdm->dma_data[0].filter_data = "dn_link";
if (!res) mcpdm->dma_data[1].filter_data = "up_link";
return -ENODEV;
mcpdm->dma_req[0] = res->start;
mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0];
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
if (!res)
return -ENODEV;
mcpdm->dma_req[1] = res->start;
mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1];
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
if (res == NULL) if (res == NULL)
......
...@@ -113,14 +113,25 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) ...@@ -113,14 +113,25 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_dmaengine_dai_dma_data *dma_data; struct snd_dmaengine_dai_dma_data *dma_data;
int ret;
snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
return snd_dmaengine_pcm_open_request_chan(substream, /* DT boot: filter_data is the DMA name */
if (rtd->cpu_dai->dev->of_node) {
struct dma_chan *chan;
chan = dma_request_slave_channel(rtd->cpu_dai->dev,
dma_data->filter_data);
ret = snd_dmaengine_pcm_open(substream, chan);
} else {
ret = snd_dmaengine_pcm_open_request_chan(substream,
omap_dma_filter_fn, omap_dma_filter_fn,
dma_data->filter_data); dma_data->filter_data);
}
return ret;
} }
static int omap_pcm_mmap(struct snd_pcm_substream *substream, static int omap_pcm_mmap(struct snd_pcm_substream *substream,
......
...@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) ...@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
substream->runtime && substream->runtime &&
snd_pcm_running(substream)) { snd_pcm_running(substream)) {
dev_dbg(pcm->dev, "xrun\n"); dev_dbg(pcm->dev, "xrun\n");
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(substream);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} }
......
...@@ -742,13 +742,13 @@ static int config_setup(struct i2s_dai *i2s) ...@@ -742,13 +742,13 @@ static int config_setup(struct i2s_dai *i2s)
return -EAGAIN; return -EAGAIN;
} }
/* Don't bother RFS, BFS & PSR in Slave mode */
if (is_slave(i2s))
return 0;
set_bfs(i2s, bfs); set_bfs(i2s, bfs);
set_rfs(i2s, rfs); set_rfs(i2s, rfs);
/* Don't bother with PSR in Slave mode */
if (is_slave(i2s))
return 0;
if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
psr = i2s->rclk_srcrate / i2s->frmclk / rfs; psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR); writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
......
...@@ -639,17 +639,25 @@ int usb6fire_pcm_init(struct sfire_chip *chip) ...@@ -639,17 +639,25 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
void usb6fire_pcm_abort(struct sfire_chip *chip) void usb6fire_pcm_abort(struct sfire_chip *chip)
{ {
struct pcm_runtime *rt = chip->pcm; struct pcm_runtime *rt = chip->pcm;
unsigned long flags;
int i; int i;
if (rt) { if (rt) {
rt->panic = true; rt->panic = true;
if (rt->playback.instance) if (rt->playback.instance) {
snd_pcm_stream_lock_irqsave(rt->playback.instance, flags);
snd_pcm_stop(rt->playback.instance, snd_pcm_stop(rt->playback.instance,
SNDRV_PCM_STATE_XRUN); SNDRV_PCM_STATE_XRUN);
if (rt->capture.instance) snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags);
}
if (rt->capture.instance) {
snd_pcm_stream_lock_irqsave(rt->capture.instance, flags);
snd_pcm_stop(rt->capture.instance, snd_pcm_stop(rt->capture.instance,
SNDRV_PCM_STATE_XRUN); SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags);
}
for (i = 0; i < PCM_N_URBS; i++) { for (i = 0; i < PCM_N_URBS; i++) {
usb_poison_urb(&rt->in_urbs[i].instance); usb_poison_urb(&rt->in_urbs[i].instance);
......
...@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua101 *ua) ...@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua101 *ua)
static void abort_alsa_capture(struct ua101 *ua) static void abort_alsa_capture(struct ua101 *ua)
{ {
if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) unsigned long flags;
if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) {
snd_pcm_stream_lock_irqsave(ua->capture.substream, flags);
snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags);
}
} }
static void abort_alsa_playback(struct ua101 *ua) static void abort_alsa_playback(struct ua101 *ua)
{ {
if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) unsigned long flags;
if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) {
snd_pcm_stream_lock_irqsave(ua->playback.substream, flags);
snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags);
}
} }
static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
......
...@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y) ...@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
struct snd_usX2Y_substream *subs = usX2Y->subs[s]; struct snd_usX2Y_substream *subs = usX2Y->subs[s];
if (subs) { if (subs) {
if (atomic_read(&subs->state) >= state_PRERUNNING) { if (atomic_read(&subs->state) >= state_PRERUNNING) {
unsigned long flags;
snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags);
snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags);
} }
for (u = 0; u < NRURBS; u++) { for (u = 0; u < NRURBS; u++) {
struct urb *urb = subs->urb[u]; struct urb *urb = subs->urb[u];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment