Messages in this thread Patch in this message | | | Date | Mon, 1 Mar 2010 00:05:00 +0100 | From | Samuel Ortiz <> | Subject | Re: [PATCH 2/2] mfd: Use completion interrupt for WM831x AUXADC |
| |
On Tue, Feb 23, 2010 at 11:08:06AM +0000, Mark Brown wrote: > Use the completion interrupt generated by the device rather than > polling for conversions to complete. As a backup we still check > the status of the AUXADC if we don't get a completion, mostly for > systems that don't have the WM831x interrupt infrastructure hooked > up. Patch applied to my for-next branch, thanks a lot.
Cheers, Samuel.
> Also reduce the timeout for completion of conversions to 5ms from > the previous 10ms, the lower timeout should be sufficient. > > Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> > --- > drivers/mfd/wm831x-core.c | 36 +++++++++++++++++++++++++++++------- > include/linux/mfd/wm831x/core.h | 2 ++ > 2 files changed, 31 insertions(+), 7 deletions(-) > > diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c > index c428d9f..07101e9 100644 > --- a/drivers/mfd/wm831x-core.c > +++ b/drivers/mfd/wm831x-core.c > @@ -321,7 +321,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits); > */ > int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) > { > - int tries = 10; > int ret, src; > > mutex_lock(&wm831x->auxadc_lock); > @@ -349,13 +348,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) > 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"); > @@ -390,6 +390,15 @@ out: > } > 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 > * > @@ -1411,6 +1420,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) > 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); > @@ -1523,6 +1533,16 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) > 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: > @@ -1593,6 +1613,8 @@ static void wm831x_device_exit(struct wm831x *wm831x) > { > 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); > } > diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h > index 53580b5..5915f6e 100644 > --- a/include/linux/mfd/wm831x/core.h > +++ b/include/linux/mfd/wm831x/core.h > @@ -15,6 +15,7 @@ > #ifndef __MFD_WM831X_CORE_H__ > #define __MFD_WM831X_CORE_H__ > > +#include <linux/completion.h> > #include <linux/interrupt.h> > > /* > @@ -261,6 +262,7 @@ struct wm831x { > 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 > -- > 1.7.0 >
-- Intel Open Source Technology Centre http://oss.intel.com/
| |