Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 199387
b: refs/heads/master
c: 7cc1392
h: refs/heads/master
i:
  199385: 5b62965
  199383: f7fc146
v: v3
  • Loading branch information
Mark Brown authored and Samuel Ortiz committed May 27, 2010
1 parent 7bc33f7 commit 764848a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 800e69fbd2faea906cabd10ddb77e36410f2bd9c
refs/heads/master: 7cc1392aabc31d2af9bd3cc5febbd91977452181
65 changes: 48 additions & 17 deletions trunk/drivers/mfd/wm831x-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -342,29 +346,56 @@ 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) {
dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
goto disable;
}

/* If an interrupt arrived late clean up after it */
try_wait_for_completion(&wm831x->auxadc_done);

/* 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) {
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");
ret = -EBUSY;
goto disable;
if (irq_masked) {
/* If we're not using interrupts then poll the
* interrupt status register */
timeout = 5;
while (timeout) {
msleep(1);

ret = wm831x_reg_read(wm831x,
WM831X_INTERRUPT_STATUS_1);
if (ret < 0) {
dev_err(wm831x->dev,
"ISR 1 read failed: %d\n", ret);
goto disable;
}

/* Did it complete? */
if (ret & WM831X_AUXADC_DATA_EINT) {
wm831x_reg_write(wm831x,
WM831X_INTERRUPT_STATUS_1,
WM831X_AUXADC_DATA_EINT);
break;
} else {
dev_err(wm831x->dev,
"AUXADC conversion timeout\n");
ret = -EBUSY;
goto disable;
}
}
} else {
/* If we are using interrupts then wait for the
* interrupt to complete. Use an extremely long
* timeout to handle situations with heavy load where
* the notification of the interrupt may be delayed by
* threaded IRQ handling. */
if (!wait_for_completion_timeout(&wm831x->auxadc_done,
msecs_to_jiffies(500))) {
dev_err(wm831x->dev, "Timed out waiting for AUXADC\n");
ret = -EBUSY;
goto disable;
}
}

ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
Expand Down

0 comments on commit 764848a

Please sign in to comment.