aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ab8500-core.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-02-13 18:24:41 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2013-02-13 18:24:51 -0500
commit6ed8b0400c74adfcbc24ea9e59878c273ef51333 (patch)
tree8b49decbe4ef215cc39efa65510788d9b9a8601a /drivers/mfd/ab8500-core.c
parentc3481955f6c78c8dd99921759306d7469c999ec2 (diff)
parente64d905e28031031c52db403826cd3bfe060b181 (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.c53
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
374static void ab8500_irq_unmask(struct irq_data *data) 383static 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
411static int ab8500_irq_set_type(struct irq_data *data, unsigned int type)
412{
413 return 0;
382} 414}
383 415
384static struct irq_chip ab8500_irq_chip = { 416static 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
393static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, 426static 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
1054static struct mfd_cell ab8500_devs[] = { 1100static 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
1071static struct mfd_cell ab9540_devs[] = { 1117static 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",