]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/es1968.c
es1968: fix sleep-while-holding-lock bug
[linux-2.6-omap-h63xx.git] / sound / pci / es1968.c
index 2faf009076bb81c94aedeee60087adedf0aa7304..7d911a18c082ffbbbfab7293693ec070ca5db224 100644 (file)
@@ -94,7 +94,6 @@
  *     places.
  */
 
-#include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -618,6 +617,18 @@ static int snd_es1968_ac97_wait(struct es1968 *chip)
        return 1; /* timeout */
 }
 
+static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
+{
+       int timeout = 100000;
+
+       while (timeout-- > 0) {
+               if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
+                       return 0;
+       }
+       snd_printd("es1968: ac97 timeout\n");
+       return 1; /* timeout */
+}
+
 static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
        struct es1968 *chip = ac97->private_data;
@@ -646,7 +657,7 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
        outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
        /*msleep(1);*/
 
-       if (! snd_es1968_ac97_wait(chip)) {
+       if (!snd_es1968_ac97_wait_poll(chip)) {
                data = inw(chip->io_port + ESM_AC97_DATA);
                /*msleep(1);*/
        }
@@ -843,10 +854,9 @@ static void snd_es1968_bob_dec(struct es1968 *chip)
                snd_es1968_bob_stop(chip);
        else if (chip->bob_freq > ESM_BOB_FREQ) {
                /* check reduction of timer frequency */
-               struct list_head *p;
                int max_freq = ESM_BOB_FREQ;
-               list_for_each(p, &chip->substream_list) {
-                       struct esschan *es = list_entry(p, struct esschan, list);
+               struct esschan *es;
+               list_for_each_entry(es, &chip->substream_list, list) {
                        if (max_freq < es->bob_freq)
                                max_freq = es->bob_freq;
                }
@@ -1316,12 +1326,11 @@ static struct snd_pcm_hardware snd_es1968_capture = {
 
 static int calc_available_memory_size(struct es1968 *chip)
 {
-       struct list_head *p;
        int max_size = 0;
-       
+       struct esm_memory *buf;
+
        mutex_lock(&chip->memory_mutex);
-       list_for_each(p, &chip->buf_list) {
-               struct esm_memory *buf = list_entry(p, struct esm_memory, list);
+       list_for_each_entry(buf, &chip->buf_list, list) {
                if (buf->empty && buf->buf.bytes > max_size)
                        max_size = buf->buf.bytes;
        }
@@ -1335,12 +1344,10 @@ static int calc_available_memory_size(struct es1968 *chip)
 static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
 {
        struct esm_memory *buf;
-       struct list_head *p;
-       
+
        size = ALIGN(size, ESM_MEM_ALIGN);
        mutex_lock(&chip->memory_mutex);
-       list_for_each(p, &chip->buf_list) {
-               buf = list_entry(p, struct esm_memory, list);
+       list_for_each_entry(buf, &chip->buf_list, list) {
                if (buf->empty && buf->buf.bytes >= size)
                        goto __found;
        }
@@ -1938,10 +1945,9 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
        }
 
        if (event & ESM_SOUND_IRQ) {
-               struct list_head *p;
+               struct esschan *es;
                spin_lock(&chip->substream_lock);
-               list_for_each(p, &chip->substream_list) {
-                       struct esschan *es = list_entry(p, struct esschan, list);
+               list_for_each_entry(es, &chip->substream_list, list) {
                        if (es->running)
                                snd_es1968_update_pcm(chip, es);
                }
@@ -2345,7 +2351,7 @@ static int es1968_resume(struct pci_dev *pci)
 {
        struct snd_card *card = pci_get_drvdata(pci);
        struct es1968 *chip = card->private_data;
-       struct list_head *p;
+       struct esschan *es;
 
        if (! chip->do_pm)
                return 0;
@@ -2374,8 +2380,7 @@ static int es1968_resume(struct pci_dev *pci)
        /* restore ac97 state */
        snd_ac97_resume(chip->ac97);
 
-       list_for_each(p, &chip->substream_list) {
-               struct esschan *es = list_entry(p, struct esschan, list);
+       list_for_each_entry(es, &chip->substream_list, list) {
                switch (es->mode) {
                case ESM_MODE_PLAY:
                        snd_es1968_playback_setup(chip, es, es->substream->runtime);