Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef21ca24 authored by Nishanth Aravamudan's avatar Nishanth Aravamudan Committed by Jaroslav Kysela
Browse files

[ALSA] sound/pci: fix-up sleeping paths



ENS1370/1+ driver,ES1968 driver,Intel8x0 driver,VIA82xx driver
VIA82xx-modem driver,AC97 Codec,ALI5451 driver,CS46xx driver
MIXART driver,RME HDSP driver,Trident driver,YMFPCI driver
Description: Fix-up sleeping in sound/pci. These changes fall under the
following two categories:

        1) Replace schedule_timeout() with msleep() to guarantee the
        task delays as expected. This also involved replacing/removing
        custom sleep functions.
        2) Do not assume jiffies will only increment by one if you
        request a 1 jiffy sleep, i.e. use time_after/time_before in
        while loops.

Signed-off-by: default avatarNishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 072c0119
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -2227,6 +2227,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97)
void snd_ac97_resume(ac97_t *ac97)
{
	int i;
	unsigned long end_time;

	if (ac97->bus->ops->reset) {
		ac97->bus->ops->reset(ac97);
@@ -2244,26 +2245,26 @@ void snd_ac97_resume(ac97_t *ac97)
	snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
	if (ac97_is_audio(ac97)) {
		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101);
		for (i = HZ/10; i >= 0; i--) {
		end_time = jiffies + msecs_to_jiffies(100);
		do {
			if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
				break;
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(1);
		}
		} while (time_after_eq(end_time, jiffies));
		/* FIXME: extra delay */
		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
		if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(HZ/4);
		}
		if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000)
			msleep(250);
	} else {
		for (i = HZ/10; i >= 0; i--) {
		end_time = jiffies + msecs_to_jiffies(100);
		do {
			unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
			if (val != 0xffff && (val & 1) != 0)
				break;
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(1);
		}
		} while (time_after_eq(end_time, jiffies));
	}
__reset_ready:

+2 −2
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ static int snd_ali_codec_ready( ali_t *codec,
	unsigned long end_time;
	unsigned int res;
	
	end_time = jiffies + 10 * (HZ >> 2);
	end_time = jiffies + 10 * msecs_to_jiffies(250);
	do {
		res = snd_ali_5451_peek(codec,port);
		if (! (res & 0x8000))
@@ -422,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched)
	dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
	dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);

	end_time = jiffies + 10 * (HZ >> 2);
	end_time = jiffies + 10 * msecs_to_jiffies(250);
	do {
		dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
		if (dwChk2 != dwChk1)
+5 −10
Original line number Diff line number Diff line
@@ -2400,8 +2400,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97)
		if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
			return;

		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(HZ/100);
		msleep(10);
	} while (time_after_eq(end_time, jiffies));

	snd_printk("CS46xx secondary codec dont respond!\n");  
@@ -2435,8 +2434,7 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec)
			err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
			return err;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(HZ/100);
		msleep(10);
	}
	snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
	return -ENXIO;
@@ -3018,8 +3016,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
	/*
         *  Wait until the PLL has stabilized.
	 */
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(HZ/10); /* 100ms */
	msleep(100);

	/*
	 *  Turn on clocking of the core so that we can setup the serial ports.
@@ -3072,8 +3069,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
		 */
		if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
			goto ok1;
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout((HZ+99)/100);
		msleep(10);
	}


@@ -3122,8 +3118,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
		 */
		if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
			goto ok2;
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout((HZ+99)/100);
		msleep(10);
	}

#ifndef CONFIG_SND_CS46XX_NEW_DSP
+1 −11
Original line number Diff line number Diff line
@@ -2018,21 +2018,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
		if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
		    pci->device == es1371_ac97_reset_hack[idx].did &&
		    ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
		        unsigned long tmo;
			signed long tmo2;

			ensoniq->cssr |= ES_1371_ST_AC97_RST;
			outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
			/* need to delay around 20ms(bleech) to give
			some CODECs enough time to wakeup */
			tmo = jiffies + (HZ / 50) + 1;
			while (1) {
				tmo2 = tmo - jiffies;
				if (tmo2 <= 0)
					break;
				set_current_state(TASK_UNINTERRUPTIBLE);
				schedule_timeout(tmo2);
			}
			msleep(20);
			break;
		}
	/* AC'97 warm reset to start the bitclk */
+4 −10
Original line number Diff line number Diff line
@@ -664,11 +664,6 @@ static inline u16 maestro_read(es1968_t *chip, u16 reg)
	return result;
}

#define big_mdelay(msec) do {\
	set_current_state(TASK_UNINTERRUPTIBLE);\
	schedule_timeout(((msec) * HZ + 999) / 1000);\
} while (0)
	
/* Wait for the codec bus to be free */
static int snd_es1968_ac97_wait(es1968_t *chip)
{
@@ -1809,8 +1804,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
	snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
	do_gettimeofday(&start_time);
	spin_unlock_irq(&chip->reg_lock);
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(HZ / 20); /* 50 msec */
	msleep(50);
	spin_lock_irq(&chip->reg_lock);
	offset = __apu_get_register(chip, apu, 5);
	do_gettimeofday(&stop_time);
@@ -2093,7 +2087,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
	outw(0x0000, ioaddr + 0x60);	/* write 0 to gpio 0 */
	udelay(20);
	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio 1 */
	big_mdelay(20);
	msleep(20);

	outw(save_68 | 0x1, ioaddr + 0x68);	/* now restore .. */
	outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
@@ -2109,7 +2103,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio */
	udelay(20);
	outw(0x0009, ioaddr + 0x60);	/* write 9 to gpio */
	big_mdelay(500);
	msleep(500);
	//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
	outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
@@ -2135,7 +2129,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)

		if (w > 10000) {
			outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);	/* do a software reset */
			big_mdelay(500);	/* oh my.. */
			msleep(500);	/* oh my.. */
			outb(inb(ioaddr + 0x37) & ~0x08,
				ioaddr + 0x37);
			udelay(1);
Loading