diff options
author | David S. Miller <davem@davemloft.net> | 2015-02-18 02:48:51 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-18 02:48:51 (GMT) |
commit | fece13ca005a5f559147e9424321f4b5e01272b4 (patch) | |
tree | 54e762e70afb664d14152e6bcf89a48be3fb9c13 /drivers/irqchip/irq-gic-common.c | |
parent | 855e7e7174bade3f2b63077a81eea5aab525dbf6 (diff) | |
parent | f5af19d10d151c5a2afae3306578f485c244db25 (diff) | |
download | linux-fece13ca005a5f559147e9424321f4b5e01272b4.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers/irqchip/irq-gic-common.c')
-rw-r--r-- | drivers/irqchip/irq-gic-common.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 61541ff..ad96ebb 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -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, |