Merge tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux
[linux-2.6-microblaze.git] / drivers / irqchip / irq-gic-common.c
index 61541ff..ad96ebb 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "irq-gic-common.h"
 
-void gic_configure_irq(unsigned int irq, unsigned int type,
+int gic_configure_irq(unsigned int irq, unsigned int type,
                       void __iomem *base, void (*sync_access)(void))
 {
        u32 enablemask = 1 << (irq % 32);
@@ -29,16 +29,17 @@ void gic_configure_irq(unsigned int irq, unsigned int type,
        u32 confmask = 0x2 << ((irq % 16) * 2);
        u32 confoff = (irq / 16) * 4;
        bool enabled = false;
-       u32 val;
+       u32 val, oldval;
+       int ret = 0;
 
        /*
         * Read current configuration register, and insert the config
         * for "irq", depending on "type".
         */
-       val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
-       if (type == IRQ_TYPE_LEVEL_HIGH)
+       val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+       if (type & IRQ_TYPE_LEVEL_MASK)
                val &= ~confmask;
-       else if (type == IRQ_TYPE_EDGE_RISING)
+       else if (type & IRQ_TYPE_EDGE_BOTH)
                val |= confmask;
 
        /*
@@ -54,15 +55,20 @@ void gic_configure_irq(unsigned int irq, unsigned int type,
 
        /*
         * Write back the new configuration, and possibly re-enable
-        * the interrupt.
+        * the interrupt. If we tried to write a new configuration and failed,
+        * return an error.
         */
        writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
+       if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
+               ret = -EINVAL;
 
        if (enabled)
                writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
 
        if (sync_access)
                sync_access();
+
+       return ret;
 }
 
 void __init gic_dist_config(void __iomem *base, int gic_irqs,