At Tue, 11 Sep 2007 01:08:07 +0200, I wrote:
At Tue, 11 Sep 2007 00:43:42 +0200, Rene Herman wrote:
Second -- not schedule_timeout_interruptible? A plain schedule_timeout won't work, as you first need to __set_current_state or it will not schedule. That is, schedule_timeout_interruptible or _uniterruptible and with the latter, the loop wouldn't make much sense anymore as it's just going to sleep for the full 250 ms directly.
Ah, right. I'm obviously too sleepy to review now...
Actually, the code with msleep() was basically OK. If more finer check is needed, it can simply use msleep(1). The point is to use timer_after_eq() instead of loop count for the precise timeouts.
Could you check whether the below patch works?
Takashi
diff -r 475132691bb1 isa/cs423x/cs4231_lib.c --- a/isa/cs423x/cs4231_lib.c Tue Sep 11 00:55:46 2007 +0200 +++ b/isa/cs423x/cs4231_lib.c Tue Sep 11 01:15:17 2007 +0200 @@ -313,6 +313,7 @@ void snd_cs4231_mce_down(struct snd_cs42 void snd_cs4231_mce_down(struct snd_cs4231 *chip) { unsigned long flags; + unsigned long end_time; int timeout;
snd_cs4231_busy_wait(chip); @@ -344,28 +345,28 @@ void snd_cs4231_mce_down(struct snd_cs42 snd_printdd("(1) jiffies = %lu\n", jiffies);
/* check condition up to 250 ms */ - timeout = msecs_to_jiffies(250); + end_time = jiffies + msecs_to_jiffies(250); while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
- if (timeout <= 0) { + if (time_after(jiffies, end_time)) { snd_printk(KERN_ERR "mce_down - " "auto calibration time out (2)\n"); return; } - timeout = schedule_timeout(timeout); + msleep(1); }
snd_printdd("(2) jiffies = %lu\n", jiffies);
/* check condition up to 100 ms */ - timeout = msecs_to_jiffies(100); + end_time = jiffies + msecs_to_jiffies(100); while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { - if (timeout <= 0) { + if (time_after(jiffies, end_time)) { snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; } - timeout = schedule_timeout(timeout); + msleep(1); }
snd_printdd("(3) jiffies = %lu\n", jiffies); diff -r 475132691bb1 sparc/cs4231.c --- a/sparc/cs4231.c Tue Sep 11 00:55:46 2007 +0200 +++ b/sparc/cs4231.c Tue Sep 11 01:15:17 2007 +0200 @@ -401,6 +401,7 @@ static void snd_cs4231_mce_down(struct s static void snd_cs4231_mce_down(struct snd_cs4231 *chip) { unsigned long flags; + unsigned long end_time; int timeout;
spin_lock_irqsave(&chip->lock, flags); @@ -431,30 +432,30 @@ static void snd_cs4231_mce_down(struct s msleep(1);
/* check condition up to 250ms */ - timeout = msecs_to_jiffies(250); + end_time = jiffies + msecs_to_jiffies(250); while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
spin_unlock_irqrestore(&chip->lock, flags); - if (timeout <= 0) { + if (time_after(jiffies, end_time)) { snd_printk("mce_down - " "auto calibration time out (2)\n"); return; } - timeout = schedule_timeout(timeout); + msleep(1); spin_lock_irqsave(&chip->lock, flags); }
/* check condition up to 100ms */ - timeout = msecs_to_jiffies(100); + end_time = jiffies + msecs_to_jiffies(100); while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) { spin_unlock_irqrestore(&chip->lock, flags); - if (timeout <= 0) { + if (time_after(jiffies, end_time)) { snd_printk("mce_down - " "auto calibration time out (3)\n"); return; } - timeout = schedule_timeout(timeout); + msleep(1); spin_lock_irqsave(&chip->lock, flags); } spin_unlock_irqrestore(&chip->lock, flags);