提交 ef21ca24 编写于 作者: N Nishanth Aravamudan 提交者: Jaroslav Kysela

[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: NNishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: NJaroslav Kysela <perex@suse.cz>
上级 072c0119
...@@ -2227,6 +2227,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97) ...@@ -2227,6 +2227,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97)
void snd_ac97_resume(ac97_t *ac97) void snd_ac97_resume(ac97_t *ac97)
{ {
int i; int i;
unsigned long end_time;
if (ac97->bus->ops->reset) { if (ac97->bus->ops->reset) {
ac97->bus->ops->reset(ac97); ac97->bus->ops->reset(ac97);
...@@ -2244,26 +2245,26 @@ void snd_ac97_resume(ac97_t *ac97) ...@@ -2244,26 +2245,26 @@ void snd_ac97_resume(ac97_t *ac97)
snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
if (ac97_is_audio(ac97)) { if (ac97_is_audio(ac97)) {
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); 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) if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} } while (time_after_eq(end_time, jiffies));
/* FIXME: extra delay */ /* FIXME: extra delay */
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) { if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000)
set_current_state(TASK_UNINTERRUPTIBLE); msleep(250);
schedule_timeout(HZ/4);
}
} else { } 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); unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
if (val != 0xffff && (val & 1) != 0) if (val != 0xffff && (val & 1) != 0)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} } while (time_after_eq(end_time, jiffies));
} }
__reset_ready: __reset_ready:
......
...@@ -399,7 +399,7 @@ static int snd_ali_codec_ready( ali_t *codec, ...@@ -399,7 +399,7 @@ static int snd_ali_codec_ready( ali_t *codec,
unsigned long end_time; unsigned long end_time;
unsigned int res; unsigned int res;
end_time = jiffies + 10 * (HZ >> 2); end_time = jiffies + 10 * msecs_to_jiffies(250);
do { do {
res = snd_ali_5451_peek(codec,port); res = snd_ali_5451_peek(codec,port);
if (! (res & 0x8000)) if (! (res & 0x8000))
...@@ -422,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched) ...@@ -422,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched)
dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
dwChk2 = 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 { do {
dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
if (dwChk2 != dwChk1) if (dwChk2 != dwChk1)
......
...@@ -2400,8 +2400,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97) ...@@ -2400,8 +2400,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97)
if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
return; return;
set_current_state(TASK_UNINTERRUPTIBLE); msleep(10);
schedule_timeout(HZ/100);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
snd_printk("CS46xx secondary codec dont respond!\n"); snd_printk("CS46xx secondary codec dont respond!\n");
...@@ -2435,8 +2434,7 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) ...@@ -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]); err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
return err; return err;
} }
set_current_state(TASK_INTERRUPTIBLE); msleep(10);
schedule_timeout(HZ/100);
} }
snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
return -ENXIO; return -ENXIO;
...@@ -3018,8 +3016,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) ...@@ -3018,8 +3016,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
/* /*
* Wait until the PLL has stabilized. * Wait until the PLL has stabilized.
*/ */
set_current_state(TASK_UNINTERRUPTIBLE); msleep(100);
schedule_timeout(HZ/10); /* 100ms */
/* /*
* Turn on clocking of the core so that we can setup the serial ports. * 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) ...@@ -3072,8 +3069,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
*/ */
if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
goto ok1; goto ok1;
set_current_state(TASK_UNINTERRUPTIBLE); msleep(10);
schedule_timeout((HZ+99)/100);
} }
...@@ -3122,8 +3118,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) ...@@ -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)) if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
goto ok2; goto ok2;
set_current_state(TASK_UNINTERRUPTIBLE); msleep(10);
schedule_timeout((HZ+99)/100);
} }
#ifndef CONFIG_SND_CS46XX_NEW_DSP #ifndef CONFIG_SND_CS46XX_NEW_DSP
......
...@@ -2018,21 +2018,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, ...@@ -2018,21 +2018,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
if (pci->vendor == es1371_ac97_reset_hack[idx].vid && if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
pci->device == es1371_ac97_reset_hack[idx].did && pci->device == es1371_ac97_reset_hack[idx].did &&
ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
unsigned long tmo;
signed long tmo2;
ensoniq->cssr |= ES_1371_ST_AC97_RST; ensoniq->cssr |= ES_1371_ST_AC97_RST;
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
/* need to delay around 20ms(bleech) to give /* need to delay around 20ms(bleech) to give
some CODECs enough time to wakeup */ some CODECs enough time to wakeup */
tmo = jiffies + (HZ / 50) + 1; msleep(20);
while (1) {
tmo2 = tmo - jiffies;
if (tmo2 <= 0)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(tmo2);
}
break; break;
} }
/* AC'97 warm reset to start the bitclk */ /* AC'97 warm reset to start the bitclk */
......
...@@ -664,11 +664,6 @@ static inline u16 maestro_read(es1968_t *chip, u16 reg) ...@@ -664,11 +664,6 @@ static inline u16 maestro_read(es1968_t *chip, u16 reg)
return result; 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 */ /* Wait for the codec bus to be free */
static int snd_es1968_ac97_wait(es1968_t *chip) static int snd_es1968_ac97_wait(es1968_t *chip)
{ {
...@@ -1809,8 +1804,7 @@ static void __devinit es1968_measure_clock(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); snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
do_gettimeofday(&start_time); do_gettimeofday(&start_time);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(50);
schedule_timeout(HZ / 20); /* 50 msec */
spin_lock_irq(&chip->reg_lock); spin_lock_irq(&chip->reg_lock);
offset = __apu_get_register(chip, apu, 5); offset = __apu_get_register(chip, apu, 5);
do_gettimeofday(&stop_time); do_gettimeofday(&stop_time);
...@@ -2093,7 +2087,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) ...@@ -2093,7 +2087,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */
udelay(20); udelay(20);
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */
big_mdelay(20); msleep(20);
outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */
outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
...@@ -2109,7 +2103,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) ...@@ -2109,7 +2103,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */
udelay(20); udelay(20);
outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */
big_mdelay(500); msleep(500);
//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
...@@ -2135,7 +2129,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) ...@@ -2135,7 +2129,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
if (w > 10000) { if (w > 10000) {
outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ 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, outb(inb(ioaddr + 0x37) & ~0x08,
ioaddr + 0x37); ioaddr + 0x37);
udelay(1); udelay(1);
......
...@@ -2464,8 +2464,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) ...@@ -2464,8 +2464,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
} }
do_gettimeofday(&start_time); do_gettimeofday(&start_time);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
set_current_state(TASK_UNINTERRUPTIBLE); msleep(50);
schedule_timeout(HZ / 20);
spin_lock_irq(&chip->reg_lock); spin_lock_irq(&chip->reg_lock);
/* check the position */ /* check the position */
pos = ichdev->fragsize1; pos = ichdev->fragsize1;
......
...@@ -445,9 +445,9 @@ static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd) ...@@ -445,9 +445,9 @@ static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd)
static int mixart_sync_nonblock_events(mixart_mgr_t *mgr) static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
{ {
int timeout = HZ; unsigned long timeout = jiffies + HZ;
while (atomic_read(&mgr->msg_processed) > 0) { while (atomic_read(&mgr->msg_processed) > 0) {
if (! timeout--) { if (time_after(jiffies, timeout)) {
snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n"); snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
return -EBUSY; return -EBUSY;
} }
......
...@@ -679,8 +679,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) { ...@@ -679,8 +679,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
} }
if ((1000 / HZ) < 3000) { if ((1000 / HZ) < 3000) {
set_current_state(TASK_UNINTERRUPTIBLE); ssleep(3);
schedule_timeout((3000 * HZ + 999) / 1000);
} else { } else {
mdelay(3000); mdelay(3000);
} }
...@@ -5080,8 +5079,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, ...@@ -5080,8 +5079,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
if (!is_9652 && !is_9632) { if (!is_9652 && !is_9632) {
/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
if ((1000 / HZ) < 2000) { if ((1000 / HZ) < 2000) {
set_current_state(TASK_UNINTERRUPTIBLE); ssleep(2);
schedule_timeout((2000 * HZ + 999) / 1000);
} else { } else {
mdelay(2000); mdelay(2000);
} }
......
...@@ -3153,8 +3153,7 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) ...@@ -3153,8 +3153,7 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode)
switch (mode) { switch (mode) {
case GAMEPORT_MODE_COOKED: case GAMEPORT_MODE_COOKED:
outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
set_current_state(TASK_UNINTERRUPTIBLE); msleep(20);
schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */
return 0; return 0;
case GAMEPORT_MODE_RAW: case GAMEPORT_MODE_RAW:
outb(0, TRID_REG(chip, GAMEPORT_GCR)); outb(0, TRID_REG(chip, GAMEPORT_GCR));
......
...@@ -547,8 +547,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) ...@@ -547,8 +547,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97)
int err; int err;
err = snd_via82xx_codec_ready(chip, ac97->num); err = snd_via82xx_codec_ready(chip, ac97->num);
/* here we need to wait fairly for long time.. */ /* here we need to wait fairly for long time.. */
set_current_state(TASK_UNINTERRUPTIBLE); msleep(500);
schedule_timeout(HZ/2);
} }
static void snd_via82xx_codec_write(ac97_t *ac97, static void snd_via82xx_codec_write(ac97_t *ac97,
...@@ -1847,7 +1846,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) ...@@ -1847,7 +1846,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
static int snd_via82xx_chip_init(via82xx_t *chip) static int snd_via82xx_chip_init(via82xx_t *chip)
{ {
unsigned int val; unsigned int val;
int max_count; unsigned long end_time;
unsigned char pval; unsigned char pval;
#if 0 /* broken on K7M? */ #if 0 /* broken on K7M? */
...@@ -1889,14 +1888,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -1889,14 +1888,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
} }
/* wait until codec ready */ /* wait until codec ready */
max_count = ((3 * HZ) / 4) + 1; end_time = jiffies + msecs_to_jiffies(750);
do { do {
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} while (--max_count > 0); } while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
snd_printk("AC'97 codec is not ready [0x%x]\n", val); snd_printk("AC'97 codec is not ready [0x%x]\n", val);
...@@ -1905,7 +1904,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -1905,7 +1904,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID | VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
max_count = ((3 * HZ) / 4) + 1; end_time = jiffies + msecs_to_jiffies(750);
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID | VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
...@@ -1916,7 +1915,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -1916,7 +1915,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
} }
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} while (--max_count > 0); } while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */ /* This is ok, the most of motherboards have only one codec */
__ac97_ok2: __ac97_ok2:
......
...@@ -408,8 +408,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) ...@@ -408,8 +408,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97)
int err; int err;
err = snd_via82xx_codec_ready(chip, ac97->num); err = snd_via82xx_codec_ready(chip, ac97->num);
/* here we need to wait fairly for long time.. */ /* here we need to wait fairly for long time.. */
set_current_state(TASK_UNINTERRUPTIBLE); msleep(500);
schedule_timeout(HZ/2);
} }
static void snd_via82xx_codec_write(ac97_t *ac97, static void snd_via82xx_codec_write(ac97_t *ac97,
...@@ -923,7 +922,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) ...@@ -923,7 +922,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
static int snd_via82xx_chip_init(via82xx_t *chip) static int snd_via82xx_chip_init(via82xx_t *chip)
{ {
unsigned int val; unsigned int val;
int max_count; unsigned long end_time;
unsigned char pval; unsigned char pval;
pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval); pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
...@@ -962,14 +961,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -962,14 +961,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
} }
/* wait until codec ready */ /* wait until codec ready */
max_count = ((3 * HZ) / 4) + 1; end_time = jiffies + msecs_to_jiffies(750);
do { do {
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} while (--max_count > 0); } while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
snd_printk("AC'97 codec is not ready [0x%x]\n", val); snd_printk("AC'97 codec is not ready [0x%x]\n", val);
...@@ -977,7 +976,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -977,7 +976,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID | VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
max_count = ((3 * HZ) / 4) + 1; end_time = jiffies + msecs_to_jiffies(750);
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID | VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
...@@ -988,7 +987,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) ...@@ -988,7 +987,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
} }
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} while (--max_count > 0); } while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */ /* This is ok, the most of motherboards have only one codec */
__ac97_ok2: __ac97_ok2:
......
...@@ -84,16 +84,16 @@ static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val) ...@@ -84,16 +84,16 @@ static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val)
static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary) static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
{ {
signed long end_time; unsigned long end_time;
u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
end_time = (jiffies + ((3 * HZ) / 4)) + 1; end_time = jiffies + msecs_to_jiffies(750);
do { do {
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
return 0; return 0;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} while (end_time - (signed long)jiffies >= 0); } while (time_before(jiffies, end_time));
snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
return -EBUSY; return -EBUSY;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册