]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/sysdev/cpm1.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[karo-tx-linux.git] / arch / powerpc / sysdev / cpm1.c
index 81d49476c47e0aa9d44a0981cb458723b1d760e9..c651e668996bc4d7c2592f8f9602c81147d1f3b6 100644 (file)
@@ -132,7 +132,7 @@ unsigned int cpm_pic_init(void)
 {
        struct device_node *np = NULL;
        struct resource res;
-       unsigned int sirq = NO_IRQ, hwirq, eirq;
+       unsigned int sirq = 0, hwirq, eirq;
        int ret;
 
        pr_debug("cpm_pic_init\n");
@@ -154,7 +154,7 @@ unsigned int cpm_pic_init(void)
                goto end;
 
        sirq = irq_of_parse_and_map(np, 0);
-       if (sirq == NO_IRQ)
+       if (!sirq)
                goto end;
 
        /* Initialize the CPM interrupt controller. */
@@ -168,7 +168,7 @@ unsigned int cpm_pic_init(void)
        cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
        if (cpm_pic_host == NULL) {
                printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
-               sirq = NO_IRQ;
+               sirq = 0;
                goto end;
        }
 
@@ -182,7 +182,7 @@ unsigned int cpm_pic_init(void)
        }
 
        eirq = irq_of_parse_and_map(np, 0);
-       if (eirq == NO_IRQ)
+       if (!eirq)
                goto end;
 
        if (setup_irq(eirq, &cpm_error_irqaction))
@@ -233,8 +233,6 @@ void __init cpm_reset(void)
        else
                out_be32(&siu_conf->sc_sdcr, 1);
        immr_unmap(siu_conf);
-
-       cpm_muram_init();
 }
 
 static DEFINE_SPINLOCK(cmd_lock);
@@ -379,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);
        }
 }
 
@@ -530,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)
@@ -580,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);
@@ -620,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)
@@ -627,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;
 
@@ -636,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);
 }