*/
 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 {
-       int tries = 10;
        int ret, src;
 
        mutex_lock(&wm831x->auxadc_lock);
                goto disable;
        }
 
-       do {
-               msleep(1);
+       /* Ignore the result to allow us to soldier on without IRQ hookup */
+       wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
 
-               ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
-               if (ret < 0)
-                       ret = WM831X_AUX_CVT_ENA;
-       } while ((ret & WM831X_AUX_CVT_ENA) && --tries);
+       ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
+       if (ret < 0) {
+               dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret);
+               goto disable;
+       }
 
        if (ret & WM831X_AUX_CVT_ENA) {
                dev_err(wm831x->dev, "Timed out reading AUXADC\n");
 }
 EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
 
+static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
+{
+       struct wm831x *wm831x = irq_data;
+
+       complete(&wm831x->auxadc_done);
+
+       return IRQ_HANDLED;
+}
+
 /**
  * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
  *
        mutex_init(&wm831x->io_lock);
        mutex_init(&wm831x->key_lock);
        mutex_init(&wm831x->auxadc_lock);
+       init_completion(&wm831x->auxadc_done);
        dev_set_drvdata(wm831x->dev, wm831x);
 
        ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
        if (ret != 0)
                goto err;
 
+       if (wm831x->irq_base) {
+               ret = request_threaded_irq(wm831x->irq_base +
+                                          WM831X_IRQ_AUXADC_DATA,
+                                          NULL, wm831x_auxadc_irq, 0,
+                                          "auxadc", wm831x);
+               if (ret < 0)
+                       dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
+                               ret);
+       }
+
        /* The core device is up, instantiate the subdevices. */
        switch (parent) {
        case WM8310:
 {
        wm831x_otp_exit(wm831x);
        mfd_remove_devices(wm831x->dev);
+       if (wm831x->irq_base)
+               free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
        wm831x_irq_exit(wm831x);
        kfree(wm831x);
 }
 
 #ifndef __MFD_WM831X_CORE_H__
 #define __MFD_WM831X_CORE_H__
 
+#include <linux/completion.h>
 #include <linux/interrupt.h>
 
 /*
        int num_gpio;
 
        struct mutex auxadc_lock;
+       struct completion auxadc_done;
 
        /* The WM831x has a security key blocking access to certain
         * registers.  The mutex is taken by the accessors for locking