Skip to content

Commit 726bd22

Browse files
chleroyScott Wood
authored andcommitted
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 <[email protected]> Signed-off-by: Scott Wood <[email protected]>
1 parent e21c731 commit 726bd22

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

Documentation/devicetree/bindings/soc/fsl/cpm_qe/gpio.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,17 @@ Required properties:
1313
- #gpio-cells : Should be two. The first cell is the pin number and the
1414
second cell is used to specify optional parameters (currently unused).
1515
- gpio-controller : Marks the port as GPIO controller.
16+
Optional properties:
17+
- fsl,cpm1-gpio-irq-mask : For banks having interrupt capability (like port C
18+
on CPM1), this item tells which ports have an associated interrupt (ports are
19+
listed in the same order as in PCINT register)
20+
- interrupts : This property provides the list of interrupt for each GPIO having
21+
one as described by the fsl,cpm1-gpio-irq-mask property. There should be as
22+
many interrupts as number of ones in the mask property. The first interrupt in
23+
the list corresponds to the most significant bit of the mask.
24+
- interrupt-parent : Parent for the above interrupt property.
1625

17-
Example of three SOC GPIO banks defined as gpio-controller nodes:
26+
Example of four SOC GPIO banks defined as gpio-controller nodes:
1827

1928
CPM1_PIO_A: gpio-controller@950 {
2029
#gpio-cells = <2>;
@@ -30,6 +39,16 @@ Example of three SOC GPIO banks defined as gpio-controller nodes:
3039
gpio-controller;
3140
};
3241

42+
CPM1_PIO_C: gpio-controller@960 {
43+
#gpio-cells = <2>;
44+
compatible = "fsl,cpm1-pario-bank-c";
45+
reg = <0x960 0x10>;
46+
fsl,cpm1-gpio-irq-mask = <0x0fff>;
47+
interrupts = <1 2 6 9 10 11 14 15 23 24 26 31>;
48+
interrupt-parent = <&CPM_PIC>;
49+
gpio-controller;
50+
};
51+
3352
CPM1_PIO_E: gpio-controller@ac8 {
3453
#gpio-cells = <2>;
3554
compatible = "fsl,cpm1-pario-bank-e";

arch/powerpc/include/asm/cpm1.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,8 @@ typedef struct risc_timer_pram {
560560
#define CPM_PIN_SECONDARY 2
561561
#define CPM_PIN_GPIO 4
562562
#define CPM_PIN_OPENDRAIN 8
563+
#define CPM_PIN_FALLEDGE 16
564+
#define CPM_PIN_ANYEDGE 0
563565

564566
enum cpm_port {
565567
CPM_PORTA,

arch/powerpc/sysdev/cpm1.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,10 @@ static void cpm1_set_pin16(int port, int pin, int flags)
377377
setbits16(&iop->odr_sor, pin);
378378
else
379379
clrbits16(&iop->odr_sor, pin);
380+
if (flags & CPM_PIN_FALLEDGE)
381+
setbits16(&iop->intr, pin);
382+
else
383+
clrbits16(&iop->intr, pin);
380384
}
381385
}
382386

@@ -528,6 +532,9 @@ struct cpm1_gpio16_chip {
528532

529533
/* shadowed data register to clear/set bits safely */
530534
u16 cpdata;
535+
536+
/* IRQ associated with Pins when relevant */
537+
int irq[16];
531538
};
532539

533540
static 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)
578585
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
579586
}
580587

588+
static 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+
581596
static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
582597
{
583598
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
@@ -618,13 +633,22 @@ int cpm1_gpiochip_add16(struct device_node *np)
618633
struct cpm1_gpio16_chip *cpm1_gc;
619634
struct of_mm_gpio_chip *mm_gc;
620635
struct gpio_chip *gc;
636+
u16 mask;
621637

622638
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
623639
if (!cpm1_gc)
624640
return -ENOMEM;
625641

626642
spin_lock_init(&cpm1_gc->lock);
627643

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+
628652
mm_gc = &cpm1_gc->mm_gc;
629653
gc = &mm_gc->gc;
630654

@@ -634,6 +658,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
634658
gc->direction_output = cpm1_gpio16_dir_out;
635659
gc->get = cpm1_gpio16_get;
636660
gc->set = cpm1_gpio16_set;
661+
gc->to_irq = cpm1_gpio16_to_irq;
637662

638663
return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
639664
}

0 commit comments

Comments
 (0)