summaryrefslogtreecommitdiffstats
path: root/sound/pci/pcxhr/pcxhr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-11 04:13:25 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-11 04:13:25 +0200
commita2ce35273c2f1aa0dcddd8822681d64ee5f31852 (patch)
treefac2b4d526b6ca6657ea7c1b0a25efe76a3a0b5e /sound/pci/pcxhr/pcxhr.c
parentMerge tag 'edac/v3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/m... (diff)
parentMerge tag 'asoc-v3.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/bro... (diff)
downloadlinux-a2ce35273c2f1aa0dcddd8822681d64ee5f31852.tar.xz
linux-a2ce35273c2f1aa0dcddd8822681d64ee5f31852.zip
Merge tag 'sound-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This time it's a relatively calm update batch, but the amount isn't too small in the end. Here we go over some highlights: ALSA core: - One major change is the support of nonatomic PCM operations. This allows the trigger and other callbacks to call schedule(), which would be useful for mailbox type communications. Already some drivers (Digigram ones) have been converted to use together with threaded irqs as an example. - Improvement / fixes of DSD PCM format support HD-audio: - Large volume of rewrites are found in Realtek codec driver for converting Dell and HP quirks to generic forms. - Inverted dmic code cleanup from David. - Realtek COEF access has been optimized. - Now HD-audio jack infrastructure allows multiple callbacks, which fixes / simplifies the jack-dependent power controls on STAC/IDT and VIA codecs. - Many additional device-specific fixups as usual - A few deadcode cleanups, CA0132 code cleanup, etc. ASoC: - More componentization work from Lars-Peter, this time mainly cleaning up the suspend and bias level transition callbacks. - Real system support for the Intel drivers and a bunch of fixes and enhancements for the associated CODEC drivers, this is going to need a lot quirks over time due to the lack of any firmware description of the boards. - Jack detect support for simple card from Dylan Reid. - A bunch of small fixes and enhancements for the Freescale drivers. - New drivers for Analog Devices SSM4567, Cirrus Logic CS35L32, Everest Semiconductor ES8328 and Freescale cards using the ASRC in newer i.MX processors. - A few simple-card fixes, mostly cleanups but also a fix for interaction between GPIO 0 and simple-card. Misc: - Virtuoso / Oxygen updates by Clemens - USB-audio: Yamaha MOTIF XF MIDI port name fixes - Conversion of kernel messages to standard dev_*() in ctxfi driver" * tag 'sound-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (251 commits) ASoC: mc13783: Ensure we only try to dereference valid of_nodes ASoC: rockchip-i2s: fix infinite loop in rockchip_snd_txctrl ALSA: hda - Add dock port support to Thinkpad L440 (71aa:501e) ALSA: Allow pass NULL dev for snd_pci_quirk_lookup() ASoC: imx-es8328: Fix of_node_put() call with uninitialized object ASoC: soc-pcm: fix sig_bits determination in soc_pcm_apply_msb() ASoC: simple-card: Initialize headphone and mic GPIO numbers ASoC: imx-es8328: Fix missing return code in imx_es8328_probe() ALSA: hda - Add dock support for Thinkpad T440 (17aa:2212) ALSA: usb: caiaq: check for cdev->n_streams > 1 ASoC: 88pm860x-codec: Fix possibly missing string termination ASoC: core: fix use after free in snd_soc_remove_platform() ASoC: soc-dapm: fix use after free ALSA: hda - Make the inv dmic handling for Realtek use generic parser ALSA: hda - Add Inverted Internal mic for Samsung Ativ book 9 (NP900X3G) ALSA: hda - Add inverted internal mic for Asus Aspire 4830T ASoC: Intel: byt-rt5640: fix coccinelle warnings ASoC: fsl_esai doc: Add "fsl,vf610-esai" as compatible string ASoC: da732x: Remove unnecessary KERN_ERR in pr_err() ASoC: simple-card: Fix detect gpio documentation. ...
Diffstat (limited to 'sound/pci/pcxhr/pcxhr.c')
-rw-r--r--sound/pci/pcxhr/pcxhr.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 68a37a7906c1..b854fc5e01f5 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -702,13 +702,11 @@ static inline int pcxhr_stream_scheduled_get_pipe(struct pcxhr_stream *stream,
return 0;
}
-static void pcxhr_trigger_tasklet(unsigned long arg)
+static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
{
- unsigned long flags;
int i, j, err;
struct pcxhr_pipe *pipe;
struct snd_pcxhr *chip;
- struct pcxhr_mgr *mgr = (struct pcxhr_mgr*)(arg);
int capture_mask = 0;
int playback_mask = 0;
@@ -736,11 +734,11 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
}
if (capture_mask == 0 && playback_mask == 0) {
mutex_unlock(&mgr->setup_mutex);
- dev_err(&mgr->pci->dev, "pcxhr_trigger_tasklet : no pipes\n");
+ dev_err(&mgr->pci->dev, "pcxhr_start_linked_stream : no pipes\n");
return;
}
- dev_dbg(&mgr->pci->dev, "pcxhr_trigger_tasklet : "
+ dev_dbg(&mgr->pci->dev, "pcxhr_start_linked_stream : "
"playback_mask=%x capture_mask=%x\n",
playback_mask, capture_mask);
@@ -748,7 +746,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
if (err) {
mutex_unlock(&mgr->setup_mutex);
- dev_err(&mgr->pci->dev, "pcxhr_trigger_tasklet : "
+ dev_err(&mgr->pci->dev, "pcxhr_start_linked_stream : "
"error stop pipes (P%x C%x)\n",
playback_mask, capture_mask);
return;
@@ -793,7 +791,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
if (err) {
mutex_unlock(&mgr->setup_mutex);
- dev_err(&mgr->pci->dev, "pcxhr_trigger_tasklet : "
+ dev_err(&mgr->pci->dev, "pcxhr_start_linked_stream : "
"error start pipes (P%x C%x)\n",
playback_mask, capture_mask);
return;
@@ -802,7 +800,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
/* put the streams into the running state now
* (increment pointer by interrupt)
*/
- spin_lock_irqsave(&mgr->lock, flags);
+ mutex_lock(&mgr->lock);
for ( i =0; i < mgr->num_cards; i++) {
struct pcxhr_stream *stream;
chip = mgr->chip[i];
@@ -820,13 +818,13 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
}
}
}
- spin_unlock_irqrestore(&mgr->lock, flags);
+ mutex_unlock(&mgr->lock);
mutex_unlock(&mgr->setup_mutex);
#ifdef CONFIG_SND_DEBUG_VERBOSE
do_gettimeofday(&my_tv2);
- dev_dbg(&mgr->pci->dev, "***TRIGGER TASKLET*** TIME = %ld (err = %x)\n",
+ dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n",
(long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
#endif
}
@@ -853,7 +851,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
PCXHR_STREAM_STATUS_SCHEDULE_RUN;
snd_pcm_trigger_done(s, subs);
}
- tasklet_schedule(&chip->mgr->trigger_taskq);
+ pcxhr_start_linked_stream(chip->mgr);
} else {
stream = subs->runtime->private_data;
snd_printdd("Only one Substream %c %d\n",
@@ -1127,20 +1125,19 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
{
- unsigned long flags;
u_int32_t timer_period_frag;
int timer_buf_periods;
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
struct snd_pcm_runtime *runtime = subs->runtime;
struct pcxhr_stream *stream = runtime->private_data;
- spin_lock_irqsave(&chip->mgr->lock, flags);
+ mutex_lock(&chip->mgr->lock);
/* get the period fragment and the nb of periods in the buffer */
timer_period_frag = stream->timer_period_frag;
timer_buf_periods = stream->timer_buf_periods;
- spin_unlock_irqrestore(&chip->mgr->lock, flags);
+ mutex_unlock(&chip->mgr->lock);
return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +
timer_period_frag);
@@ -1181,6 +1178,7 @@ int pcxhr_create_pcm(struct snd_pcxhr *chip)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcxhr_ops);
pcm->info_flags = 0;
+ pcm->nonatomic = true;
strcpy(pcm->name, name);
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
@@ -1588,8 +1586,9 @@ static int pcxhr_probe(struct pci_dev *pci,
mgr->pci = pci;
mgr->irq = -1;
- if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, mgr)) {
+ if (request_threaded_irq(pci->irq, pcxhr_interrupt,
+ pcxhr_threaded_irq, IRQF_SHARED,
+ KBUILD_MODNAME, mgr)) {
dev_err(&pci->dev, "unable to grab IRQ %d\n", pci->irq);
pcxhr_free(mgr);
return -EBUSY;
@@ -1601,19 +1600,13 @@ static int pcxhr_probe(struct pci_dev *pci,
mgr->shortname,
mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
- /* ISR spinlock */
- spin_lock_init(&mgr->lock);
- spin_lock_init(&mgr->msg_lock);
+ /* ISR lock */
+ mutex_init(&mgr->lock);
+ mutex_init(&mgr->msg_lock);
/* init setup mutex*/
mutex_init(&mgr->setup_mutex);
- /* init taslket */
- tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet,
- (unsigned long) mgr);
- tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet,
- (unsigned long) mgr);
-
mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
PCXHR_SIZE_MAX_STATUS),