diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 06:13:25 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 06:13:25 +0400 |
commit | a2ce35273c2f1aa0dcddd8822681d64ee5f31852 (patch) | |
tree | fac2b4d526b6ca6657ea7c1b0a25efe76a3a0b5e /sound/drivers | |
parent | bf65dea87e87c53ba4f97c6432761498bc977efd (diff) | |
parent | fd1a2a90d08b0052fa52bd36cebd0592c9e537c2 (diff) | |
download | linux-a2ce35273c2f1aa0dcddd8822681d64ee5f31852.tar.xz |
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/drivers')
-rw-r--r-- | sound/drivers/vx/vx_core.c | 49 | ||||
-rw-r--r-- | sound/drivers/vx/vx_mixer.c | 12 | ||||
-rw-r--r-- | sound/drivers/vx/vx_pcm.c | 68 | ||||
-rw-r--r-- | sound/drivers/vx/vx_uer.c | 23 |
4 files changed, 60 insertions, 92 deletions
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index 83596891cde4..e8cc16993903 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -117,7 +117,7 @@ static int vx_reset_chk(struct vx_core *chip) * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). - * NB: call with spinlock held! + * NB: call with mutex held! */ static int vx_transfer_end(struct vx_core *chip, int cmd) { @@ -155,7 +155,7 @@ static int vx_transfer_end(struct vx_core *chip, int cmd) * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). - * NB: call with spinlock held! + * NB: call with mutex held! */ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh) { @@ -236,7 +236,7 @@ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh) * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * - * this function doesn't call spinlock at all. + * this function doesn't call mutex lock at all. */ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) { @@ -337,7 +337,7 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) /* - * vx_send_msg - send a DSP message with spinlock + * vx_send_msg - send a DSP message with mutex * @rmh: the rmh record to send and receive * * returns 0 if successful, or a negative error code. @@ -345,12 +345,11 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) */ int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh) { - unsigned long flags; int err; - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); err = vx_send_msg_nolock(chip, rmh); - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); return err; } @@ -362,7 +361,7 @@ int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh) * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * - * this function doesn't call spinlock at all. + * this function doesn't call mutex at all. * * unlike RMH, no command is sent to DSP. */ @@ -398,19 +397,18 @@ int vx_send_rih_nolock(struct vx_core *chip, int cmd) /* - * vx_send_rih - send an RIH with spinlock + * vx_send_rih - send an RIH with mutex * @cmd: the command to send * * see vx_send_rih_nolock(). */ int vx_send_rih(struct vx_core *chip, int cmd) { - unsigned long flags; int err; - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); err = vx_send_rih_nolock(chip, cmd); - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); return err; } @@ -482,30 +480,30 @@ static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret) int err; vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT); - spin_lock(&chip->lock); + mutex_lock(&chip->lock); err = vx_send_msg_nolock(chip, &chip->irq_rmh); if (err < 0) *ret = 0; else *ret = chip->irq_rmh.Stat[0]; - spin_unlock(&chip->lock); + mutex_unlock(&chip->lock); return err; } /* - * vx_interrupt - soft irq handler + * snd_vx_threaded_irq_handler - threaded irq handler */ -static void vx_interrupt(unsigned long private_data) +irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev) { - struct vx_core *chip = (struct vx_core *) private_data; + struct vx_core *chip = dev; unsigned int events; if (chip->chip_status & VX_STAT_IS_STALE) - return; + return IRQ_HANDLED; if (vx_test_irq_src(chip, &events) < 0) - return; + return IRQ_HANDLED; #if 0 if (events & 0x000800) @@ -519,7 +517,7 @@ static void vx_interrupt(unsigned long private_data) */ if (events & FATAL_DSP_ERROR) { snd_printk(KERN_ERR "vx_core: fatal DSP error!!\n"); - return; + return IRQ_HANDLED; } /* The start on time code conditions are filled (ie the time code @@ -534,8 +532,9 @@ static void vx_interrupt(unsigned long private_data) /* update the pcm streams */ vx_pcm_update_intr(chip, events); + return IRQ_HANDLED; } - +EXPORT_SYMBOL(snd_vx_threaded_irq_handler); /** * snd_vx_irq_handler - interrupt handler @@ -548,8 +547,8 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev) (chip->chip_status & VX_STAT_IS_STALE)) return IRQ_NONE; if (! vx_test_and_ack(chip)) - tasklet_schedule(&chip->tq); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; + return IRQ_NONE; } EXPORT_SYMBOL(snd_vx_irq_handler); @@ -790,13 +789,11 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw, snd_printk(KERN_ERR "vx_core: no memory\n"); return NULL; } - spin_lock_init(&chip->lock); - spin_lock_init(&chip->irq_lock); + mutex_init(&chip->lock); chip->irq = -1; chip->hw = hw; chip->type = hw->type; chip->ops = ops; - tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip); mutex_init(&chip->mixer_mutex); chip->card = card; diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index c71b8d148d7f..3b6823fc0606 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c @@ -32,17 +32,15 @@ */ static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data) { - unsigned long flags; - if (snd_BUG_ON(!chip->ops->write_codec)) return; if (chip->chip_status & VX_STAT_IS_STALE) return; - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); chip->ops->write_codec(chip, codec, data); - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); } /* @@ -178,14 +176,12 @@ void vx_reset_codec(struct vx_core *chip, int cold_reset) */ static void vx_change_audio_source(struct vx_core *chip, int src) { - unsigned long flags; - if (chip->chip_status & VX_STAT_IS_STALE) return; - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); chip->ops->change_audio_source(chip, src); - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); } diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index deed5efff33c..11467272089e 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -229,7 +229,7 @@ static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *st vx_init_rmh(&rmh, CMD_PIPE_STATE); vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); - err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + err = vx_send_msg(chip, &rmh); if (! err) *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0; return err; @@ -280,7 +280,7 @@ static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe) vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); rmh.Cmd[0] |= 1; - err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + err = vx_send_msg(chip, &rmh); if (! err) { if (rmh.Stat[0]) err = 1; @@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe) if (pipe->is_capture) rmh.Cmd[0] |= COMMAND_RECORD_MASK; rmh.Cmd[1] = 1 << pipe->number; - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } /* @@ -311,7 +311,7 @@ static int vx_send_irqa(struct vx_core *chip) struct vx_rmh rmh; vx_init_rmh(&rmh, CMD_SEND_IRQA); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -389,7 +389,7 @@ static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe) struct vx_rmh rmh; vx_init_rmh(&rmh, CMD_STOP_PIPE); vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -477,7 +477,7 @@ static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe) vx_init_rmh(&rmh, CMD_START_ONE_STREAM); vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); vx_set_differed_time(chip, &rmh, pipe); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -492,7 +492,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe) vx_init_rmh(&rmh, CMD_STOP_STREAM); vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); - return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ + return vx_send_msg(chip, &rmh); } @@ -520,8 +520,6 @@ static struct snd_pcm_hardware vx_pcm_playback_hw = { }; -static void vx_pcm_delayed_start(unsigned long arg); - /* * vx_pcm_playback_open - open callback for playback */ @@ -553,7 +551,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs) pipe->references++; pipe->substream = subs; - tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); chip->playback_pipes[audio] = pipe; runtime->hw = vx_pcm_playback_hw; @@ -646,12 +643,12 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip, /* we don't need irqsave here, because this function * is called from either trigger callback or irq handler */ - spin_lock(&chip->lock); + mutex_lock(&chip->lock); vx_pseudo_dma_write(chip, runtime, pipe, size); err = vx_notify_end_of_buffer(chip, pipe); /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); - spin_unlock(&chip->lock); + mutex_unlock(&chip->lock); return err; } @@ -728,31 +725,6 @@ static void vx_pcm_playback_update(struct vx_core *chip, } /* - * start the stream and pipe. - * this function is called from tasklet, which is invoked by the trigger - * START callback. - */ -static void vx_pcm_delayed_start(unsigned long arg) -{ - struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg; - struct vx_core *chip = subs->pcm->private_data; - struct vx_pipe *pipe = subs->runtime->private_data; - int err; - - /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/ - - if ((err = vx_start_stream(chip, pipe)) < 0) { - snd_printk(KERN_ERR "vx: cannot start stream\n"); - return; - } - if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) { - snd_printk(KERN_ERR "vx: cannot start pipe\n"); - return; - } - /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/ -} - -/* * vx_pcm_playback_trigger - trigger callback for playback */ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) @@ -769,11 +741,17 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) case SNDRV_PCM_TRIGGER_RESUME: if (! pipe->is_capture) vx_pcm_playback_transfer(chip, subs, pipe, 2); - /* FIXME: - * we trigger the pipe using tasklet, so that the interrupts are - * issued surely after the trigger is completed. - */ - tasklet_schedule(&pipe->start_tq); + err = vx_start_stream(chip, pipe); + if (err < 0) { + pr_debug("vx: cannot start stream\n"); + return err; + } + err = vx_toggle_pipe(chip, pipe, 1); + if (err < 0) { + pr_debug("vx: cannot start pipe\n"); + vx_stop_stream(chip, pipe); + return err; + } chip->pcm_running++; pipe->running = 1; break; @@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs) if (err < 0) return err; pipe->substream = subs; - tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); chip->capture_pipes[audio] = pipe; /* check if monitoring is needed */ @@ -1082,7 +1059,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream count -= 3; } /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ - vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); + vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); /* read the last pending 6 bytes */ count = DMA_READ_ALIGN; while (count > 0) { @@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream _error: /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ - vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); + vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); return; } @@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip) pcm->private_data = chip; pcm->private_free = snd_vx_pcm_free; pcm->info_flags = 0; + pcm->nonatomic = true; strcpy(pcm->name, chip->card->shortname); chip->pcm[i] = pcm; } diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c index b0560fec6bba..ef0b40c0a594 100644 --- a/sound/drivers/vx/vx_uer.c +++ b/sound/drivers/vx/vx_uer.c @@ -60,9 +60,9 @@ static int vx_modify_board_inputs(struct vx_core *chip) */ static int vx_read_one_cbit(struct vx_core *chip, int index) { - unsigned long flags; int val; - spin_lock_irqsave(&chip->lock, flags); + + mutex_lock(&chip->lock); if (chip->type >= VX_TYPE_VXPOCKET) { vx_outb(chip, CSUER, 1); /* read */ vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK); @@ -72,7 +72,7 @@ static int vx_read_one_cbit(struct vx_core *chip, int index) vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK); val = (vx_inl(chip, RUER) >> 7) & 0x01; } - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); return val; } @@ -83,9 +83,8 @@ static int vx_read_one_cbit(struct vx_core *chip, int index) */ static void vx_write_one_cbit(struct vx_core *chip, int index, int val) { - unsigned long flags; val = !!val; /* 0 or 1 */ - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); if (vx_is_pcmcia(chip)) { vx_outb(chip, CSUER, 0); /* write */ vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK)); @@ -93,7 +92,7 @@ static void vx_write_one_cbit(struct vx_core *chip, int index, int val) vx_outl(chip, CSUER, 0); /* write */ vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK)); } - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); } /* @@ -190,14 +189,12 @@ static int vx_calc_clock_from_freq(struct vx_core *chip, int freq) */ static void vx_change_clock_source(struct vx_core *chip, int source) { - unsigned long flags; - /* we mute DAC to prevent clicks */ vx_toggle_dac_mute(chip, 1); - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); chip->ops->set_clock_source(chip, source); chip->clock_source = source; - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); /* unmute */ vx_toggle_dac_mute(chip, 0); } @@ -209,11 +206,11 @@ static void vx_change_clock_source(struct vx_core *chip, int source) void vx_set_internal_clock(struct vx_core *chip, unsigned int freq) { int clock; - unsigned long flags; + /* Get real clock value */ clock = vx_calc_clock_from_freq(chip, freq); snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq); - spin_lock_irqsave(&chip->lock, flags); + mutex_lock(&chip->lock); if (vx_is_pcmcia(chip)) { vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f); vx_outb(chip, LOFREQ, clock & 0xff); @@ -221,7 +218,7 @@ void vx_set_internal_clock(struct vx_core *chip, unsigned int freq) vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f); vx_outl(chip, LOFREQ, clock & 0xff); } - spin_unlock_irqrestore(&chip->lock, flags); + mutex_unlock(&chip->lock); } |