diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ctxfi/ctatc.c | 22 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctatc.h | 4 | ||||
-rw-r--r-- | sound/pci/ctxfi/cttimer.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 24 |
5 files changed, 35 insertions, 35 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 80fb2baed7a..b0adc809400 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -259,7 +259,6 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int n_amixer = apcm->substream->runtime->channels, i = 0; int device = apcm->substream->pcm->device; unsigned int pitch; - unsigned long flags; if (NULL != apcm->src) { /* Prepared pcm playback */ @@ -311,10 +310,10 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) src = apcm->src; for (i = 0; i < n_amixer; i++) { amixer = apcm->amixers[i]; - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); amixer->ops->setup(amixer, &src->rsc, INIT_VOL, atc->pcm[i+device*2]); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); src = src->ops->next_interleave(src); if (NULL == src) src = apcm->src; @@ -865,7 +864,6 @@ static int spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) { struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); - unsigned long flags; unsigned int rate = apcm->substream->runtime->rate; unsigned int status; int err; @@ -885,7 +883,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) return -ENOENT; } - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao->ops->get_spos(dao, &status); if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { status &= ((~IEC958_AES3_CON_FS) << 24); @@ -895,7 +893,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) } if ((rate != atc->pll_rate) && (32000 != rate)) err = atc_pll_init(atc, rate); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); return err; } @@ -908,7 +906,6 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct dao *dao; int err; int i; - unsigned long flags; if (NULL != apcm->src) return 0; @@ -934,13 +931,13 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) src = apcm->src; } /* Connect to SPDIFOO */ - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao = container_of(atc->daios[SPDIFOO], struct dao, daio); amixer = apcm->amixers[0]; dao->ops->set_left_input(dao, &amixer->rsc); amixer = apcm->amixers[1]; dao->ops->set_right_input(dao, &amixer->rsc); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); ct_timer_prepare(apcm->timer); @@ -1088,7 +1085,6 @@ static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status) static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) { - unsigned long flags; struct dao_desc da_dsc = {0}; struct dao *dao; int err; @@ -1096,7 +1092,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) struct rsc *rscs[2] = {NULL}; unsigned int spos = 0; - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao = container_of(atc->daios[SPDIFOO], struct dao, daio); da_dsc.msr = state ? 1 : atc->msr; da_dsc.passthru = state ? 1 : 0; @@ -1114,7 +1110,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) } dao->ops->set_spos(dao, spos); dao->ops->commit_write(dao); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); return err; } @@ -1572,7 +1568,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, atc->msr = msr; atc->chip_type = chip_type; - spin_lock_init(&atc->atc_lock); + mutex_init(&atc->atc_mutex); /* Find card model */ err = atc_identify_card(atc); diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index a03347232e8..9fe620ea5f3 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -19,7 +19,7 @@ #define CTATC_H #include <linux/types.h> -#include <linux/spinlock_types.h> +#include <linux/mutex.h> #include <linux/pci.h> #include <linux/timer.h> #include <sound/core.h> @@ -90,7 +90,7 @@ struct ct_atc { void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); - spinlock_t atc_lock; + struct mutex atc_mutex; int (*pcm_playback_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm); diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index 779c6c3591a..93b0aedc36d 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c @@ -180,7 +180,7 @@ static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer) * * call this inside the lock and irq disabled */ -static int ct_xfitimer_reprogram(struct ct_timer *atimer) +static int ct_xfitimer_reprogram(struct ct_timer *atimer, int can_update) { struct ct_timer_instance *ti; unsigned int min_intr = (unsigned int)-1; @@ -216,6 +216,8 @@ static int ct_xfitimer_reprogram(struct ct_timer *atimer) ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ + rate - 1, rate); } + if (ti->need_update && !can_update) + min_intr = 0; /* pending to the next irq */ if (ti->frag_count < min_intr) min_intr = ti->frag_count; } @@ -235,7 +237,7 @@ static void ct_xfitimer_check_period(struct ct_timer *atimer) spin_lock_irqsave(&atimer->list_lock, flags); list_for_each_entry(ti, &atimer->instance_head, instance_list) { - if (ti->need_update) { + if (ti->running && ti->need_update) { ti->need_update = 0; ti->apcm->interrupt(ti->apcm); } @@ -252,7 +254,7 @@ static void ct_xfitimer_callback(struct ct_timer *atimer) spin_lock_irqsave(&atimer->lock, flags); atimer->irq_handling = 1; do { - update = ct_xfitimer_reprogram(atimer); + update = ct_xfitimer_reprogram(atimer, 1); spin_unlock(&atimer->lock); if (update) ct_xfitimer_check_period(atimer); @@ -265,6 +267,7 @@ static void ct_xfitimer_callback(struct ct_timer *atimer) static void ct_xfitimer_prepare(struct ct_timer_instance *ti) { ti->frag_count = ti->substream->runtime->period_size; + ti->running = 0; ti->need_update = 0; } @@ -273,7 +276,6 @@ static void ct_xfitimer_prepare(struct ct_timer_instance *ti) static void ct_xfitimer_update(struct ct_timer *atimer) { unsigned long flags; - int update; spin_lock_irqsave(&atimer->lock, flags); if (atimer->irq_handling) { @@ -284,10 +286,8 @@ static void ct_xfitimer_update(struct ct_timer *atimer) } ct_xfitimer_irq_stop(atimer); - update = ct_xfitimer_reprogram(atimer); + ct_xfitimer_reprogram(atimer, 0); spin_unlock_irqrestore(&atimer->lock, flags); - if (update) - ct_xfitimer_check_period(atimer); } static void ct_xfitimer_start(struct ct_timer_instance *ti) @@ -298,6 +298,8 @@ static void ct_xfitimer_start(struct ct_timer_instance *ti) spin_lock_irqsave(&atimer->lock, flags); if (list_empty(&ti->running_list)) atimer->wc = ct_xfitimer_get_wc(atimer); + ti->running = 1; + ti->need_update = 0; list_add(&ti->running_list, &atimer->running_head); spin_unlock_irqrestore(&atimer->lock, flags); ct_xfitimer_update(atimer); @@ -310,7 +312,7 @@ static void ct_xfitimer_stop(struct ct_timer_instance *ti) spin_lock_irqsave(&atimer->lock, flags); list_del_init(&ti->running_list); - ti->need_update = 0; + ti->running = 0; spin_unlock_irqrestore(&atimer->lock, flags); ct_xfitimer_update(atimer); } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 337d2a59c67..d22b2606801 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9014,6 +9014,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", ALC888_ACER_ASPIRE_8930G), + SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", + ALC888_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 173bebf9f51..8aa5687f392 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -356,8 +356,6 @@ struct ichdev { unsigned int position; unsigned int pos_shift; unsigned int last_pos; - unsigned long last_pos_jiffies; - unsigned int jiffy_to_bytes; int frags; int lvi; int lvi_frag; @@ -844,7 +842,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: val = ICH_IOCE | ICH_STARTBM; ichdev->last_pos = ichdev->position; - ichdev->last_pos_jiffies = jiffies; break; case SNDRV_PCM_TRIGGER_SUSPEND: ichdev->suspended = 1; @@ -1048,7 +1045,6 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; } snd_intel8x0_setup_periods(chip, ichdev); - ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ; return 0; } @@ -1073,19 +1069,23 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) break; } while (timeout--); + ptr = ichdev->last_pos; if (ptr1 != 0) { ptr1 <<= ichdev->pos_shift; ptr = ichdev->fragsize1 - ptr1; ptr += position; - ichdev->last_pos = ptr; - ichdev->last_pos_jiffies = jiffies; - } else { - ptr1 = jiffies - ichdev->last_pos_jiffies; - if (ptr1) - ptr1 -= 1; - ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes; - ptr %= ichdev->size; + if (ptr < ichdev->last_pos) { + unsigned int pos_base, last_base; + pos_base = position / ichdev->fragsize1; + last_base = ichdev->last_pos / ichdev->fragsize1; + /* another sanity check; ptr1 can go back to full + * before the base position is updated + */ + if (pos_base == last_base) + ptr = ichdev->last_pos; + } } + ichdev->last_pos = ptr; spin_unlock(&chip->reg_lock); if (ptr >= ichdev->size) return 0; |