]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/sysdev/cpm1.c
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / arch / powerpc / sysdev / cpm1.c
index 986cd111d4df1064161238a6b2fabad474fa5260..c651e668996bc4d7c2592f8f9602c81147d1f3b6 100644 (file)
@@ -377,6 +377,10 @@ static void cpm1_set_pin16(int port, int pin, int flags)
                        setbits16(&iop->odr_sor, pin);
                else
                        clrbits16(&iop->odr_sor, pin);
+               if (flags & CPM_PIN_FALLEDGE)
+                       setbits16(&iop->intr, pin);
+               else
+                       clrbits16(&iop->intr, pin);
        }
 }
 
@@ -528,6 +532,9 @@ struct cpm1_gpio16_chip {
 
        /* shadowed data register to clear/set bits safely */
        u16 cpdata;
+
+       /* IRQ associated with Pins when relevant */
+       int irq[16];
 };
 
 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)
        spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 }
 
+static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc);
+
+       return cpm1_gc->irq[gpio] ? : -ENXIO;
+}
+
 static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
        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)
        struct cpm1_gpio16_chip *cpm1_gc;
        struct of_mm_gpio_chip *mm_gc;
        struct gpio_chip *gc;
+       u16 mask;
 
        cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
        if (!cpm1_gc)
@@ -625,6 +641,14 @@ int cpm1_gpiochip_add16(struct device_node *np)
 
        spin_lock_init(&cpm1_gc->lock);
 
+       if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
+               int i, j;
+
+               for (i = 0, j = 0; i < 16; i++)
+                       if (mask & (1 << (15 - i)))
+                               cpm1_gc->irq[i] = irq_of_parse_and_map(np, j++);
+       }
+
        mm_gc = &cpm1_gc->mm_gc;
        gc = &mm_gc->gc;
 
@@ -634,6 +658,7 @@ int cpm1_gpiochip_add16(struct device_node *np)
        gc->direction_output = cpm1_gpio16_dir_out;
        gc->get = cpm1_gpio16_get;
        gc->set = cpm1_gpio16_set;
+       gc->to_irq = cpm1_gpio16_to_irq;
 
        return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc);
 }