aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/cpm1.c
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2017-05-01 03:38:13 -0400
committerScott Wood <oss@buserror.net>2017-05-02 23:35:00 -0400
commit726bd223105c04f7bf5eacdc2540819c301061f7 (patch)
tree1df7f57b9804aeeaa2a9d4fb89a131c9a23b6cfb /arch/powerpc/sysdev/cpm1.c
parente21c7316d8ddcf1fd679591d1427e937999a7cf5 (diff)
powerpc/8xx: Adding support of IRQ in MPC8xx GPIO
This patch allows the use of IRQ to notify the change of GPIO status on MPC8xx CPM IO ports. This then allows to associate IRQs to GPIOs in the Device Tree. Ex: CPM1_PIO_C: gpio-controller@960 { #gpio-cells = <2>; compatible = "fsl,cpm1-pario-bank-c"; reg = <0x960 0x10>; fsl,cpm1-gpio-irq-mask = <0x0fff>; interrupts = <1 2 6 9 10 11 14 15 23 24 26 31>; interrupt-parent = <&CPM_PIC>; gpio-controller; }; The property 'fsl,cpm1-gpio-irq-mask' defines which of the 16 GPIOs have the associated interrupts defined in the 'interrupts' property. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Scott Wood <oss@buserror.net>
Diffstat (limited to 'arch/powerpc/sysdev/cpm1.c')
-rw-r--r--arch/powerpc/sysdev/cpm1.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 986cd111d4df..c651e668996b 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -377,6 +377,10 @@ static void cpm1_set_pin16(int port, int pin, int flags)
377 setbits16(&iop->odr_sor, pin); 377 setbits16(&iop->odr_sor, pin);
378 else 378 else
379 clrbits16(&iop->odr_sor, pin); 379 clrbits16(&iop->odr_sor, pin);
380 if (flags & CPM_PIN_FALLEDGE)
381 setbits16(&iop->intr, pin);
382 else
383 clrbits16(&iop->intr, pin);
380 } 384 }
381} 385}
382 386
@@ -528,6 +532,9 @@ struct cpm1_gpio16_chip {
528 532
529 /* shadowed data register to clear/set bits safely */ 533 /* shadowed data register to clear/set bits safely */
530 u16 cpdata; 534 u16 cpdata;
535
536 /* IRQ associated with Pins when relevant */
537 int irq[16];
531}; 538};
532 539
533static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc) 540static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
@@ -578,6 +585,14 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
578 spin_unlock_irqrestore(&cpm1_gc->lock, flags); 585 spin_unlock_irqrestore(&cpm1_gc->lock, flags);
579} 586}
580 587
588static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
589{
590 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
591 struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
592
593 return cpm1_gc->irq[gpio] ? : -ENXIO;
594}
595
581static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 596static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
582{ 597{
583 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 598 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
@@ -618,6 +633,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
618 struct cpm1_gpio16_chip *cpm1_gc; 633 struct cpm1_gpio16_chip *cpm1_gc;
619 struct of_mm_gpio_chip *mm_gc; 634 struct of_mm_gpio_chip *mm_gc;
620 struct gpio_chip *gc; 635 struct gpio_chip *gc;
636 u16 mask;
621 637
622 cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); 638 cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
623 if (!cpm1_gc) 639 if (!cpm1_gc)
@@ -625,6 +641,14 @@ int cpm1_gpiochip_add16(struct device_node *np)
625 641
626 spin_lock_init(&cpm1_gc->lock); 642 spin_lock_init(&cpm1_gc->lock);
627 643
644 if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
645 int i, j;
646
647 for (i = 0, j = 0; i < 16; i++)
648 if (mask & (1 << (15 - i)))
649 cpm1_gc->irq[i] = irq_of_parse_and_map(np, j++);
650 }
651
628 mm_gc = &cpm1_gc->mm_gc; 652 mm_gc = &cpm1_gc->mm_gc;
629 gc = &mm_gc->gc; 653 gc = &mm_gc->gc;
630 654
@@ -634,6 +658,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
634 gc->direction_output = cpm1_gpio16_dir_out; 658 gc->direction_output = cpm1_gpio16_dir_out;
635 gc->get = cpm1_gpio16_get; 659 gc->get = cpm1_gpio16_get;
636 gc->set = cpm1_gpio16_set; 660 gc->set = cpm1_gpio16_set;
661 gc->to_irq = cpm1_gpio16_to_irq;
637 662
638 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); 663 return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
639} 664}