aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/wm831x-irq.c24
-rw-r--r--include/linux/mfd/wm831x/core.h4
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)
387static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) 396static 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
420static struct irq_chip wm831x_irq_chip = { 432static 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 @@
237struct regulator_dev; 237struct 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
241enum wm831x_parent { 242enum 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