summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-05-10 16:14:39 +0100
committerMarc Zyngier <marc.zyngier@arm.com>2016-05-11 10:12:42 +0100
commit992345a58e0cbcd63c26226e3e818b4583c4a34d (patch)
treeba0993d031095d5e5a0ffed19f5d3a60b1b85c73
parentec1a454d6136b93e26902ead21025efc08047d05 (diff)
downloadlinux-992345a58e0cbcd63c26226e3e818b4583c4a34d.tar.bz2
irqchip/gic: WARN if setting the interrupt type for a PPI fails
Setting the interrupt type for private peripheral interrupts (PPIs) may not be supported by a given GIC because it is IMPLEMENTATION DEFINED whether this is allowed. There is no way to know if setting the type is supported for a given GIC and so the value written is read back to verify it matches the desired configuration. If it does not match then an error is return. There are cases where the interrupt configuration read from firmware (such as a device-tree blob), has been incorrect and hence gic_configure_irq() has returned an error. This error has gone undetected because the error code returned was ignored but the interrupt still worked fine because the configuration for the interrupt could not be overwritten. Given that this has done undetected and that failing to set the configuration for a PPI may not be a catastrophic, don't return an error but WARN if we fail to configure a PPI. This will allows us to fix up any places in the kernel where we should be checking the return status and maintain backward compatibility with firmware images that may have incorrect PPI configurations. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--drivers/irqchip/irq-gic-common.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index ffff5a45f1e3..97c0028e8388 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -56,12 +56,20 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
/*
* Write back the new configuration, and possibly re-enable
- * the interrupt. If we fail to write a new configuration,
- * return an error.
+ * the interrupt. If we fail to write a new configuration for
+ * an SPI then WARN and return an error. If we fail to write the
+ * configuration for a PPI this is most likely because the GIC
+ * does not allow us to set the configuration or we are in a
+ * non-secure mode, and hence it may not be catastrophic.
*/
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
- if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val)
- ret = -EINVAL;
+ if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
+ if (WARN_ON(irq >= 32))
+ ret = -EINVAL;
+ else
+ pr_warn("GIC: PPI%d is secure or misconfigured\n",
+ irq - 16);
+ }
if (sync_access)
sync_access();