ASoC: Handle spurious wm_hubs DC servo done interrupts
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 15 Jul 2011 08:33:26 +0000 (17:33 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 15 Jul 2011 14:48:05 +0000 (23:48 +0900)
Don't assume the first fire indicates that we're done.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/codecs/wm_hubs.c

index 5c2d565..4cc2d56 100644 (file)
@@ -66,8 +66,8 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
        struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
        unsigned int reg;
        int count = 0;
+       int timeout;
        unsigned int val;
-       unsigned long timeout;
 
        val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
 
@@ -76,21 +76,23 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 
        dev_dbg(codec->dev, "Waiting for DC servo...\n");
 
-       if (hubs->dcs_done_irq) {
-               timeout = wait_for_completion_timeout(&hubs->dcs_done,
-                                                     msecs_to_jiffies(500));
-               if (timeout == 0)
-                       dev_warn(codec->dev, "No DC servo interrupt\n");
+       if (hubs->dcs_done_irq)
+               timeout = 4;
+       else
+               timeout = 400;
 
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
-       } else {
-               do {
-                       count++;
+       do {
+               count++;
+
+               if (hubs->dcs_done_irq)
+                       wait_for_completion_timeout(&hubs->dcs_done,
+                                                   msecs_to_jiffies(250));
+               else
                        msleep(1);
-                       reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
-                       dev_dbg(codec->dev, "DC servo: %x\n", reg);
-               } while (reg & op && count < 400);
-       }
+
+               reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
+               dev_dbg(codec->dev, "DC servo: %x\n", reg);
+       } while (reg & op && count < timeout);
 
        if (reg & op)
                dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",