diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-02-13 18:24:41 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-02-13 18:24:51 -0500 |
commit | 6ed8b0400c74adfcbc24ea9e59878c273ef51333 (patch) | |
tree | 8b49decbe4ef215cc39efa65510788d9b9a8601a /drivers/mfd/ab8500-core.c | |
parent | c3481955f6c78c8dd99921759306d7469c999ec2 (diff) | |
parent | e64d905e28031031c52db403826cd3bfe060b181 (diff) |
Merge branch 'abx500-pinctrl-for-mfd' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl into for-next
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/ab8500-core.c')
-rw-r--r-- | drivers/mfd/ab8500-core.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 104514228b74..5b1c29685a7c 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -369,16 +369,48 @@ static void ab8500_irq_mask(struct irq_data *data) | |||
369 | int mask = 1 << (offset % 8); | 369 | int mask = 1 << (offset % 8); |
370 | 370 | ||
371 | ab8500->mask[index] |= mask; | 371 | ab8500->mask[index] |= mask; |
372 | |||
373 | /* The AB8500 GPIOs have two interrupts each (rising & falling). */ | ||
374 | if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) | ||
375 | ab8500->mask[index + 2] |= mask; | ||
376 | if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) | ||
377 | ab8500->mask[index + 1] |= mask; | ||
378 | if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) | ||
379 | /* Here the falling IRQ is one bit lower */ | ||
380 | ab8500->mask[index] |= (mask << 1); | ||
372 | } | 381 | } |
373 | 382 | ||
374 | static void ab8500_irq_unmask(struct irq_data *data) | 383 | static void ab8500_irq_unmask(struct irq_data *data) |
375 | { | 384 | { |
376 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); | 385 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
386 | unsigned int type = irqd_get_trigger_type(data); | ||
377 | int offset = data->hwirq; | 387 | int offset = data->hwirq; |
378 | int index = offset / 8; | 388 | int index = offset / 8; |
379 | int mask = 1 << (offset % 8); | 389 | int mask = 1 << (offset % 8); |
380 | 390 | ||
381 | ab8500->mask[index] &= ~mask; | 391 | if (type & IRQ_TYPE_EDGE_RISING) |
392 | ab8500->mask[index] &= ~mask; | ||
393 | |||
394 | /* The AB8500 GPIOs have two interrupts each (rising & falling). */ | ||
395 | if (type & IRQ_TYPE_EDGE_FALLING) { | ||
396 | if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) | ||
397 | ab8500->mask[index + 2] &= ~mask; | ||
398 | else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) | ||
399 | ab8500->mask[index + 1] &= ~mask; | ||
400 | else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) | ||
401 | /* Here the falling IRQ is one bit lower */ | ||
402 | ab8500->mask[index] &= ~(mask << 1); | ||
403 | else | ||
404 | ab8500->mask[index] &= ~mask; | ||
405 | } else { | ||
406 | /* Satisfies the case where type is not set. */ | ||
407 | ab8500->mask[index] &= ~mask; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | static int ab8500_irq_set_type(struct irq_data *data, unsigned int type) | ||
412 | { | ||
413 | return 0; | ||
382 | } | 414 | } |
383 | 415 | ||
384 | static struct irq_chip ab8500_irq_chip = { | 416 | static struct irq_chip ab8500_irq_chip = { |
@@ -388,6 +420,7 @@ static struct irq_chip ab8500_irq_chip = { | |||
388 | .irq_mask = ab8500_irq_mask, | 420 | .irq_mask = ab8500_irq_mask, |
389 | .irq_disable = ab8500_irq_mask, | 421 | .irq_disable = ab8500_irq_mask, |
390 | .irq_unmask = ab8500_irq_unmask, | 422 | .irq_unmask = ab8500_irq_unmask, |
423 | .irq_set_type = ab8500_irq_set_type, | ||
391 | }; | 424 | }; |
392 | 425 | ||
393 | static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, | 426 | static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, |
@@ -412,6 +445,19 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, | |||
412 | line = (i << 3) + int_bit; | 445 | line = (i << 3) + int_bit; |
413 | latch_val &= ~(1 << int_bit); | 446 | latch_val &= ~(1 << int_bit); |
414 | 447 | ||
448 | /* | ||
449 | * This handles the falling edge hwirqs from the GPIO | ||
450 | * lines. Route them back to the line registered for the | ||
451 | * rising IRQ, as this is merely a flag for the same IRQ | ||
452 | * in linux terms. | ||
453 | */ | ||
454 | if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F) | ||
455 | line -= 16; | ||
456 | if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F) | ||
457 | line -= 8; | ||
458 | if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F) | ||
459 | line += 1; | ||
460 | |||
415 | handle_nested_irq(ab8500->irq_base + line); | 461 | handle_nested_irq(ab8500->irq_base + line); |
416 | } while (latch_val); | 462 | } while (latch_val); |
417 | 463 | ||
@@ -1053,7 +1099,7 @@ static struct mfd_cell ab8500_bm_devs[] = { | |||
1053 | 1099 | ||
1054 | static struct mfd_cell ab8500_devs[] = { | 1100 | static struct mfd_cell ab8500_devs[] = { |
1055 | { | 1101 | { |
1056 | .name = "ab8500-gpio", | 1102 | .name = "pinctrl-ab8500", |
1057 | .of_compatible = "stericsson,ab8500-gpio", | 1103 | .of_compatible = "stericsson,ab8500-gpio", |
1058 | }, | 1104 | }, |
1059 | { | 1105 | { |
@@ -1070,7 +1116,8 @@ static struct mfd_cell ab8500_devs[] = { | |||
1070 | 1116 | ||
1071 | static struct mfd_cell ab9540_devs[] = { | 1117 | static struct mfd_cell ab9540_devs[] = { |
1072 | { | 1118 | { |
1073 | .name = "ab8500-gpio", | 1119 | .name = "pinctrl-ab9540", |
1120 | .of_compatible = "stericsson,ab9540-gpio", | ||
1074 | }, | 1121 | }, |
1075 | { | 1122 | { |
1076 | .name = "ab9540-usb", | 1123 | .name = "ab9540-usb", |