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 |
