diff options
-rw-r--r-- | drivers/mfd/wm831x-irq.c | 24 | ||||
-rw-r--r-- | include/linux/mfd/wm831x/core.h | 4 |
2 files changed, 22 insertions, 6 deletions
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 42b928ec891e..b23d8d5ee96c 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -348,6 +348,15 @@ static void wm831x_irq_sync_unlock(struct irq_data *data) | |||
348 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); | 348 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
349 | int i; | 349 | int i; |
350 | 350 | ||
351 | for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) { | ||
352 | if (wm831x->gpio_update[i]) { | ||
353 | wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i, | ||
354 | WM831X_GPN_INT_MODE | WM831X_GPN_POL, | ||
355 | wm831x->gpio_update[i]); | ||
356 | wm831x->gpio_update[i] = 0; | ||
357 | } | ||
358 | } | ||
359 | |||
351 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { | 360 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { |
352 | /* If there's been a change in the mask write it back | 361 | /* If there's been a change in the mask write it back |
353 | * to the hardware. */ | 362 | * to the hardware. */ |
@@ -387,7 +396,7 @@ static void wm831x_irq_disable(struct irq_data *data) | |||
387 | static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | 396 | static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) |
388 | { | 397 | { |
389 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); | 398 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
390 | int val, irq; | 399 | int irq; |
391 | 400 | ||
392 | irq = data->irq - wm831x->irq_base; | 401 | irq = data->irq - wm831x->irq_base; |
393 | 402 | ||
@@ -399,22 +408,25 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | |||
399 | return -EINVAL; | 408 | return -EINVAL; |
400 | } | 409 | } |
401 | 410 | ||
411 | /* We set the high bit to flag that we need an update; don't | ||
412 | * do the update here as we can be called with the bus lock | ||
413 | * held. | ||
414 | */ | ||
402 | switch (type) { | 415 | switch (type) { |
403 | case IRQ_TYPE_EDGE_BOTH: | 416 | case IRQ_TYPE_EDGE_BOTH: |
404 | val = WM831X_GPN_INT_MODE; | 417 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; |
405 | break; | 418 | break; |
406 | case IRQ_TYPE_EDGE_RISING: | 419 | case IRQ_TYPE_EDGE_RISING: |
407 | val = WM831X_GPN_POL; | 420 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
408 | break; | 421 | break; |
409 | case IRQ_TYPE_EDGE_FALLING: | 422 | case IRQ_TYPE_EDGE_FALLING: |
410 | val = 0; | 423 | wm831x->gpio_update[irq] = 0x10000; |
411 | break; | 424 | break; |
412 | default: | 425 | default: |
413 | return -EINVAL; | 426 | return -EINVAL; |
414 | } | 427 | } |
415 | 428 | ||
416 | return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq, | 429 | return 0; |
417 | WM831X_GPN_INT_MODE | WM831X_GPN_POL, val); | ||
418 | } | 430 | } |
419 | 431 | ||
420 | static struct irq_chip wm831x_irq_chip = { | 432 | static struct irq_chip wm831x_irq_chip = { |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 0d515ee1c247..ebead1c401aa 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
@@ -237,6 +237,7 @@ | |||
237 | struct regulator_dev; | 237 | struct regulator_dev; |
238 | 238 | ||
239 | #define WM831X_NUM_IRQ_REGS 5 | 239 | #define WM831X_NUM_IRQ_REGS 5 |
240 | #define WM831X_NUM_GPIO_REGS 16 | ||
240 | 241 | ||
241 | enum wm831x_parent { | 242 | enum wm831x_parent { |
242 | WM8310 = 0x8310, | 243 | WM8310 = 0x8310, |
@@ -272,6 +273,9 @@ struct wm831x { | |||
272 | 273 | ||
273 | int num_gpio; | 274 | int num_gpio; |
274 | 275 | ||
276 | /* Used by the interrupt controller code to post writes */ | ||
277 | int gpio_update[WM831X_NUM_GPIO_REGS]; | ||
278 | |||
275 | struct mutex auxadc_lock; | 279 | struct mutex auxadc_lock; |
276 | struct completion auxadc_done; | 280 | struct completion auxadc_done; |
277 | 281 | ||