diff options
-rw-r--r-- | drivers/mfd/wm831x-core.c | 36 | ||||
-rw-r--r-- | 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 c428d9f918fc..07101e9e1cba 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -321,7 +321,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits); | |||
321 | */ | 321 | */ |
322 | int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) | 322 | int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) |
323 | { | 323 | { |
324 | int tries = 10; | ||
325 | int ret, src; | 324 | int ret, src; |
326 | 325 | ||
327 | mutex_lock(&wm831x->auxadc_lock); | 326 | mutex_lock(&wm831x->auxadc_lock); |
@@ -349,13 +348,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) | |||
349 | goto disable; | 348 | goto disable; |
350 | } | 349 | } |
351 | 350 | ||
352 | do { | 351 | /* Ignore the result to allow us to soldier on without IRQ hookup */ |
353 | msleep(1); | 352 | wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5)); |
354 | 353 | ||
355 | ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); | 354 | ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); |
356 | if (ret < 0) | 355 | if (ret < 0) { |
357 | ret = WM831X_AUX_CVT_ENA; | 356 | dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret); |
358 | } while ((ret & WM831X_AUX_CVT_ENA) && --tries); | 357 | goto disable; |
358 | } | ||
359 | 359 | ||
360 | if (ret & WM831X_AUX_CVT_ENA) { | 360 | if (ret & WM831X_AUX_CVT_ENA) { |
361 | dev_err(wm831x->dev, "Timed out reading AUXADC\n"); | 361 | dev_err(wm831x->dev, "Timed out reading AUXADC\n"); |
@@ -390,6 +390,15 @@ out: | |||
390 | } | 390 | } |
391 | EXPORT_SYMBOL_GPL(wm831x_auxadc_read); | 391 | EXPORT_SYMBOL_GPL(wm831x_auxadc_read); |
392 | 392 | ||
393 | static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) | ||
394 | { | ||
395 | struct wm831x *wm831x = irq_data; | ||
396 | |||
397 | complete(&wm831x->auxadc_done); | ||
398 | |||
399 | return IRQ_HANDLED; | ||
400 | } | ||
401 | |||
393 | /** | 402 | /** |
394 | * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC | 403 | * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC |
395 | * | 404 | * |
@@ -1411,6 +1420,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1411 | mutex_init(&wm831x->io_lock); | 1420 | mutex_init(&wm831x->io_lock); |
1412 | mutex_init(&wm831x->key_lock); | 1421 | mutex_init(&wm831x->key_lock); |
1413 | mutex_init(&wm831x->auxadc_lock); | 1422 | mutex_init(&wm831x->auxadc_lock); |
1423 | init_completion(&wm831x->auxadc_done); | ||
1414 | dev_set_drvdata(wm831x->dev, wm831x); | 1424 | dev_set_drvdata(wm831x->dev, wm831x); |
1415 | 1425 | ||
1416 | ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); | 1426 | 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) | |||
1523 | if (ret != 0) | 1533 | if (ret != 0) |
1524 | goto err; | 1534 | goto err; |
1525 | 1535 | ||
1536 | if (wm831x->irq_base) { | ||
1537 | ret = request_threaded_irq(wm831x->irq_base + | ||
1538 | WM831X_IRQ_AUXADC_DATA, | ||
1539 | NULL, wm831x_auxadc_irq, 0, | ||
1540 | "auxadc", wm831x); | ||
1541 | if (ret < 0) | ||
1542 | dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", | ||
1543 | ret); | ||
1544 | } | ||
1545 | |||
1526 | /* The core device is up, instantiate the subdevices. */ | 1546 | /* The core device is up, instantiate the subdevices. */ |
1527 | switch (parent) { | 1547 | switch (parent) { |
1528 | case WM8310: | 1548 | case WM8310: |
@@ -1593,6 +1613,8 @@ static void wm831x_device_exit(struct wm831x *wm831x) | |||
1593 | { | 1613 | { |
1594 | wm831x_otp_exit(wm831x); | 1614 | wm831x_otp_exit(wm831x); |
1595 | mfd_remove_devices(wm831x->dev); | 1615 | mfd_remove_devices(wm831x->dev); |
1616 | if (wm831x->irq_base) | ||
1617 | free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); | ||
1596 | wm831x_irq_exit(wm831x); | 1618 | wm831x_irq_exit(wm831x); |
1597 | kfree(wm831x); | 1619 | kfree(wm831x); |
1598 | } | 1620 | } |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 53580b592bc9..5915f6e3d9ab 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #ifndef __MFD_WM831X_CORE_H__ | 15 | #ifndef __MFD_WM831X_CORE_H__ |
16 | #define __MFD_WM831X_CORE_H__ | 16 | #define __MFD_WM831X_CORE_H__ |
17 | 17 | ||
18 | #include <linux/completion.h> | ||
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | 20 | ||
20 | /* | 21 | /* |
@@ -261,6 +262,7 @@ struct wm831x { | |||
261 | int num_gpio; | 262 | int num_gpio; |
262 | 263 | ||
263 | struct mutex auxadc_lock; | 264 | struct mutex auxadc_lock; |
265 | struct completion auxadc_done; | ||
264 | 266 | ||
265 | /* The WM831x has a security key blocking access to certain | 267 | /* The WM831x has a security key blocking access to certain |
266 | * registers. The mutex is taken by the accessors for locking | 268 | * registers. The mutex is taken by the accessors for locking |