Re: [PATCH] mfd: Improve WM831x AUXADC completion handling

Previous thread: unhelpful and somewhat scary r8169 boot message in 2.6.33.2 regarding a security fix by Nix on Friday, April 2, 2010 - 8:19 am. (3 messages)

Next thread: regulator: regulator_get behaviour without CONFIG_REGULATOR set by Jerome Oufella on Friday, April 2, 2010 - 8:47 am. (15 messages)
From: Mark Brown
Date: Friday, April 2, 2010 - 8:31 am

Currently completion of WM831x AUXADC conversions is monitored by
checking for convertor enable. Due to the mechanism used to ensure
data corruption is avoided when reading AUXADC data there may under
heavy I/O be a window where this bit has cleared but the conversion
results have not been updated. Data availability is only guaranteed
after the AUXADC data interrupt has been asserted.

Avoid this by always using the interrupt to detect completion. If the
chip IRQ is not set up then we poll the IRQ status register for up to
5ms. If it is set up then we rely on the data done interrupt with a
vastly increased timeout, failing the conversion if the interrupt is
not generated.

This also saves a register read when using interrupts.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-core.c |   65 +++++++++++++++++++++++++++++++++------------
 1 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index f2ab025..da00ca9 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -322,7 +322,11 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits);
  */
 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 {
-	int ret, src;
+	int ret, src, irq_masked, timeout;
+
+	/* Are we using the interrupt? */
+	irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK);
+	irq_masked &= WM831X_AUXADC_DATA_EINT;
 
 	mutex_lock(&wm831x->auxadc_lock);
 
@@ -342,6 +346,9 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 		goto out;
 	}
 
+	/* Clear any notification from a very late arriving interrupt */
+	try_wait_for_completion(&wm831x->auxadc_done);
+
 	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
 			      WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
 	if (ret < 0) {
@@ -349,22 +356,46 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 		goto disable;
 	}
 
-	/* If an interrupt arrived late clean up ...
From: Samuel Ortiz
Date: Friday, April 2, 2010 - 9:27 am

Applied to my for-next branch, thanks.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/
--

Previous thread: unhelpful and somewhat scary r8169 boot message in 2.6.33.2 regarding a security fix by Nix on Friday, April 2, 2010 - 8:19 am. (3 messages)

Next thread: regulator: regulator_get behaviour without CONFIG_REGULATOR set by Jerome Oufella on Friday, April 2, 2010 - 8:47 am. (15 messages)